1
0
Fork 0

Add short-circuiting for 'and' and 'or'

This commit is contained in:
Vili Sinervä 2025-02-03 18:17:25 +02:00
parent 1ed2ac97cc
commit f4b208dfde
No known key found for this signature in database
GPG key ID: DF8FEAF54EFAC996
2 changed files with 34 additions and 28 deletions

View file

@ -40,8 +40,40 @@ impl<'source> Interpreter<'source> {
"<=" => Value::Bool(self.interpret(left) <= self.interpret(right)), "<=" => Value::Bool(self.interpret(left) <= self.interpret(right)),
">" => Value::Bool(self.interpret(left) > self.interpret(right)), ">" => Value::Bool(self.interpret(left) > self.interpret(right)),
">=" => Value::Bool(self.interpret(left) >= self.interpret(right)), ">=" => Value::Bool(self.interpret(left) >= self.interpret(right)),
"and" => self.interpret(left).and(&self.interpret(right)), "and" => {
"or" => self.interpret(left).or(&self.interpret(right)), let left_val = self.interpret(left);
if let Value::Bool(val_l) = left_val {
if !val_l {
Value::Bool(false)
} else {
let right_val = self.interpret(right);
if let Value::Bool(val_r) = right_val {
Value::Bool(val_r)
} else {
panic!("Non-bool with and operator");
}
}
} else {
panic!("Non-bool with and operator");
}
}
"or" => {
let left_val = self.interpret(left);
if let Value::Bool(val_l) = left_val {
if val_l {
Value::Bool(true)
} else {
let right_val = self.interpret(right);
if let Value::Bool(val_r) = right_val {
Value::Bool(val_r)
} else {
panic!("Non-bool with and operator");
}
}
} else {
panic!("Non-bool with and operator");
}
}
"=" => { "=" => {
if let Expression::Identifier(_, name) = **left { if let Expression::Identifier(_, name) = **left {
let val = self.interpret(right); let val = self.interpret(right);

View file

@ -10,32 +10,6 @@ pub enum Value {
None(), None(),
} }
impl Value {
pub fn and(&self, other: &Self) -> Self {
if let Value::Bool(val1) = self {
if let Value::Bool(val2) = other {
Value::Bool(*val1 && *val2)
} else {
panic!("Can't apply and to non-bools!")
}
} else {
panic!("Can't apply and to non-bools!!")
}
}
pub fn or(&self, other: &Self) -> Self {
if let Value::Bool(val1) = self {
if let Value::Bool(val2) = other {
Value::Bool(*val1 || *val2)
} else {
panic!("Can't apply or to non-bools!")
}
} else {
panic!("Can't apply or to non-bools!!")
}
}
}
impl fmt::Display for Value { impl fmt::Display for Value {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { match self {