aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEdvard Thörnros <edvard.thornros@gmail.com>2021-03-07 19:09:33 +0100
committerEdvard Thörnros <edvard.thornros@gmail.com>2021-03-07 19:09:33 +0100
commit42909d2d19d60d24da79f79e24d06554484771db (patch)
tree7be77c826067492306345152daf559744df4e0cf
parent09c830296fdb55efbc7f590337ce72f5ec75c04b (diff)
downloadsylt-42909d2d19d60d24da79f79e24d06554484771db.tar.gz
add short-circuiting logic
-rw-r--r--src/compiler.rs37
1 files changed, 35 insertions, 2 deletions
diff --git a/src/compiler.rs b/src/compiler.rs
index dc3bd96..2aad62b 100644
--- a/src/compiler.rs
+++ b/src/compiler.rs
@@ -182,7 +182,8 @@ macro_rules! push_scope {
nextable_enum!(Prec {
No,
Assert,
- Bool,
+ BoolOr,
+ BoolAnd,
Comp,
Term,
Factor,
@@ -615,7 +616,8 @@ impl Compiler {
| Token::NotEqual
=> Prec::Comp,
- Token::And | Token::Or => Prec::Bool,
+ Token::And => Prec::BoolAnd,
+ Token::Or => Prec::BoolOr,
Token::AssertEqual => Prec::Assert,
@@ -656,6 +658,9 @@ impl Compiler {
| Token::NotEqual
=> self.binary(block),
+ Token::And | Token::Or
+ => self.binary_bool(block),
+
Token::LeftBracket => self.index(block),
_ => { return false; },
@@ -741,6 +746,34 @@ impl Compiler {
add_op(self, block, op);
}
+ fn binary_bool(&mut self, block: &mut Block) {
+ let op = self.eat();
+
+ match op {
+ Token::And => {
+ add_op(self, block, Op::Copy);
+ let jump = add_op(self, block, Op::Illegal);
+
+ self.parse_precedence(block, self.precedence(op.clone()).next());
+
+ block.patch(Op::JmpFalse(block.curr()), jump);
+ }
+
+ Token::Or => {
+ add_op(self, block, Op::Copy);
+ let skipp = add_op(self, block, Op::Illegal);
+ let jump = add_op(self, block, Op::Illegal);
+ block.patch(Op::JmpFalse(block.curr()), skipp);
+
+ self.parse_precedence(block, self.precedence(op.clone()).next());
+
+ block.patch(Op::Jmp(block.curr()), jump);
+ }
+
+ _ => { error!(self, "Illegal operator"); }
+ }
+ }
+
fn binary(&mut self, block: &mut Block) {
let op = self.eat();