diff --git a/src/operator/display.rs b/src/operator/display.rs index d4291e7..12351dd 100644 --- a/src/operator/display.rs +++ b/src/operator/display.rs @@ -41,7 +41,9 @@ impl Display for Operator { Chain => write!(f, "; "), Const { value } => write!(f, "{}", value), - VariableIdentifier { identifier } => write!(f, "{}", identifier), + VariableIdentifierWrite { identifier } | VariableIdentifierRead { identifier } => { + write!(f, "{}", identifier) + }, FunctionIdentifier { identifier } => write!(f, "{}", identifier), } } diff --git a/src/operator/mod.rs b/src/operator/mod.rs index a8ae045..5f2be51 100644 --- a/src/operator/mod.rs +++ b/src/operator/mod.rs @@ -75,8 +75,13 @@ pub enum Operator { /** The value of the constant. */ value: Value, }, - /// A variable identifier. - VariableIdentifier { + /// A write to a variable identifier. + VariableIdentifierWrite { + /// The identifier of the variable. + identifier: String, + }, + /// A read from a variable identifier. + VariableIdentifierRead { /// The identifier of the variable. identifier: String, }, @@ -92,8 +97,12 @@ impl Operator { Operator::Const { value } } - pub(crate) fn variable_identifier(identifier: String) -> Self { - Operator::VariableIdentifier { identifier } + pub(crate) fn variable_identifier_write(identifier: String) -> Self { + Operator::VariableIdentifierWrite { identifier } + } + + pub(crate) fn variable_identifier_read(identifier: String) -> Self { + Operator::VariableIdentifierRead { identifier } } pub(crate) fn function_identifier(identifier: String) -> Self { @@ -124,7 +133,7 @@ impl Operator { Chain => 0, Const { .. } => 200, - VariableIdentifier { .. } => 200, + VariableIdentifierWrite { .. } | VariableIdentifierRead { .. } => 200, FunctionIdentifier { .. } => 190, } } @@ -159,7 +168,7 @@ impl Operator { Tuple | Chain => None, Not | Neg | RootNode => Some(1), Const { .. } => Some(0), - VariableIdentifier { .. } => Some(0), + VariableIdentifierWrite { .. } | VariableIdentifierRead { .. } => Some(0), FunctionIdentifier { .. } => Some(1), } } @@ -422,7 +431,12 @@ impl Operator { Ok(value.clone()) }, - VariableIdentifier { identifier } => { + VariableIdentifierWrite { identifier } => { + expect_operator_argument_amount(arguments.len(), 0)?; + + Ok(identifier.clone().into()) + }, + VariableIdentifierRead { identifier } => { expect_operator_argument_amount(arguments.len(), 0)?; if let Some(value) = context.get_value(identifier).cloned() { @@ -473,7 +487,7 @@ impl Operator { expect_operator_argument_amount(arguments.len(), 2)?; let target = arguments[0].as_string()?; - let left_value = Operator::VariableIdentifier { + let left_value = Operator::VariableIdentifierRead { identifier: target.clone(), } .eval(&Vec::new(), context)?; diff --git a/src/tree/mod.rs b/src/tree/mod.rs index 69f4494..1956e56 100644 --- a/src/tree/mod.rs +++ b/src/tree/mod.rs @@ -69,7 +69,8 @@ impl Node { /// ``` pub fn iter_identifiers(&self) -> impl Iterator { self.iter().filter_map(|node| match node.operator() { - Operator::VariableIdentifier { identifier } + Operator::VariableIdentifierWrite { identifier } + | Operator::VariableIdentifierRead { identifier } | Operator::FunctionIdentifier { identifier } => Some(identifier.as_str()), _ => None, }) @@ -92,7 +93,8 @@ impl Node { /// ``` pub fn iter_variable_identifiers(&self) -> impl Iterator { self.iter().filter_map(|node| match node.operator() { - Operator::VariableIdentifier { identifier } => Some(identifier.as_str()), + Operator::VariableIdentifierWrite { identifier } + | Operator::VariableIdentifierRead { identifier } => Some(identifier.as_str()), _ => None, }) } @@ -616,10 +618,14 @@ pub(crate) fn tokens_to_operator_tree(tokens: Vec) -> EvalexprResult Some(Node::new(Operator::Chain)), Token::Identifier(identifier) => { - let mut result = Some(Node::new(Operator::variable_identifier(identifier.clone()))); + let mut result = Some(Node::new(Operator::variable_identifier_read( + identifier.clone(), + ))); if let Some(next) = next { if next.is_assignment() { - result = Some(Node::new(Operator::value(identifier.clone().into()))); + result = Some(Node::new(Operator::variable_identifier_write( + identifier.clone(), + ))); } else if next.is_leftsided_value() { result = Some(Node::new(Operator::function_identifier(identifier))); } diff --git a/tests/integration.rs b/tests/integration.rs index 30f20d4..9524da3 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -2090,7 +2090,7 @@ fn assignment_lhs_is_identifier() { let operators: Vec<_> = tree.iter().map(|node| node.operator().clone()).collect(); let mut context = HashMapContext::new(); - tree.eval_empty_with_context_mut(&mut context).unwrap(); + tree.eval_with_context_mut(&mut context).unwrap(); assert_eq!(context.get_value("a"), Some(&Value::Int(1))); assert!( @@ -2098,7 +2098,7 @@ fn assignment_lhs_is_identifier() { operators.as_slice(), [ Operator::Assign, - Operator::VariableIdentifier { identifier: value }, + Operator::VariableIdentifierWrite { identifier: value }, Operator::Const { value: Value::Int(1) }