Add short-circuiting for 'and' and 'or'
This commit is contained in:
parent
1ed2ac97cc
commit
f4b208dfde
2 changed files with 34 additions and 28 deletions
|
@ -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)),
|
||||
"and" => self.interpret(left).and(&self.interpret(right)),
|
||||
"or" => self.interpret(left).or(&self.interpret(right)),
|
||||
"and" => {
|
||||
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 {
|
||||
let val = self.interpret(right);
|
||||
|
|
|
@ -10,32 +10,6 @@ pub enum Value {
|
|||
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 {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
|
|
Reference in a new issue