Merge pull request #113 from NatanFreeman/main
Replaces `f64` and `i64` with `FloatType` and `IntType`.
This commit is contained in:
commit
040a192147
@ -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(),
|
||||||
|
@ -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,
|
||||||
@ -1673,7 +1682,7 @@ fn test_long_expression_i89() {
|
|||||||
+ 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: {}",
|
||||||
|
Loading…
Reference in New Issue
Block a user