diff --git a/src/lib.rs b/src/lib.rs index 4745995..de23244 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -69,10 +69,10 @@ //! configuration.insert_variable("a", 6); //! configuration.insert_variable("b", 2); //! configuration.insert_variable("c", 3); -//! assert_eq!(precompiled.eval(&configuration), Ok(Value::from(true))); +//! assert_eq!(precompiled.eval_with_configuration(&configuration), Ok(Value::from(true))); //! //! configuration.insert_variable("c", 8); -//! assert_eq!(precompiled.eval(&configuration), Ok(Value::from(false))); +//! assert_eq!(precompiled.eval_with_configuration(&configuration), Ok(Value::from(false))); //! ``` //! //! ## Features @@ -234,7 +234,7 @@ pub use value::Value; /// /// *See the [crate doc](index.html) for more examples and explanations of the expression format.* pub fn eval(string: &str) -> Result { - tree::tokens_to_operator_tree(token::tokenize(string)?)?.eval(&EmptyConfiguration) + eval_with_configuration(string, &EmptyConfiguration) } /// Evaluate the given expression string with the given configuration. @@ -256,7 +256,7 @@ pub fn eval_with_configuration( string: &str, configuration: &Configuration, ) -> Result { - tree::tokens_to_operator_tree(token::tokenize(string)?)?.eval(configuration) + tree::tokens_to_operator_tree(token::tokenize(string)?)?.eval_with_configuration(configuration) } /// Build the operator tree for the given expression string. @@ -276,10 +276,10 @@ pub fn eval_with_configuration( /// configuration.insert_variable("two", 2); /// configuration.insert_variable("three", 3); /// -/// assert_eq!(precomputed.eval(&configuration), Ok(Value::from(6))); +/// assert_eq!(precomputed.eval_with_configuration(&configuration), Ok(Value::from(6))); /// /// configuration.insert_variable("three", 5); -/// assert_eq!(precomputed.eval(&configuration), Ok(Value::from(8))); +/// assert_eq!(precomputed.eval_with_configuration(&configuration), Ok(Value::from(8))); /// ``` /// /// *See the [crate doc](index.html) for more examples and explanations of the expression format.* diff --git a/src/tree/mod.rs b/src/tree/mod.rs index 68e4ebc..0a9baf9 100644 --- a/src/tree/mod.rs +++ b/src/tree/mod.rs @@ -1,5 +1,6 @@ use crate::{configuration::Configuration, error::Error, operator::*, value::Value}; use token::Token; +use EmptyConfiguration; mod display; @@ -7,13 +8,17 @@ mod display; /// The operator tree is created by the crate-level `build_operator_tree` method. /// It can be evaluated for a given configuration with the `Node::eval` method. /// +/// The advantage of constructing the operator tree separately from the actual evaluation is that it can be evaluated arbitrarily often with different configurations. +/// /// # Examples /// /// ```rust /// use evalexpr::*; /// -/// let node = build_operator_tree("1 + 2").unwrap(); -/// assert_eq!(node.eval(&EmptyConfiguration), Ok(Value::from(3))); +/// let mut configuration = HashMapConfiguration::new(); +/// configuration.insert_variable("alpha", 2); +/// let node = build_operator_tree("1 + alpha").unwrap(); +/// assert_eq!(node.eval_with_configuration(&configuration), Ok(Value::from(3))); /// ``` /// #[derive(Debug)] @@ -34,17 +39,24 @@ impl Node { Self::new(RootNode) } - /// Evaluates the operator tree rooted at this node. + /// Evaluates the operator tree rooted at this node with the given configuration. /// - /// Fails, if an operator is used with a wrong number of arguments or a wrong type. - pub fn eval(&self, configuration: &Configuration) -> Result { + /// Fails, if one of the operators in the expression tree fails. + pub fn eval_with_configuration(&self, configuration: &Configuration) -> Result { let mut arguments = Vec::new(); for child in self.children() { - arguments.push(child.eval(configuration)?); + arguments.push(child.eval_with_configuration(configuration)?); } self.operator().eval(&arguments, configuration) } + /// Evaluates the operator tree rooted at this node with an empty configuration. + /// + /// Fails, if one of the operators in the expression tree fails. + pub fn eval(&self) -> Result { + self.eval_with_configuration(&EmptyConfiguration) + } + fn children(&self) -> &[Node] { &self.children }