aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEdvard Thörnros <edvard.thornros@gmail.com>2021-03-08 17:11:34 +0100
committerGitHub <noreply@github.com>2021-03-08 17:11:34 +0100
commitc61fb2a37fee54b7eb42da074e8c1b42aa6a42f1 (patch)
tree8002080789ac944ec018050c1be9941455fdd9eb
parent61aa7ebf79b2e7102be033f74bb1fafbfcdb3080 (diff)
parenta40b38b048cf064927c21bc967b49600c891a483 (diff)
downloadsylt-c61fb2a37fee54b7eb42da074e8c1b42aa6a42f1.tar.gz
Merge pull request #98 from FredTheDino/boolean-ops
boolean ops
-rw-r--r--progs/tests/boolean_ops.sy56
-rw-r--r--progs/tests/boolean_order.sy42
-rw-r--r--src/compiler.rs37
-rw-r--r--src/vm.rs2
4 files changed, 133 insertions, 4 deletions
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
+}
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();
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!();
}
}