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)),
|
">" => 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);
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Reference in a new issue