diff options
| author | Edvard Thörnros <edvard.thornros@gmail.com> | 2021-03-07 19:09:33 +0100 |
|---|---|---|
| committer | Edvard Thörnros <edvard.thornros@gmail.com> | 2021-03-07 19:09:33 +0100 |
| commit | 42909d2d19d60d24da79f79e24d06554484771db (patch) | |
| tree | 7be77c826067492306345152daf559744df4e0cf /src/compiler.rs | |
| parent | 09c830296fdb55efbc7f590337ce72f5ec75c04b (diff) | |
| download | sylt-42909d2d19d60d24da79f79e24d06554484771db.tar.gz | |
add short-circuiting logic
Diffstat (limited to 'src/compiler.rs')
| -rw-r--r-- | src/compiler.rs | 37 |
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(); |
