From 42909d2d19d60d24da79f79e24d06554484771db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edvard=20Th=C3=B6rnros?= Date: Sun, 7 Mar 2021 19:09:33 +0100 Subject: add short-circuiting logic --- src/compiler.rs | 37 +++++++++++++++++++++++++++++++++++-- 1 file 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(); -- cgit v1.2.1 From 9a36b08b5e67cc4a9bfc7fe83682c2f2951aa3ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edvard=20Th=C3=B6rnros?= Date: Sun, 7 Mar 2021 19:09:51 +0100 Subject: allow non-caputed upvalues to be dropped --- src/vm.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/vm.rs b/src/vm.rs index 7cfc8d3..7321deb 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -101,8 +101,6 @@ impl VM { if let Entry::Occupied(entry) = self.upvalues.entry(slot) { entry.get().borrow_mut().close(value); entry.remove(); - } else { - unreachable!(); } } -- cgit v1.2.1 From a40b38b048cf064927c21bc967b49600c891a483 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edvard=20Th=C3=B6rnros?= Date: Sun, 7 Mar 2021 19:10:11 +0100 Subject: add tests for boolean ops --- progs/tests/boolean_ops.sy | 56 ++++++++++++++++++++++++++++++++++++++++++++ progs/tests/boolean_order.sy | 42 +++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 progs/tests/boolean_ops.sy create mode 100644 progs/tests/boolean_order.sy diff --git a/progs/tests/boolean_ops.sy b/progs/tests/boolean_ops.sy new file mode 100644 index 0000000..368068b --- /dev/null +++ b/progs/tests/boolean_ops.sy @@ -0,0 +1,56 @@ +start :: fn { + ts := 0 + t :: fn -> bool { + ts += 1 + ret true + } + + fs := 0 + f :: fn -> bool { + fs += 1 + ret false + } + + i :: fn -> bool { + + ret false + } + + if f() && i() { + + } + + if t() || i() { + // Empty + } else { + + } + + if f() && i() && i() { + + } + + if t() || i() || i() { + // Empty + } else { + + } + + fs <=> 2 + ts <=> 2 +} + + + + // if t() || i() && f() { + // // Empty + // } else { + // + // } + + // if f() && t() || i() { + // // Empty + // } else { + // + // } + diff --git a/progs/tests/boolean_order.sy b/progs/tests/boolean_order.sy new file mode 100644 index 0000000..ecec262 --- /dev/null +++ b/progs/tests/boolean_order.sy @@ -0,0 +1,42 @@ +start :: fn { + ts := 0 + t :: fn -> bool { + ts += 1 + ret true + } + + fs := 0 + f :: fn -> bool { + fs += 1 + ret false + } + + i :: fn -> bool { + + ret false + } + + if t() || i() && i() { + // Empty + } else { + + } + + if f() && i() || t() { + // Empty + } else { + + } + + fs <=> 1 + fs = 0 + ts <=> 2 + ts = 0 + + f() && i() || f() <=> t() && f() || f() + f() && i() || f() <=> (t() && f()) || f() + t() && t() && f() || t() <=> t() || i() && i() && i() + + fs <=> 9 + ts <=> 6 +} -- cgit v1.2.1