Implement better error messages for addition with incompatible types
Implements #60
This commit is contained in:
parent
2ec3dc74c1
commit
2d1704b9a3
@ -214,6 +214,11 @@ impl EvalexprError {
|
|||||||
EvalexprError::TypeError { actual, expected }
|
EvalexprError::TypeError { actual, expected }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Constructs `EvalexprError::WrongTypeCombination{operator, actual}`.
|
||||||
|
pub fn wrong_type_combination(operator: Operator, actual: Vec<ValueType>) -> Self {
|
||||||
|
EvalexprError::WrongTypeCombination { operator, actual }
|
||||||
|
}
|
||||||
|
|
||||||
/// Constructs `EvalexprError::ExpectedString{actual}`.
|
/// Constructs `EvalexprError::ExpectedString{actual}`.
|
||||||
pub fn expected_string(actual: Value) -> Self {
|
pub fn expected_string(actual: Value) -> Self {
|
||||||
EvalexprError::ExpectedString { actual }
|
EvalexprError::ExpectedString { actual }
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
use crate::function::builtin::builtin_function;
|
use crate::function::builtin::builtin_function;
|
||||||
|
|
||||||
use crate::{context::Context, error::*, value::Value};
|
use crate::{context::Context, error::*, value::Value};
|
||||||
|
use std::borrow::Borrow;
|
||||||
|
|
||||||
mod display;
|
mod display;
|
||||||
|
|
||||||
/// An enum that represents operators in the operator tree.
|
/// An enum that represents operators in the operator tree.
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum Operator {
|
pub enum Operator {
|
||||||
/// A root node in the operator tree.
|
/// A root node in the operator tree.
|
||||||
/// The whole expression is stored under a root node, as well as each subexpression surrounded by parentheses.
|
/// The whole expression is stored under a root node, as well as each subexpression surrounded by parentheses.
|
||||||
@ -205,9 +206,13 @@ impl Operator {
|
|||||||
arguments[1].clone(),
|
arguments[1].clone(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
} else if let (Ok(a), Ok(b)) = (arguments[0].as_number(), arguments[1].as_number())
|
||||||
|
{
|
||||||
|
Ok(Value::Float(a + b))
|
||||||
} else {
|
} else {
|
||||||
Ok(Value::Float(
|
Err(EvalexprError::wrong_type_combination(
|
||||||
arguments[0].as_number()? + arguments[1].as_number()?,
|
self.clone(),
|
||||||
|
vec![arguments[0].borrow().into(), arguments[1].borrow().into()],
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -698,17 +698,20 @@ fn test_operator_assignments() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_type_errors_in_binary_operators() {
|
fn test_type_errors_in_binary_operators() {
|
||||||
// This error is bad. In future, maybe add a special error message for this kind of call.
|
// Only addition supports incompatible types, all others work only on numbers or only on booleans.
|
||||||
|
// So only addition requires the more fancy error message.
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
eval("4 + \"abc\""),
|
eval("4 + \"abc\""),
|
||||||
Err(EvalexprError::expected_number(Value::from(
|
Err(EvalexprError::wrong_type_combination(
|
||||||
"abc".to_string()
|
Operator::Add,
|
||||||
)))
|
vec![ValueType::Int, ValueType::String]
|
||||||
|
))
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
eval("\"abc\" + 4"),
|
eval("\"abc\" + 4"),
|
||||||
Err(EvalexprError::expected_number(Value::from(
|
Err(EvalexprError::wrong_type_combination(
|
||||||
"abc".to_string()
|
Operator::Add,
|
||||||
)))
|
vec![ValueType::String, ValueType::Int]
|
||||||
|
))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user