diff --git a/README.md b/README.md index 9df5f50..6e4f244 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Features -------- Supported operators: `!` `!=` `""` `''` `()` `[]` `,` `>` `<` `>=` `<=` `==` -`+` `-` `*` `/` `%` `&&` `||` `n..m`. +`+` unary/binary `-` `*` `/` `%` `&&` `||` `n..m`. Built-in functions: `min()` `max()` `len()` `is_empty()` `array()` `converge()`. See the `builtin` module for a detailed description of each. diff --git a/src/lib.rs b/src/lib.rs index ba35828..76433cb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,7 @@ //! Eval is a powerful expression evaluator. //! //! Supported operators: `!` `!=` `""` `''` `()` `[]` `.` `,` `>` `<` `>=` `<=` -//! `==` `+` `-` `*` `/` `%` `&&` `||` `n..m`. +//! `==` `+` unary/binary `-` `*` `/` `%` `&&` `||` `n..m`. //! //! Built-in functions: `min()` `max()` `len()` `is_empty()` `array()` `converge()`. //! @@ -111,6 +111,8 @@ mod error; mod builtin; mod expr; +mod reboot; + pub use expr::ExecOptions; pub use serde_json::Value; pub use error::Error; @@ -604,6 +606,16 @@ mod tests { assert_eq!(eval("2 * (2 + 2) + (1 + 3)"), Ok(to_value(12))); assert_eq!(eval("2 * (4) + (4)"), Ok(to_value(12))); } + + #[test] + fn test_unary_minus() { + assert_eq!(eval("3 + -4"), Ok(to_value(-1))); + assert_eq!(eval("3+-4"), Ok(to_value(-1))); + assert_eq!(eval("true && !false"), Ok(to_value(true))); + assert_eq!(eval("!true || !true"), Ok(to_value(false))); + assert_eq!(eval("-5 + -4"), Ok(to_value(-9))); + assert_eq!(eval("-3-4"), Ok(to_value(-7))); + } } #[cfg(all(feature = "unstable", test))] diff --git a/src/operator/mod.rs b/src/operator/mod.rs index d23423d..ed55a7f 100644 --- a/src/operator/mod.rs +++ b/src/operator/mod.rs @@ -8,6 +8,7 @@ use node::Node; #[derive(Debug, Clone, PartialEq)] pub enum Operator { + Neg(u8), Add(u8), Mul(u8), Sub(u8), @@ -46,6 +47,7 @@ impl Operator { pub fn can_at_beginning(&self) -> bool { match *self { + Operator::Neg(_) | Operator::Not(_) | Operator::Function(_) | Operator::LeftParenthesis => true, @@ -59,7 +61,7 @@ impl Operator { Operator::Eq(_) | Operator::Ne(_) | Operator::Gt(_) | Operator::Lt(_) | Operator::Ge(_) | Operator::Le(_) | Operator::And(_) | Operator::Or(_) | Operator::Rem(_) => Some(2), - Operator::Not(_) => Some(1), + Operator::Not(_) | Operator::Neg(_) => Some(1), Operator::Function(_) => None, _ => Some(0), } @@ -71,7 +73,7 @@ impl Operator { Operator::Eq(_) | Operator::Ne(_) | Operator::Gt(_) | Operator::Lt(_) | Operator::Ge(_) | Operator::Le(_) | Operator::And(_) | Operator::Or(_) | Operator::Rem(_) => Some(2), - Operator::Not(_) => Some(1), + Operator::Not(_) | Operator::Neg(_) => Some(1), Operator::Function(_) => None, _ => Some(0), } @@ -79,6 +81,7 @@ impl Operator { pub fn get_priority(&self) -> u8 { match *self { + Operator::Neg(priority) | Operator::Add(priority) | Operator::Sub(priority) | Operator::Div(priority) | @@ -147,6 +150,7 @@ impl Operator { Operator::Or(_) | Operator::Ge(_) | Operator::Not(_) | + Operator::Neg(_) | Operator::Dot(_) | Operator::LeftSquareBracket(_) | Operator::Le(_) => true, diff --git a/src/reboot/mod.rs b/src/reboot/mod.rs new file mode 100644 index 0000000..e69de29