diff options
| author | Edvard Thörnros <edvard.thornros@gmail.com> | 2021-01-21 20:56:38 +0100 |
|---|---|---|
| committer | Edvard Thörnros <edvard.thornros@gmail.com> | 2021-01-21 20:56:38 +0100 |
| commit | 4448657f8443842e3ef75353c5fa87dfebb3cffd (patch) | |
| tree | 4d09b1fa7db276b9bac76396bdbaf2cd720a34d9 /src/vm.rs | |
| parent | 18e7483580c000ee512f4a1f266b39c8f206ba65 (diff) | |
| download | sylt-4448657f8443842e3ef75353c5fa87dfebb3cffd.tar.gz | |
Add type inference for upvalues
Diffstat (limited to 'src/vm.rs')
| -rw-r--r-- | src/vm.rs | 37 |
1 files changed, 35 insertions, 2 deletions
@@ -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 => { |
