Replaces f64 and i64 with FloatType and IntType.

This commit is contained in:
Natan Freeman 2022-09-14 21:36:36 +03:00
parent db191e1674
commit 927e0e4075
2 changed files with 29 additions and 20 deletions

View File

@ -23,7 +23,7 @@ macro_rules! simple_math {
}; };
} }
fn float_is(func: fn(f64) -> bool) -> Option<Function> { fn float_is(func: fn(FloatType) -> bool) -> Option<Function> {
Some(Function::new(move |argument| { Some(Function::new(move |argument| {
Ok(func(argument.as_number()?).into()) Ok(func(argument.as_number()?).into())
})) }))
@ -83,10 +83,10 @@ pub fn builtin_function(identifier: &str) -> Option<Function> {
"round" => simple_math!(round), "round" => simple_math!(round),
"ceil" => simple_math!(ceil), "ceil" => simple_math!(ceil),
// Float special values // Float special values
"math::is_nan" => float_is(f64::is_nan), "math::is_nan" => float_is(FloatType::is_nan),
"math::is_finite" => float_is(f64::is_finite), "math::is_finite" => float_is(FloatType::is_finite),
"math::is_infinite" => float_is(f64::is_infinite), "math::is_infinite" => float_is(FloatType::is_infinite),
"math::is_normal" => float_is(f64::is_normal), "math::is_normal" => float_is(FloatType::is_normal),
// Other // Other
"typeof" => Some(Function::new(move |argument| { "typeof" => Some(Function::new(move |argument| {
Ok(match argument { Ok(match argument {
@ -102,7 +102,7 @@ pub fn builtin_function(identifier: &str) -> Option<Function> {
"min" => Some(Function::new(|argument| { "min" => Some(Function::new(|argument| {
let arguments = argument.as_tuple()?; let arguments = argument.as_tuple()?;
let mut min_int = IntType::max_value(); let mut min_int = IntType::max_value();
let mut min_float = 1.0f64 / 0.0f64; let mut min_float: FloatType = 1.0 / 0.0;
debug_assert!(min_float.is_infinite()); debug_assert!(min_float.is_infinite());
for argument in arguments { for argument in arguments {
@ -124,7 +124,7 @@ pub fn builtin_function(identifier: &str) -> Option<Function> {
"max" => Some(Function::new(|argument| { "max" => Some(Function::new(|argument| {
let arguments = argument.as_tuple()?; let arguments = argument.as_tuple()?;
let mut max_int = IntType::min_value(); let mut max_int = IntType::min_value();
let mut max_float = -1.0f64 / 0.0f64; let mut max_float: FloatType = -1.0 / 0.0;
debug_assert!(max_float.is_infinite()); debug_assert!(max_float.is_infinite());
for argument in arguments { for argument in arguments {
@ -150,9 +150,9 @@ pub fn builtin_function(identifier: &str) -> Option<Function> {
})), })),
"len" => Some(Function::new(|argument| { "len" => Some(Function::new(|argument| {
if let Ok(subject) = argument.as_string() { if let Ok(subject) = argument.as_string() {
Ok(Value::from(subject.len() as i64)) Ok(Value::from(subject.len() as IntType))
} else if let Ok(subject) = argument.as_tuple() { } else if let Ok(subject) = argument.as_tuple() {
Ok(Value::from(subject.len() as i64)) Ok(Value::from(subject.len() as IntType))
} else { } else {
Err(EvalexprError::type_error( Err(EvalexprError::type_error(
argument.clone(), argument.clone(),

View File

@ -89,7 +89,10 @@ fn test_mod_examples() {
#[test] #[test]
fn test_pow_examples() { fn test_pow_examples() {
assert_eq!(eval("1 ^ 4"), Ok(Value::Float(1.0))); assert_eq!(eval("1 ^ 4"), Ok(Value::Float(1.0)));
assert_eq!(eval("6 ^ 4"), Ok(Value::Float(6.0f64.powf(4.0)))); assert_eq!(
eval("6 ^ 4"),
Ok(Value::Float((6.0 as FloatType).powf(4.0)))
);
assert_eq!(eval("1 ^ 4 + 2"), Ok(Value::Float(3.0))); assert_eq!(eval("1 ^ 4 + 2"), Ok(Value::Float(3.0)));
assert_eq!(eval("2 ^ (4 + 2)"), Ok(Value::Float(64.0))); assert_eq!(eval("2 ^ (4 + 2)"), Ok(Value::Float(64.0)));
} }
@ -289,7 +292,7 @@ fn test_capturing_functions() {
if let Value::Int(int) = argument { if let Value::Int(int) = argument {
Ok(Value::Int(int * three)) Ok(Value::Int(int * three))
} else if let Value::Float(float) = argument { } else if let Value::Float(float) = argument {
Ok(Value::Float(float * three as f64)) Ok(Value::Float(float * three as FloatType))
} else { } else {
Err(EvalexprError::expected_number(argument.clone())) Err(EvalexprError::expected_number(argument.clone()))
} }
@ -321,11 +324,17 @@ fn test_builtin_functions() {
assert_eq!(eval("math::log2(2)"), Ok(Value::Float(1.0))); assert_eq!(eval("math::log2(2)"), Ok(Value::Float(1.0)));
assert_eq!(eval("math::log10(10)"), Ok(Value::Float(1.0))); assert_eq!(eval("math::log10(10)"), Ok(Value::Float(1.0)));
// Powers // Powers
assert_eq!(eval("math::exp(2)"), Ok(Value::Float(2.0_f64.exp()))); assert_eq!(
assert_eq!(eval("math::exp2(2)"), Ok(Value::Float(2.0_f64.exp2()))); eval("math::exp(2)"),
Ok(Value::Float((2.0 as FloatType).exp()))
);
assert_eq!(
eval("math::exp2(2)"),
Ok(Value::Float((2.0 as FloatType).exp2()))
);
assert_eq!( assert_eq!(
eval("math::pow(1.5, 1.3)"), eval("math::pow(1.5, 1.3)"),
Ok(Value::Float(1.5_f64.powf(1.3))) Ok(Value::Float((1.5 as FloatType).powf(1.3)))
); );
// Cos // Cos
assert_eq!(eval("math::cos(0)"), Ok(Value::Float(1.0))); assert_eq!(eval("math::cos(0)"), Ok(Value::Float(1.0)));
@ -344,7 +353,7 @@ fn test_builtin_functions() {
assert_eq!(eval("math::atanh(0)"), Ok(Value::Float(0.0))); assert_eq!(eval("math::atanh(0)"), Ok(Value::Float(0.0)));
assert_eq!( assert_eq!(
eval("math::atan2(1.2, -5.5)"), eval("math::atan2(1.2, -5.5)"),
Ok(Value::Float(1.2_f64.atan2(-5.5))) Ok(Value::Float((1.2 as FloatType).atan2(-5.5)))
); );
// Root // Root
assert_eq!(eval("math::sqrt(25)"), Ok(Value::Float(5.0))); assert_eq!(eval("math::sqrt(25)"), Ok(Value::Float(5.0)));
@ -352,7 +361,7 @@ fn test_builtin_functions() {
// Hypotenuse // Hypotenuse
assert_eq!( assert_eq!(
eval("math::hypot(8.2, 1.1)"), eval("math::hypot(8.2, 1.1)"),
Ok(Value::Float(8.2_f64.hypot(1.1))) Ok(Value::Float((8.2 as FloatType).hypot(1.1)))
); );
// Rounding // Rounding
assert_eq!(eval("floor(1.1)"), Ok(Value::Float(1.0))); assert_eq!(eval("floor(1.1)"), Ok(Value::Float(1.0)));
@ -1525,7 +1534,7 @@ fn test_hashmap_context_clone_debug() {
if let Value::Int(int) = argument { if let Value::Int(int) = argument {
Ok(Value::Int(int * three)) Ok(Value::Int(int * three))
} else if let Value::Float(float) = argument { } else if let Value::Float(float) = argument {
Ok(Value::Float(float * three as f64)) Ok(Value::Float(float * three as FloatType))
} else { } else {
Err(EvalexprError::expected_number(argument.clone())) Err(EvalexprError::expected_number(argument.clone()))
} }
@ -1661,7 +1670,7 @@ fn test_long_expression_i89() {
) )
.unwrap(); .unwrap();
let x = 0.0; let x = 0.0;
let y: f64 = 3.0; let y: FloatType = 3.0;
let z = 4.0; let z = 4.0;
let context = context_map! { let context = context_map! {
"x" => 0.0, "x" => 0.0,
@ -1672,8 +1681,8 @@ fn test_long_expression_i89() {
let expected = x * 0.2 * 5.0 / 4.0 let expected = x * 0.2 * 5.0 / 4.0
+ x * 2.0 * 4.0 * 1.0 * 1.0 * 1.0 * 1.0 * 1.0 * 1.0 * 1.0 + x * 2.0 * 4.0 * 1.0 * 1.0 * 1.0 * 1.0 * 1.0 * 1.0 * 1.0
+ 7.0 * y.sin() + 7.0 * y.sin()
- z / (3.0 / 2.0 / (1.0 - x * 4.0 * 1.0 * 1.0 * 1.0 * 1.0)).sin(); - z / (3.0 / 2.0 / (1.0 - x * 4.0 * 1.0 * 1.0 * 1.0 * 1.0)).sin() ;
let actual = tree.eval_float_with_context(&context).unwrap(); let actual: FloatType = tree.eval_float_with_context(&context).unwrap();
assert!( assert!(
(expected - actual).abs() < expected.abs().min(actual.abs()) * 1e-12, (expected - actual).abs() < expected.abs().min(actual.abs()) * 1e-12,
"expected: {}, actual: {}", "expected: {}, actual: {}",