aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs24
-rw-r--r--src/vm.rs10
2 files changed, 34 insertions, 0 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 794bbea..e83d11f 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -232,6 +232,30 @@ mod tests {
factorial(5) <=> 120
factorial(6) <=> 720
factorial(12) <=> 479001600",
+
+ returning_closures: "
+f : fn -> fn -> int = fn -> fn -> int {
+ x : int = 0
+ f := fn -> int {
+ x = x + 1
+ ret x
+ }
+ f() <=> 1
+ ret f
+}
+
+a := f()
+b := f()
+
+a() <=> 2
+a() <=> 3
+
+b() <=> 2
+b() <=> 3
+
+a() <=> 4
+"
+
//TODO this tests doesn't terminate in proper time if we print blocks and ops
/*
fibonacci: "fibonacci : fn int -> int = fn n: int -> int {
diff --git a/src/vm.rs b/src/vm.rs
index 3a3e752..177c547 100644
--- a/src/vm.rs
+++ b/src/vm.rs
@@ -590,6 +590,12 @@ impl VM {
return Ok(OpResult::Done);
} else {
self.stack[last.stack_offset] = self.stack.pop().unwrap();
+ for slot in last.stack_offset+1..self.stack.len() {
+ if self.upvalues.contains_key(&slot) {
+ let value = self.stack[slot].clone();
+ self.drop_upvalue(slot, value);
+ }
+ }
self.stack.truncate(last.stack_offset + 1);
}
}
@@ -653,6 +659,10 @@ impl VM {
self.stack.push(value.clone());
}
+ Op::PopUpvalue => {
+ self.stack.pop().unwrap();
+ }
+
Op::ReadUpvalue(slot) => {
let value = self.frame().block.borrow().ups[slot].2.as_value();
self.stack.push(value);