From a7b5f602d5edcfcc1551a8ed928ddbeeb0ed1f33 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Thu, 28 Mar 2019 10:02:08 +0100 Subject: [PATCH] Do not require expressions to have content * Make parser return implicit toplevel node * Make `RootNode` return `Value::Empty` if it has no arguments instead of failing Relates to #28 --- src/error/display.rs | 5 ---- src/error/mod.rs | 3 --- src/operator/mod.rs | 55 +++++++++++++++++++++++--------------------- src/tree/mod.rs | 19 ++++----------- 4 files changed, 34 insertions(+), 48 deletions(-) diff --git a/src/error/display.rs b/src/error/display.rs index 1d212b4..9857dc0 100644 --- a/src/error/display.rs +++ b/src/error/display.rs @@ -29,11 +29,6 @@ impl fmt::Display for EvalexprError { }, ExpectedTuple { actual } => write!(f, "Expected a Value::Tuple, but got {:?}.", actual), ExpectedEmpty { actual } => write!(f, "Expected a Value::Empty, but got {:?}.", actual), - EmptyExpression => write!( - f, - "Got an empty expression that cannot be parsed into a node tree, because it \ - returns nothing." - ), AppendedToLeafNode => write!(f, "Tried to append a node to a leaf node."), PrecedenceViolation => write!( f, diff --git a/src/error/mod.rs b/src/error/mod.rs index ab28874..84042fa 100644 --- a/src/error/mod.rs +++ b/src/error/mod.rs @@ -74,9 +74,6 @@ pub enum EvalexprError { actual: Value, }, - /// The given expression is empty - EmptyExpression, - /// Tried to append a child to a leaf node. /// Leaf nodes cannot have children. AppendedToLeafNode, diff --git a/src/operator/mod.rs b/src/operator/mod.rs index 171cf84..b6d9c07 100644 --- a/src/operator/mod.rs +++ b/src/operator/mod.rs @@ -21,12 +21,12 @@ pub trait Operator: Debug + Display { /// True if this operator is a leaf, meaning it accepts no arguments. // Make this a const fn once #57563 is resolved fn is_leaf(&self) -> bool { - self.argument_amount() == 0 + self.max_argument_amount() == 0 } - /// Returns the amount of arguments required by this operator. + /// Returns the maximum amount of arguments required by this operator. // Make this a const fn once #57563 is resolved - fn argument_amount(&self) -> usize; + fn max_argument_amount(&self) -> usize; /// Evaluates the operator with the given arguments and context. fn eval(&self, arguments: &[Value], context: &dyn Context) -> EvalexprResult; @@ -119,13 +119,16 @@ impl Operator for RootNode { true } - fn argument_amount(&self) -> usize { + fn max_argument_amount(&self) -> usize { 1 } fn eval(&self, arguments: &[Value], _context: &Context) -> EvalexprResult { - expect_operator_argument_amount(arguments.len(), 1)?; - Ok(arguments[0].clone()) + if let Some(first) = arguments.first() { + Ok(first.clone()) + } else { + Ok(Value::Empty) + } } } @@ -138,7 +141,7 @@ impl Operator for Add { true } - fn argument_amount(&self) -> usize { + fn max_argument_amount(&self) -> usize { 2 } @@ -174,7 +177,7 @@ impl Operator for Sub { true } - fn argument_amount(&self) -> usize { + fn max_argument_amount(&self) -> usize { 2 } @@ -210,7 +213,7 @@ impl Operator for Neg { true } - fn argument_amount(&self) -> usize { + fn max_argument_amount(&self) -> usize { 1 } @@ -240,7 +243,7 @@ impl Operator for Mul { true } - fn argument_amount(&self) -> usize { + fn max_argument_amount(&self) -> usize { 2 } @@ -276,7 +279,7 @@ impl Operator for Div { true } - fn argument_amount(&self) -> usize { + fn max_argument_amount(&self) -> usize { 2 } @@ -312,7 +315,7 @@ impl Operator for Mod { true } - fn argument_amount(&self) -> usize { + fn max_argument_amount(&self) -> usize { 2 } @@ -348,7 +351,7 @@ impl Operator for Exp { true } - fn argument_amount(&self) -> usize { + fn max_argument_amount(&self) -> usize { 2 } @@ -375,7 +378,7 @@ impl Operator for Eq { true } - fn argument_amount(&self) -> usize { + fn max_argument_amount(&self) -> usize { 2 } @@ -399,7 +402,7 @@ impl Operator for Neq { true } - fn argument_amount(&self) -> usize { + fn max_argument_amount(&self) -> usize { 2 } @@ -423,7 +426,7 @@ impl Operator for Gt { true } - fn argument_amount(&self) -> usize { + fn max_argument_amount(&self) -> usize { 2 } @@ -457,7 +460,7 @@ impl Operator for Lt { true } - fn argument_amount(&self) -> usize { + fn max_argument_amount(&self) -> usize { 2 } @@ -491,7 +494,7 @@ impl Operator for Geq { true } - fn argument_amount(&self) -> usize { + fn max_argument_amount(&self) -> usize { 2 } @@ -525,7 +528,7 @@ impl Operator for Leq { true } - fn argument_amount(&self) -> usize { + fn max_argument_amount(&self) -> usize { 2 } @@ -559,7 +562,7 @@ impl Operator for And { true } - fn argument_amount(&self) -> usize { + fn max_argument_amount(&self) -> usize { 2 } @@ -585,7 +588,7 @@ impl Operator for Or { true } - fn argument_amount(&self) -> usize { + fn max_argument_amount(&self) -> usize { 2 } @@ -611,7 +614,7 @@ impl Operator for Not { true } - fn argument_amount(&self) -> usize { + fn max_argument_amount(&self) -> usize { 1 } @@ -636,7 +639,7 @@ impl Operator for Tuple { true } - fn argument_amount(&self) -> usize { + fn max_argument_amount(&self) -> usize { 2 } @@ -673,7 +676,7 @@ impl Operator for Const { true } - fn argument_amount(&self) -> usize { + fn max_argument_amount(&self) -> usize { 0 } @@ -693,7 +696,7 @@ impl Operator for VariableIdentifier { true } - fn argument_amount(&self) -> usize { + fn max_argument_amount(&self) -> usize { 0 } @@ -717,7 +720,7 @@ impl Operator for FunctionIdentifier { false } - fn argument_amount(&self) -> usize { + fn max_argument_amount(&self) -> usize { 1 } diff --git a/src/tree/mod.rs b/src/tree/mod.rs index ef15ce3..6ce412d 100644 --- a/src/tree/mod.rs +++ b/src/tree/mod.rs @@ -264,8 +264,8 @@ impl Node { &self.operator } - fn has_correct_amount_of_children(&self) -> bool { - self.children().len() == self.operator().argument_amount() + fn has_enough_children(&self) -> bool { + self.children().len() == self.operator().max_argument_amount() } fn insert_back_prioritized(&mut self, node: Node, is_root_node: bool) -> EvalexprResult<()> { @@ -275,7 +275,7 @@ impl Node { { if self.operator().is_leaf() { Err(EvalexprError::AppendedToLeafNode) - } else if self.has_correct_amount_of_children() { + } else if self.has_enough_children() { if self.children.last().unwrap().operator().precedence() < node.operator().precedence() // Right-to-left chaining @@ -381,17 +381,8 @@ pub(crate) fn tokens_to_operator_tree(tokens: Vec) -> EvalexprResult 1 { Err(EvalexprError::UnmatchedLBrace) - } else if let Some(mut root) = root.pop() { - if root.children().len() > 1 { - Err(EvalexprError::wrong_operator_argument_amount( - root.children().len(), - 1, - )) - } else if let Some(child) = root.children.pop() { - Ok(child) - } else { - Err(EvalexprError::EmptyExpression) - } + } else if let Some(root) = root.pop() { + Ok(root) } else { Err(EvalexprError::UnmatchedRBrace) }