diff options
| author | Gustav Sörnäs <gustav@sornas.net> | 2021-01-15 16:01:22 +0100 |
|---|---|---|
| committer | Gustav Sörnäs <gustav@sornas.net> | 2021-01-15 16:58:08 +0100 |
| commit | 0fd774deba11e3cd5a70840d1ea8efb0bf8ff17b (patch) | |
| tree | 40ae38aa039b4e2b01692a968271ac903b55859e | |
| parent | bbd4123387a35d8920acaf77f3a2d420f9d76860 (diff) | |
| download | sylt-0fd774deba11e3cd5a70840d1ea8efb0bf8ff17b.tar.gz | |
typecheck: infere type from rhs in assignments
| -rw-r--r-- | src/compiler.rs | 3 | ||||
| -rw-r--r-- | src/typer.rs | 24 | ||||
| -rw-r--r-- | src/vm.rs | 4 |
3 files changed, 28 insertions, 3 deletions
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) + ); + } + _ => {} } } @@ -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] { |
