From d576cec9b9472d89ff31731ecb248d67f9a886eb Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Sat, 13 Apr 2019 20:04:36 +0200 Subject: [PATCH] Add flattening of operator chains when building operator tree Relates to #44 --- src/operator/mod.rs | 9 +++++++++ src/tree/mod.rs | 3 +++ src/value/mod.rs | 4 ++++ tests/integration.rs | 14 ++++++++++++++ 4 files changed, 30 insertions(+) diff --git a/src/operator/mod.rs b/src/operator/mod.rs index a94dc9c..1be227d 100644 --- a/src/operator/mod.rs +++ b/src/operator/mod.rs @@ -91,6 +91,15 @@ impl Operator { } } + /// Returns true if chains of this operator should be flattened into one operator with many arguments. + // Make this a const fn once #57563 is resolved + fn is_flatten_chains(&self) -> bool { + match self { + Operator::Chain => true, + _ => false, + } + } + /// True if this operator is a leaf, meaning it accepts no arguments. // Make this a const fn once #57563 is resolved pub(crate) fn is_leaf(&self) -> bool { diff --git a/src/tree/mod.rs b/src/tree/mod.rs index 7e9f8b8..e9f50d8 100644 --- a/src/tree/mod.rs +++ b/src/tree/mod.rs @@ -383,6 +383,9 @@ impl Node { .last_mut() .unwrap() .insert_back_prioritized(node, false) + } else if self.children.last().unwrap().operator().id() == node.operator().id() && node.operator().is_flatten_chains() && !self.children.last().unwrap().has_enough_children() { + // The operators will be chained together, and the next value will be added to this nodes last child. + Ok(()) } else { if node.operator().is_leaf() { return Err(EvalexprError::AppendedToLeafNode); diff --git a/src/value/mod.rs b/src/value/mod.rs index b2e8cee..17aafe2 100644 --- a/src/value/mod.rs +++ b/src/value/mod.rs @@ -194,6 +194,10 @@ impl From for EvalexprResult { } } +impl From<()> for Value { + fn from(_: ()) -> Self { Value::Empty } +} + #[cfg(test)] mod tests { use value::{TupleType, Value}; diff --git a/tests/integration.rs b/tests/integration.rs index 4aedc2a..35428a2 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -605,3 +605,17 @@ fn test_serde() { assert_eq!(manual_tree.eval(), serde_tree.eval()); } } + +#[test] +fn test_tuple_definitions() { + assert_eq!(eval_empty("()"), Ok(())); + assert_eq!(eval_int("(3)"), Ok(3)); + assert_eq!(eval_tuple("(3, 4)"), Ok(vec![Value::from(3), Value::from(4)])); + assert_eq!(eval_tuple("2, (5, 6)"), Ok(vec![Value::from(2), Value::from(vec![Value::from(5), Value::from(6)])])); + assert_eq!(eval_tuple("1, 2"), Ok(vec![Value::from(1), Value::from(2)])); + assert_eq!(eval_tuple("1, 2, 3, 4"), Ok(vec![Value::from(1), Value::from(2), Value::from(3), Value::from(4)])); + assert_eq!(eval_tuple("(1, 2, 3), 5, 6, (true, false, 0)"), Ok(vec![Value::from(vec![Value::from(1), Value::from(2), Value::from(3)]), Value::from(5), Value::from(6), Value::from(vec![Value::from(true), Value::from(false), Value::from(0)])])); + assert_eq!(eval_tuple("1, (2)"), Ok(vec![Value::from(1), Value::from(2)])); + assert_eq!(eval_tuple("1, ()"), Ok(vec![Value::from(1), Value::from(())])); + assert_eq!(eval_tuple("1, ((2))"), Ok(vec![Value::from(1), Value::from(2)])); +}