From 0d7cf0a069b96e3b16bd16a5ab14416f124f9b08 Mon Sep 17 00:00:00 2001 From: Dmitry Dodzin Date: Wed, 18 Jun 2025 20:59:54 +0300 Subject: [PATCH] Update a more correct math evaluation --- src/lib.rs | 4 ++++ src/transform/expr.rs | 26 ++++++++++++++++++-------- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 502f439..4cb0d7f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1214,6 +1214,10 @@ mod tests { #[case("1 + 2 / 2 + 1", "3")] #[case("3.12 * 2", "6.24")] #[case("\"3.12\" + \".2\"", "\"3.12.2\"")] + #[case("22 - 18", "4")] + #[case("22 - 18 - 1", "3")] + #[case("16 / 2", "8")] + #[case("16 / 2 / 2", "4")] #[case("true and true", "true")] #[case("true or false", "true")] #[case("false or false", "false")] diff --git a/src/transform/expr.rs b/src/transform/expr.rs index 259ba87..d70cfc4 100644 --- a/src/transform/expr.rs +++ b/src/transform/expr.rs @@ -122,11 +122,20 @@ pub struct OperatorExprTransformer { macro_rules! impl_operator_parse { ($ident:ident, $op:ident) => { - if let Some((index, _)) = $ident - .iter() - .enumerate() - .find(|(_, pair)| matches!(pair.as_rule(), Rule::$op)) - { + impl_operator_parse!($ident, $op, false) + }; + ($ident:ident, $op:ident, $invert:literal) => { + let found_rule = { + let matcher = |(_, pair): &(_, &Pair)| matches!(pair.as_rule(), Rule::$op); + + if $invert { + $ident.iter().enumerate().rev().find(matcher) + } else { + $ident.iter().enumerate().find(matcher) + } + }; + + if let Some((index, _)) = found_rule { let mut right = $ident.split_off(index).split_off(1); let lhs = if $ident.len() == 1 { @@ -168,10 +177,11 @@ impl OperatorExprTransformer { impl_operator_parse!(pairs, Lte); impl_operator_parse!(pairs, Equal); impl_operator_parse!(pairs, NotEqual); - impl_operator_parse!(pairs, Add); - impl_operator_parse!(pairs, Sub); + impl_operator_parse!(pairs, Mul); - impl_operator_parse!(pairs, Div); + impl_operator_parse!(pairs, Add); + impl_operator_parse!(pairs, Div, true); + impl_operator_parse!(pairs, Sub, true); Err(JsltError::InvalidInput(format!( "Could not evaluate the expession {pairs:#?}",