aboutsummaryrefslogtreecommitdiffstats
path: root/src/vm.rs
diff options
context:
space:
mode:
authorEdvard Thörnros <edvard.thornros@gmail.com>2021-01-21 20:56:38 +0100
committerEdvard Thörnros <edvard.thornros@gmail.com>2021-01-21 20:56:38 +0100
commit4448657f8443842e3ef75353c5fa87dfebb3cffd (patch)
tree4d09b1fa7db276b9bac76396bdbaf2cd720a34d9 /src/vm.rs
parent18e7483580c000ee512f4a1f266b39c8f206ba65 (diff)
downloadsylt-4448657f8443842e3ef75353c5fa87dfebb3cffd.tar.gz
Add type inference for upvalues
Diffstat (limited to 'src/vm.rs')
-rw-r--r--src/vm.rs37
1 files changed, 35 insertions, 2 deletions
diff --git a/src/vm.rs b/src/vm.rs
index 177c547..c7b6c0f 100644
--- a/src/vm.rs
+++ b/src/vm.rs
@@ -655,8 +655,41 @@ impl VM {
Op::Jmp(_line) => {}
- Op::Constant(value) => {
- self.stack.push(value.clone());
+ Op::Constant(ref value) => {
+ match value.clone() {
+ Value::Function(_, block) => {
+ self.stack.push(Value::Function(Vec::new(), block.clone()));
+
+ let mut types = Vec::new();
+ for (slot, is_up, _) in block.borrow().ups.iter() {
+ if *is_up {
+ types.push(Type::Void);
+ } else {
+ types.push(self.stack[*slot].as_type());
+ }
+ }
+
+ let mut block_mut = block.borrow_mut();
+ for (i, (_, is_up, ty)) in block_mut.ups.iter_mut().enumerate() {
+ if *is_up { continue; }
+
+ let suggestion = &types[i];
+ if ty.is_unkown() {
+ *ty = suggestion.clone();
+ } else {
+ if ty != suggestion {
+ error!(self,
+ ErrorKind::TypeError(op.clone(),
+ vec![ty.clone(), suggestion.clone()]),
+ "Failed to infer type.".to_string());
+ }
+ }
+ };
+ },
+ _ => {
+ self.stack.push(value.clone());
+ }
+ }
}
Op::PopUpvalue => {