aboutsummaryrefslogtreecommitdiffstats
path: root/src/vm.rs
diff options
context:
space:
mode:
authorEdvard Thörnros <edvard.thornros@gmail.com>2021-02-16 21:10:03 +0100
committerEdvard Thörnros <edvard.thornros@gmail.com>2021-02-16 21:10:03 +0100
commite86b1be782c2c2f57e968557d7f91bbcc7b8b27f (patch)
tree22e603ce7b369b51dc1e2ceaeb63e64c51ea4bfd /src/vm.rs
parentecc84fc8259ab0f2f5754718ed70e3a57048a540 (diff)
downloadsylt-e86b1be782c2c2f57e968557d7f91bbcc7b8b27f.tar.gz
fix the failing testcase
Diffstat (limited to 'src/vm.rs')
-rw-r--r--src/vm.rs41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/vm.rs b/src/vm.rs
index b292a79..f5c1cf0 100644
--- a/src/vm.rs
+++ b/src/vm.rs
@@ -258,6 +258,34 @@ impl VM {
self.push(value);
}
+ Op::Link(slot) => {
+ let offset = self.frame().stack_offset;
+ let constant = self.constant(slot).clone();
+ let constant = match constant {
+ Value::Function(_, block) => {
+ let mut ups = Vec::new();
+ for (slot, is_up, _) in block.borrow().upvalues.iter() {
+ let up = if *is_up {
+ if let Value::Function(local_ups, _) = &self.stack[offset] {
+ Rc::clone(&local_ups[*slot])
+ } else {
+ unreachable!()
+ }
+ } else {
+ let slot = self.frame().stack_offset + slot;
+ Rc::clone(self.find_upvalue(slot))
+ };
+ ups.push(up);
+ }
+ Value::Function(ups, block)
+ },
+ value => error!(self,
+ ErrorKind::RuntimeTypeError(op, vec![value.clone()]),
+ format!("Not a function {:?}.", value)),
+ };
+ self.constants[slot] = constant;
+ }
+
Op::Index => {
let slot = self.stack.pop().unwrap();
let val = self.stack.pop().unwrap();
@@ -638,6 +666,19 @@ impl VM {
}
}
+ Op::Link(slot) => {
+ println!("{:?}", self.constants);
+ println!("{:?} - {}", self.constant(slot), slot);
+ match self.constant(slot).clone() {
+ Value::Function(_, _) => {}
+ value => {
+ error!(self,
+ ErrorKind::TypeError(op, vec![Type::from(&value)]),
+ format!("Cannot link non-function {:?}.", value));
+ }
+ };
+ }
+
Op::Call(num_args) => {
let new_base = self.stack.len() - 1 - num_args;
match self.stack[new_base].clone() {