parent
b9c4b34a2f
commit
b7233a3337
@ -25,9 +25,17 @@ impl Display for Operator {
|
|||||||
Or => write!(f, "||"),
|
Or => write!(f, "||"),
|
||||||
Not => write!(f, "!"),
|
Not => write!(f, "!"),
|
||||||
|
|
||||||
Tuple => write!(f, ", "),
|
|
||||||
Assign => write!(f, " = "),
|
Assign => write!(f, " = "),
|
||||||
|
AddAssign => write!(f, " += "),
|
||||||
|
SubAssign => write!(f, " -= "),
|
||||||
|
MulAssign => write!(f, " *= "),
|
||||||
|
DivAssign => write!(f, " /= "),
|
||||||
|
ModAssign => write!(f, " %= "),
|
||||||
|
ExpAssign => write!(f, " ^= "),
|
||||||
|
AndAssign => write!(f, " &&= "),
|
||||||
|
OrAssign => write!(f, " ||= "),
|
||||||
|
|
||||||
|
Tuple => write!(f, ", "),
|
||||||
Chain => write!(f, "; "),
|
Chain => write!(f, "; "),
|
||||||
|
|
||||||
Const { value } => write!(f, "{}", value),
|
Const { value } => write!(f, "{}", value),
|
||||||
|
@ -26,9 +26,17 @@ pub enum Operator {
|
|||||||
Or,
|
Or,
|
||||||
Not,
|
Not,
|
||||||
|
|
||||||
Tuple,
|
|
||||||
Assign,
|
Assign,
|
||||||
|
AddAssign,
|
||||||
|
SubAssign,
|
||||||
|
MulAssign,
|
||||||
|
DivAssign,
|
||||||
|
ModAssign,
|
||||||
|
ExpAssign,
|
||||||
|
AndAssign,
|
||||||
|
OrAssign,
|
||||||
|
|
||||||
|
Tuple,
|
||||||
Chain,
|
Chain,
|
||||||
|
|
||||||
Const { value: Value },
|
Const { value: Value },
|
||||||
@ -67,9 +75,10 @@ impl Operator {
|
|||||||
Or => 70,
|
Or => 70,
|
||||||
Not => 110,
|
Not => 110,
|
||||||
|
|
||||||
Tuple => 40,
|
Assign | AddAssign | SubAssign | MulAssign | DivAssign | ModAssign | ExpAssign
|
||||||
Assign => 50,
|
| AndAssign | OrAssign => 50,
|
||||||
|
|
||||||
|
Tuple => 40,
|
||||||
Chain => 0,
|
Chain => 0,
|
||||||
|
|
||||||
Const { value: _ } => 200,
|
Const { value: _ } => 200,
|
||||||
@ -113,7 +122,8 @@ impl Operator {
|
|||||||
use crate::operator::Operator::*;
|
use crate::operator::Operator::*;
|
||||||
match self {
|
match self {
|
||||||
Add | Sub | Mul | Div | Mod | Exp | Eq | Neq | Gt | Lt | Geq | Leq | And | Or
|
Add | Sub | Mul | Div | Mod | Exp | Eq | Neq | Gt | Lt | Geq | Leq | And | Or
|
||||||
| Assign => Some(2),
|
| Assign | AddAssign | SubAssign | MulAssign | DivAssign | ModAssign | ExpAssign
|
||||||
|
| AndAssign | OrAssign => Some(2),
|
||||||
Tuple | Chain => None,
|
Tuple | Chain => None,
|
||||||
Not | Neg | RootNode => Some(1),
|
Not | Neg | RootNode => Some(1),
|
||||||
Const { value: _ } => Some(0),
|
Const { value: _ } => Some(0),
|
||||||
@ -420,8 +430,9 @@ impl Operator {
|
|||||||
Ok(Value::Boolean(false))
|
Ok(Value::Boolean(false))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Assign | AddAssign | SubAssign | MulAssign | DivAssign | ModAssign | ExpAssign
|
||||||
|
| AndAssign | OrAssign => Err(EvalexprError::ContextNotManipulable),
|
||||||
Tuple => Ok(Value::Tuple(arguments.into())),
|
Tuple => Ok(Value::Tuple(arguments.into())),
|
||||||
Assign => Err(EvalexprError::ContextNotManipulable),
|
|
||||||
Chain => {
|
Chain => {
|
||||||
if arguments.is_empty() {
|
if arguments.is_empty() {
|
||||||
return Err(EvalexprError::wrong_operator_argument_amount(0, 1));
|
return Err(EvalexprError::wrong_operator_argument_amount(0, 1));
|
||||||
@ -435,6 +446,8 @@ impl Operator {
|
|||||||
Ok(value.clone())
|
Ok(value.clone())
|
||||||
},
|
},
|
||||||
VariableIdentifier { identifier } => {
|
VariableIdentifier { identifier } => {
|
||||||
|
expect_operator_argument_amount(arguments.len(), 0)?;
|
||||||
|
|
||||||
if let Some(value) = context.get_value(&identifier).cloned() {
|
if let Some(value) = context.get_value(&identifier).cloned() {
|
||||||
Ok(value)
|
Ok(value)
|
||||||
} else {
|
} else {
|
||||||
@ -475,6 +488,35 @@ impl Operator {
|
|||||||
|
|
||||||
Ok(Value::Empty)
|
Ok(Value::Empty)
|
||||||
},
|
},
|
||||||
|
AddAssign | SubAssign | MulAssign | DivAssign | ModAssign | ExpAssign | AndAssign
|
||||||
|
| OrAssign => {
|
||||||
|
expect_operator_argument_amount(arguments.len(), 2)?;
|
||||||
|
|
||||||
|
let target = arguments[0].as_string()?;
|
||||||
|
let left_value = Operator::VariableIdentifier {
|
||||||
|
identifier: target.clone(),
|
||||||
|
}
|
||||||
|
.eval(&Vec::new(), context)?;
|
||||||
|
let arguments = vec![left_value, arguments[1].clone()];
|
||||||
|
|
||||||
|
let result = match self {
|
||||||
|
AddAssign => Operator::Add.eval(&arguments, context),
|
||||||
|
SubAssign => Operator::Sub.eval(&arguments, context),
|
||||||
|
MulAssign => Operator::Mul.eval(&arguments, context),
|
||||||
|
DivAssign => Operator::Div.eval(&arguments, context),
|
||||||
|
ModAssign => Operator::Mod.eval(&arguments, context),
|
||||||
|
ExpAssign => Operator::Exp.eval(&arguments, context),
|
||||||
|
AndAssign => Operator::And.eval(&arguments, context),
|
||||||
|
OrAssign => Operator::Or.eval(&arguments, context),
|
||||||
|
_ => unreachable!(
|
||||||
|
"Forgot to add a match arm for an assign operation: {}",
|
||||||
|
self
|
||||||
|
),
|
||||||
|
}?;
|
||||||
|
context.set_value(target.into(), result)?;
|
||||||
|
|
||||||
|
Ok(Value::Empty)
|
||||||
|
},
|
||||||
_ => self.eval(arguments, context),
|
_ => self.eval(arguments, context),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,9 +28,19 @@ impl fmt::Display for Token {
|
|||||||
LBrace => write!(f, "("),
|
LBrace => write!(f, "("),
|
||||||
RBrace => write!(f, ")"),
|
RBrace => write!(f, ")"),
|
||||||
|
|
||||||
|
// Assignment
|
||||||
|
Assign => write!(f, "="),
|
||||||
|
PlusAssign => write!(f, "+="),
|
||||||
|
MinusAssign => write!(f, "-="),
|
||||||
|
StarAssign => write!(f, "*="),
|
||||||
|
SlashAssign => write!(f, "/="),
|
||||||
|
PercentAssign => write!(f, "%="),
|
||||||
|
HatAssign => write!(f, "^="),
|
||||||
|
AndAssign => write!(f, "&&="),
|
||||||
|
OrAssign => write!(f, "||="),
|
||||||
|
|
||||||
// Special
|
// Special
|
||||||
Comma => write!(f, ","),
|
Comma => write!(f, ","),
|
||||||
Assign => write!(f, "="),
|
|
||||||
Semicolon => write!(f, ";"),
|
Semicolon => write!(f, ";"),
|
||||||
|
|
||||||
// Values => write!(f, ""), Variables and Functions
|
// Values => write!(f, ""), Variables and Functions
|
||||||
@ -50,6 +60,12 @@ impl fmt::Display for PartialToken {
|
|||||||
Token(token) => token.fmt(f),
|
Token(token) => token.fmt(f),
|
||||||
Literal(literal) => literal.fmt(f),
|
Literal(literal) => literal.fmt(f),
|
||||||
Whitespace => write!(f, " "),
|
Whitespace => write!(f, " "),
|
||||||
|
Plus => write!(f, "+"),
|
||||||
|
Minus => write!(f, "-"),
|
||||||
|
Star => write!(f, "*"),
|
||||||
|
Slash => write!(f, "/"),
|
||||||
|
Percent => write!(f, "%"),
|
||||||
|
Hat => write!(f, "^"),
|
||||||
Eq => write!(f, "="),
|
Eq => write!(f, "="),
|
||||||
ExclamationMark => write!(f, "!"),
|
ExclamationMark => write!(f, "!"),
|
||||||
Gt => write!(f, ">"),
|
Gt => write!(f, ">"),
|
||||||
|
120
src/token/mod.rs
120
src/token/mod.rs
@ -30,9 +30,19 @@ pub enum Token {
|
|||||||
LBrace,
|
LBrace,
|
||||||
RBrace,
|
RBrace,
|
||||||
|
|
||||||
|
// Assignment
|
||||||
|
Assign,
|
||||||
|
PlusAssign,
|
||||||
|
MinusAssign,
|
||||||
|
StarAssign,
|
||||||
|
SlashAssign,
|
||||||
|
PercentAssign,
|
||||||
|
HatAssign,
|
||||||
|
AndAssign,
|
||||||
|
OrAssign,
|
||||||
|
|
||||||
// Special
|
// Special
|
||||||
Comma,
|
Comma,
|
||||||
Assign,
|
|
||||||
Semicolon,
|
Semicolon,
|
||||||
|
|
||||||
// Values, Variables and Functions
|
// Values, Variables and Functions
|
||||||
@ -47,6 +57,12 @@ pub enum Token {
|
|||||||
pub enum PartialToken {
|
pub enum PartialToken {
|
||||||
Token(Token),
|
Token(Token),
|
||||||
Literal(String),
|
Literal(String),
|
||||||
|
Plus,
|
||||||
|
Minus,
|
||||||
|
Star,
|
||||||
|
Slash,
|
||||||
|
Percent,
|
||||||
|
Hat,
|
||||||
Whitespace,
|
Whitespace,
|
||||||
Eq,
|
Eq,
|
||||||
ExclamationMark,
|
ExclamationMark,
|
||||||
@ -59,12 +75,12 @@ pub enum PartialToken {
|
|||||||
// Make this a const fn as soon as match gets stable (issue #57563)
|
// Make this a const fn as soon as match gets stable (issue #57563)
|
||||||
fn char_to_partial_token(c: char) -> PartialToken {
|
fn char_to_partial_token(c: char) -> PartialToken {
|
||||||
match c {
|
match c {
|
||||||
'+' => PartialToken::Token(Token::Plus),
|
'+' => PartialToken::Plus,
|
||||||
'-' => PartialToken::Token(Token::Minus),
|
'-' => PartialToken::Minus,
|
||||||
'*' => PartialToken::Token(Token::Star),
|
'*' => PartialToken::Star,
|
||||||
'/' => PartialToken::Token(Token::Slash),
|
'/' => PartialToken::Slash,
|
||||||
'%' => PartialToken::Token(Token::Percent),
|
'%' => PartialToken::Percent,
|
||||||
'^' => PartialToken::Token(Token::Hat),
|
'^' => PartialToken::Hat,
|
||||||
|
|
||||||
'(' => PartialToken::Token(Token::LBrace),
|
'(' => PartialToken::Token(Token::LBrace),
|
||||||
')' => PartialToken::Token(Token::RBrace),
|
')' => PartialToken::Token(Token::RBrace),
|
||||||
@ -114,9 +130,18 @@ impl Token {
|
|||||||
Token::RBrace => false,
|
Token::RBrace => false,
|
||||||
|
|
||||||
Token::Comma => false,
|
Token::Comma => false,
|
||||||
Token::Assign => false,
|
|
||||||
Token::Semicolon => false,
|
Token::Semicolon => false,
|
||||||
|
|
||||||
|
Token::Assign => false,
|
||||||
|
Token::PlusAssign => false,
|
||||||
|
Token::MinusAssign => false,
|
||||||
|
Token::StarAssign => false,
|
||||||
|
Token::SlashAssign => false,
|
||||||
|
Token::PercentAssign => false,
|
||||||
|
Token::HatAssign => false,
|
||||||
|
Token::AndAssign => false,
|
||||||
|
Token::OrAssign => false,
|
||||||
|
|
||||||
Token::Identifier(_) => true,
|
Token::Identifier(_) => true,
|
||||||
Token::Float(_) => true,
|
Token::Float(_) => true,
|
||||||
Token::Int(_) => true,
|
Token::Int(_) => true,
|
||||||
@ -149,9 +174,18 @@ impl Token {
|
|||||||
Token::RBrace => true,
|
Token::RBrace => true,
|
||||||
|
|
||||||
Token::Comma => false,
|
Token::Comma => false,
|
||||||
Token::Assign => false,
|
|
||||||
Token::Semicolon => false,
|
Token::Semicolon => false,
|
||||||
|
|
||||||
|
Token::Assign => false,
|
||||||
|
Token::PlusAssign => false,
|
||||||
|
Token::MinusAssign => false,
|
||||||
|
Token::StarAssign => false,
|
||||||
|
Token::SlashAssign => false,
|
||||||
|
Token::PercentAssign => false,
|
||||||
|
Token::HatAssign => false,
|
||||||
|
Token::AndAssign => false,
|
||||||
|
Token::OrAssign => false,
|
||||||
|
|
||||||
Token::Identifier(_) => true,
|
Token::Identifier(_) => true,
|
||||||
Token::Float(_) => true,
|
Token::Float(_) => true,
|
||||||
Token::Int(_) => true,
|
Token::Int(_) => true,
|
||||||
@ -159,6 +193,15 @@ impl Token {
|
|||||||
Token::String(_) => true,
|
Token::String(_) => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn is_assignment(&self) -> bool {
|
||||||
|
use Token::*;
|
||||||
|
match self {
|
||||||
|
Assign | PlusAssign | MinusAssign | StarAssign | SlashAssign | PercentAssign
|
||||||
|
| HatAssign | AndAssign | OrAssign => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses an escape sequence within a string literal.
|
/// Parses an escape sequence within a string literal.
|
||||||
@ -228,6 +271,7 @@ fn partial_tokens_to_tokens(mut tokens: &[PartialToken]) -> EvalexprResult<Vec<T
|
|||||||
while tokens.len() > 0 {
|
while tokens.len() > 0 {
|
||||||
let first = tokens[0].clone();
|
let first = tokens[0].clone();
|
||||||
let second = tokens.get(1).cloned();
|
let second = tokens.get(1).cloned();
|
||||||
|
let third = tokens.get(2).cloned();
|
||||||
let mut cutoff = 2;
|
let mut cutoff = 2;
|
||||||
|
|
||||||
result.extend(
|
result.extend(
|
||||||
@ -236,6 +280,48 @@ fn partial_tokens_to_tokens(mut tokens: &[PartialToken]) -> EvalexprResult<Vec<T
|
|||||||
cutoff = 1;
|
cutoff = 1;
|
||||||
Some(token)
|
Some(token)
|
||||||
},
|
},
|
||||||
|
PartialToken::Plus => match second {
|
||||||
|
Some(PartialToken::Eq) => Some(Token::PlusAssign),
|
||||||
|
_ => {
|
||||||
|
cutoff = 1;
|
||||||
|
Some(Token::Plus)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
PartialToken::Minus => match second {
|
||||||
|
Some(PartialToken::Eq) => Some(Token::MinusAssign),
|
||||||
|
_ => {
|
||||||
|
cutoff = 1;
|
||||||
|
Some(Token::Minus)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
PartialToken::Star => match second {
|
||||||
|
Some(PartialToken::Eq) => Some(Token::StarAssign),
|
||||||
|
_ => {
|
||||||
|
cutoff = 1;
|
||||||
|
Some(Token::Star)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
PartialToken::Slash => match second {
|
||||||
|
Some(PartialToken::Eq) => Some(Token::SlashAssign),
|
||||||
|
_ => {
|
||||||
|
cutoff = 1;
|
||||||
|
Some(Token::Slash)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
PartialToken::Percent => match second {
|
||||||
|
Some(PartialToken::Eq) => Some(Token::PercentAssign),
|
||||||
|
_ => {
|
||||||
|
cutoff = 1;
|
||||||
|
Some(Token::Percent)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
PartialToken::Hat => match second {
|
||||||
|
Some(PartialToken::Eq) => Some(Token::HatAssign),
|
||||||
|
_ => {
|
||||||
|
cutoff = 1;
|
||||||
|
Some(Token::Hat)
|
||||||
|
},
|
||||||
|
},
|
||||||
PartialToken::Literal(literal) => {
|
PartialToken::Literal(literal) => {
|
||||||
cutoff = 1;
|
cutoff = 1;
|
||||||
if let Ok(number) = literal.parse::<IntType>() {
|
if let Ok(number) = literal.parse::<IntType>() {
|
||||||
@ -281,11 +367,23 @@ fn partial_tokens_to_tokens(mut tokens: &[PartialToken]) -> EvalexprResult<Vec<T
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
PartialToken::Ampersand => match second {
|
PartialToken::Ampersand => match second {
|
||||||
Some(PartialToken::Ampersand) => Some(Token::And),
|
Some(PartialToken::Ampersand) => match third {
|
||||||
|
Some(PartialToken::Eq) => {
|
||||||
|
cutoff = 3;
|
||||||
|
Some(Token::AndAssign)
|
||||||
|
},
|
||||||
|
_ => Some(Token::And),
|
||||||
|
},
|
||||||
_ => return Err(EvalexprError::unmatched_partial_token(first, second)),
|
_ => return Err(EvalexprError::unmatched_partial_token(first, second)),
|
||||||
},
|
},
|
||||||
PartialToken::VerticalBar => match second {
|
PartialToken::VerticalBar => match second {
|
||||||
Some(PartialToken::VerticalBar) => Some(Token::Or),
|
Some(PartialToken::VerticalBar) => match third {
|
||||||
|
Some(PartialToken::Eq) => {
|
||||||
|
cutoff = 3;
|
||||||
|
Some(Token::OrAssign)
|
||||||
|
},
|
||||||
|
_ => Some(Token::Or),
|
||||||
|
},
|
||||||
_ => return Err(EvalexprError::unmatched_partial_token(first, second)),
|
_ => return Err(EvalexprError::unmatched_partial_token(first, second)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -529,14 +529,23 @@ pub(crate) fn tokens_to_operator_tree(tokens: Vec<Token>) -> EvalexprResult<Node
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
Token::Comma => Some(Node::new(Operator::Tuple)),
|
|
||||||
Token::Assign => Some(Node::new(Operator::Assign)),
|
Token::Assign => Some(Node::new(Operator::Assign)),
|
||||||
|
Token::PlusAssign => Some(Node::new(Operator::AddAssign)),
|
||||||
|
Token::MinusAssign => Some(Node::new(Operator::SubAssign)),
|
||||||
|
Token::StarAssign => Some(Node::new(Operator::MulAssign)),
|
||||||
|
Token::SlashAssign => Some(Node::new(Operator::DivAssign)),
|
||||||
|
Token::PercentAssign => Some(Node::new(Operator::ModAssign)),
|
||||||
|
Token::HatAssign => Some(Node::new(Operator::ExpAssign)),
|
||||||
|
Token::AndAssign => Some(Node::new(Operator::AndAssign)),
|
||||||
|
Token::OrAssign => Some(Node::new(Operator::OrAssign)),
|
||||||
|
|
||||||
|
Token::Comma => Some(Node::new(Operator::Tuple)),
|
||||||
Token::Semicolon => Some(Node::new(Operator::Chain)),
|
Token::Semicolon => Some(Node::new(Operator::Chain)),
|
||||||
|
|
||||||
Token::Identifier(identifier) => {
|
Token::Identifier(identifier) => {
|
||||||
let mut result = Some(Node::new(Operator::variable_identifier(identifier.clone())));
|
let mut result = Some(Node::new(Operator::variable_identifier(identifier.clone())));
|
||||||
if let Some(next) = next {
|
if let Some(next) = next {
|
||||||
if next == &Token::Assign {
|
if next.is_assignment() {
|
||||||
result = Some(Node::new(Operator::value(identifier.clone().into())));
|
result = Some(Node::new(Operator::value(identifier.clone().into())));
|
||||||
} else if next.is_leftsided_value() {
|
} else if next.is_leftsided_value() {
|
||||||
result = Some(Node::new(Operator::function_identifier(identifier)));
|
result = Some(Node::new(Operator::function_identifier(identifier)));
|
||||||
|
@ -636,3 +636,62 @@ fn test_implicit_context() {
|
|||||||
Ok("xyzabc".to_string())
|
Ok("xyzabc".to_string())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_operator_assignments() {
|
||||||
|
let mut context = HashMapContext::new();
|
||||||
|
assert_eq!(eval_empty_with_context_mut("a = 5", &mut context), Ok(()));
|
||||||
|
assert_eq!(eval_empty_with_context_mut("a += 5", &mut context), Ok(()));
|
||||||
|
assert_eq!(eval_empty_with_context_mut("a -= 5", &mut context), Ok(()));
|
||||||
|
assert_eq!(eval_empty_with_context_mut("a *= 5", &mut context), Ok(()));
|
||||||
|
assert_eq!(eval_empty_with_context_mut("b = 5.0", &mut context), Ok(()));
|
||||||
|
assert_eq!(eval_empty_with_context_mut("b /= 5", &mut context), Ok(()));
|
||||||
|
assert_eq!(eval_empty_with_context_mut("b %= 5", &mut context), Ok(()));
|
||||||
|
assert_eq!(eval_empty_with_context_mut("b ^= 5", &mut context), Ok(()));
|
||||||
|
assert_eq!(
|
||||||
|
eval_empty_with_context_mut("c = true", &mut context),
|
||||||
|
Ok(())
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
eval_empty_with_context_mut("c &&= false", &mut context),
|
||||||
|
Ok(())
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
eval_empty_with_context_mut("c ||= true", &mut context),
|
||||||
|
Ok(())
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut context = HashMapContext::new();
|
||||||
|
assert_eq!(eval_int_with_context_mut("a = 5; a", &mut context), Ok(5));
|
||||||
|
assert_eq!(eval_int_with_context_mut("a += 3; a", &mut context), Ok(8));
|
||||||
|
assert_eq!(eval_int_with_context_mut("a -= 5; a", &mut context), Ok(3));
|
||||||
|
assert_eq!(eval_int_with_context_mut("a *= 5; a", &mut context), Ok(15));
|
||||||
|
assert_eq!(
|
||||||
|
eval_float_with_context_mut("b = 5.0; b", &mut context),
|
||||||
|
Ok(5.0)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
eval_float_with_context_mut("b /= 2; b", &mut context),
|
||||||
|
Ok(2.5)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
eval_float_with_context_mut("b %= 2; b", &mut context),
|
||||||
|
Ok(0.5)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
eval_float_with_context_mut("b ^= 2; b", &mut context),
|
||||||
|
Ok(0.25)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
eval_boolean_with_context_mut("c = true; c", &mut context),
|
||||||
|
Ok(true)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
eval_boolean_with_context_mut("c &&= false; c", &mut context),
|
||||||
|
Ok(false)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
eval_boolean_with_context_mut("c ||= true; c", &mut context),
|
||||||
|
Ok(true)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user