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

View File

@ -89,7 +89,10 @@ fn test_mod_examples() {
#[test]
fn test_pow_examples() {
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("2 ^ (4 + 2)"), Ok(Value::Float(64.0)));
}
@ -289,7 +292,7 @@ fn test_capturing_functions() {
if let Value::Int(int) = argument {
Ok(Value::Int(int * three))
} else if let Value::Float(float) = argument {
Ok(Value::Float(float * three as f64))
Ok(Value::Float(float * three as FloatType))
} else {
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::log10(10)"), Ok(Value::Float(1.0)));
// Powers
assert_eq!(eval("math::exp(2)"), Ok(Value::Float(2.0_f64.exp())));
assert_eq!(eval("math::exp2(2)"), Ok(Value::Float(2.0_f64.exp2())));
assert_eq!(
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!(
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
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::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
assert_eq!(eval("math::sqrt(25)"), Ok(Value::Float(5.0)));
@ -352,7 +361,7 @@ fn test_builtin_functions() {
// Hypotenuse
assert_eq!(
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
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 {
Ok(Value::Int(int * three))
} else if let Value::Float(float) = argument {
Ok(Value::Float(float * three as f64))
Ok(Value::Float(float * three as FloatType))
} else {
Err(EvalexprError::expected_number(argument.clone()))
}
@ -1661,7 +1670,7 @@ fn test_long_expression_i89() {
)
.unwrap();
let x = 0.0;
let y: f64 = 3.0;
let y: FloatType = 3.0;
let z = 4.0;
let context = context_map! {
"x" => 0.0,
@ -1672,8 +1681,8 @@ fn test_long_expression_i89() {
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
+ 7.0 * y.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();
- z / (3.0 / 2.0 / (1.0 - x * 4.0 * 1.0 * 1.0 * 1.0 * 1.0)).sin() ;
let actual: FloatType = tree.eval_float_with_context(&context).unwrap();
assert!(
(expected - actual).abs() < expected.abs().min(actual.abs()) * 1e-12,
"expected: {}, actual: {}",