From 0fd774deba11e3cd5a70840d1ea8efb0bf8ff17b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Fri, 15 Jan 2021 16:01:22 +0100 Subject: typecheck: infere type from rhs in assignments --- src/compiler.rs | 3 ++- src/typer.rs | 24 ++++++++++++++++++++++-- src/vm.rs | 4 ++++ 3 files changed, 28 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/compiler.rs b/src/compiler.rs index 3a4181b..df816c9 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -504,8 +504,9 @@ impl Compiler { } fn definition_statement(&mut self, name: &str, typ: Type, block: &mut Block) { - let slot = self.define_variable(name, typ, block); + let slot = self.define_variable(name, typ.clone(), block); self.expression(block); + block.add(Op::Define(typ), self.line()); if let Ok(slot) = slot { self.stack_mut()[slot].active = true; diff --git a/src/typer.rs b/src/typer.rs index 4e023e4..d6692d8 100644 --- a/src/typer.rs +++ b/src/typer.rs @@ -259,8 +259,28 @@ impl VM { } } (lhs, rhs) if lhs == rhs => {}, - (lhs, rhs) => error!(self, ErrorKind::TypeError(op.clone(), - vec![lhs.clone(), rhs.clone()])), + (lhs, rhs) => error!(self, + ErrorKind::TypeError( + op.clone(), + vec![lhs.clone(), rhs.clone()] + )), + } + } + + Op::Define(ref ty) => { + let top_type = self.stack.last().unwrap(); + match (ty, top_type) { + (Type::UnkownType, top_type) + if top_type != &Type::UnkownType => {} + (a, b) if a != b => { + error!(self, + ErrorKind::TypeError( + op.clone(), + vec![a.clone(), b.clone()]), + format!("Tried to assign a type {:?} to type {:?}.", a, b) + ); + } + _ => {} } } diff --git a/src/vm.rs b/src/vm.rs index 3750690..0b9195d 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -69,6 +69,8 @@ pub enum Op { ReadLocal(usize), Assign(usize), + Define(Type), + Call(usize), Print, @@ -401,6 +403,8 @@ impl VM { self.stack[slot] = self.stack.pop().unwrap(); } + Op::Define(_) => {} + Op::Call(num_args) => { let new_base = self.stack.len() - 1 - num_args; match &self.stack[new_base] { -- cgit v1.2.1