diff options
| author | Edvard Thörnros <edvard.thornros@gmail.com> | 2021-01-18 20:35:06 +0100 |
|---|---|---|
| committer | Edvard Thörnros <edvard.thornros@gmail.com> | 2021-01-18 20:35:06 +0100 |
| commit | e84d99376ba669c41b38a8750f0b4411ac5d57dc (patch) | |
| tree | 16f0bc0e2e32f1e16df9a7b4fab623a9439fd8b7 /src/vm.rs | |
| parent | c7fa3245f4b73e0699ccfc3d359d864247f62dcc (diff) | |
| download | sylt-e84d99376ba669c41b38a8750f0b4411ac5d57dc.tar.gz | |
Typecheck all blocks
Diffstat (limited to 'src/vm.rs')
| -rw-r--r-- | src/vm.rs | 46 |
1 files changed, 40 insertions, 6 deletions
@@ -498,9 +498,10 @@ impl VM { } pub fn run(&mut self, block: Rc<Block>) -> Result<(), Error>{ - crate::typer::VM::new().print_ops(self.print_ops) - .print_blocks(self.print_blocks) - .typecheck(Type::Void, Rc::clone(&block))?; + self.stack.clear(); + self.frames.clear(); + + self.stack.push(Value::Function(Rc::clone(&block))); self.frames.push(Frame { stack_offset: 0, @@ -605,8 +606,14 @@ impl VM { } fn typecheck_block(&mut self, block: Rc<Block>) -> Vec<Error> { + self.stack.clear(); self.frames.clear(); + self.stack.push(Value::Function(Rc::clone(&block))); + for arg in block.args() { + self.stack.push(arg.as_value()); + } + self.frames.push(Frame { stack_offset: 0, block: block, @@ -620,7 +627,7 @@ impl VM { let mut errors = Vec::new(); loop { let ip = self.frame().ip; - if ip > self.frame().block.ops.len() { + if ip >= self.frame().block.ops.len() { break; } @@ -630,6 +637,7 @@ impl VM { if let Err(e) = self.check_op(self.op().clone()) { errors.push(e); + self.frame_mut().ip += 1; } if !self.stack.is_empty() { @@ -640,13 +648,39 @@ impl VM { errors } - pub fn typecheck(&mut self, blocks: Vec<Rc<Block>>) -> Result<(), Vec<Error>> { + pub fn typecheck(&mut self, blocks: &Vec<Rc<Block>>) -> Result<(), Vec<Error>> { let mut errors = Vec::new(); for block in blocks.iter() { errors.append(&mut self.typecheck_block(Rc::clone(block))); } - return Ok(()); + if errors.is_empty() { + Ok(()) + } else { + Err(errors) + } + } +} + +#[cfg(test)] +mod tests { + mod typing { + use crate::test_string; + use crate::error::ErrorKind; + + test_string!(uncallable_type, " + f := fn i: int { + i() + }", + [ErrorKind::TypeError(_, _)]); + + test_string!(wrong_params, " + f : fn -> int = fn a: int -> int {}", + [ErrorKind::TypeError(_, _)]); + + test_string!(wrong_ret, " + f : fn -> int = fn {}", + [ErrorKind::TypeError(_, _)]); } } |
