aboutsummaryrefslogtreecommitdiffstats
path: root/src/vm.rs
diff options
context:
space:
mode:
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() {