small error handling improvement, allow adding strings

This commit is contained in:
elkowar 2021-07-16 19:46:23 +02:00
parent 752a842cbf
commit 228d10aeb3
No known key found for this signature in database
GPG key ID: E321AD71B1D1F27F
3 changed files with 14 additions and 7 deletions

View file

@ -1,7 +1,5 @@
use std::collections::HashMap; use std::collections::HashMap;
use simplexpr::dynval::DynVal;
fn main() { fn main() {
let mut files = codespan_reporting::files::SimpleFiles::new(); let mut files = codespan_reporting::files::SimpleFiles::new();

View file

@ -6,9 +6,11 @@ pub type Result<T> = std::result::Result<T, Error>;
pub enum Error { pub enum Error {
#[error("Parse error: {source}")] #[error("Parse error: {source}")]
ParseError { source: lalrpop_util::ParseError<usize, lexer::Token, lexer::LexicalError> }, ParseError { source: lalrpop_util::ParseError<usize, lexer::Token, lexer::LexicalError> },
#[error("Conversion error: {0}")]
#[error("Type error: {0}")]
ConversionError(#[from] dynval::ConversionError), ConversionError(#[from] dynval::ConversionError),
#[error("At: {0}: {1}")]
#[error("{1}")]
Spanned(Span, Box<dyn std::error::Error>), Spanned(Span, Box<dyn std::error::Error>),
#[error(transparent)] #[error(transparent)]

View file

@ -29,7 +29,7 @@ pub enum EvalError {
#[error("Unable to index into value {0}")] #[error("Unable to index into value {0}")]
CannotIndex(String), CannotIndex(String),
#[error("At {0}: {1}")] #[error("{1}")]
Spanned(Span, Box<EvalError>), Spanned(Span, Box<EvalError>),
} }
@ -49,6 +49,11 @@ impl EvalError {
type VarName = String; type VarName = String;
pub trait FunctionSource {
type Err;
fn run_fn(&self, name: &str, args: &Vec<DynVal>) -> Result<DynVal, Self::Err>;
}
impl SimplExpr { impl SimplExpr {
pub fn map_terminals_into(self, f: impl Fn(Self) -> Self) -> Self { pub fn map_terminals_into(self, f: impl Fn(Self) -> Self) -> Self {
use SimplExpr::*; use SimplExpr::*;
@ -124,8 +129,10 @@ impl SimplExpr {
BinOp::NotEquals => DynVal::from(a != b), BinOp::NotEquals => DynVal::from(a != b),
BinOp::And => DynVal::from(a.as_bool()? && b.as_bool()?), BinOp::And => DynVal::from(a.as_bool()? && b.as_bool()?),
BinOp::Or => DynVal::from(a.as_bool()? || b.as_bool()?), BinOp::Or => DynVal::from(a.as_bool()? || b.as_bool()?),
BinOp::Plus => match a.as_f64() {
BinOp::Plus => DynVal::from(a.as_f64()? + b.as_f64()?), Ok(num) => DynVal::from(num + b.as_f64()?),
Err(_) => DynVal::from(format!("{}{}", a.as_string()?, b.as_string()?)),
},
BinOp::Minus => DynVal::from(a.as_f64()? - b.as_f64()?), BinOp::Minus => DynVal::from(a.as_f64()? - b.as_f64()?),
BinOp::Times => DynVal::from(a.as_f64()? * b.as_f64()?), BinOp::Times => DynVal::from(a.as_f64()? * b.as_f64()?),
BinOp::Div => DynVal::from(a.as_f64()? / b.as_f64()?), BinOp::Div => DynVal::from(a.as_f64()? / b.as_f64()?),