aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGustav Sörnäs <gustav@sornas.net>2021-01-15 16:01:22 +0100
committerGustav Sörnäs <gustav@sornas.net>2021-01-15 16:58:08 +0100
commit0fd774deba11e3cd5a70840d1ea8efb0bf8ff17b (patch)
tree40ae38aa039b4e2b01692a968271ac903b55859e
parentbbd4123387a35d8920acaf77f3a2d420f9d76860 (diff)
downloadsylt-0fd774deba11e3cd5a70840d1ea8efb0bf8ff17b.tar.gz
typecheck: infere type from rhs in assignments
-rw-r--r--src/compiler.rs3
-rw-r--r--src/typer.rs24
-rw-r--r--src/vm.rs4
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)
+ );
+ }
+ _ => {}
}
}
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] {