From 7ec991b8d6654aaf27a005804347346e16500a47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edvard=20Th=C3=B6rnros?= Date: Thu, 14 Jan 2021 21:10:07 +0100 Subject: Start of typesystem There's a type system, that kinda works There needs to be better parsing of types, since not all types are currently parsable. Some of them are, and the simple stuff works! :D --- src/vm.rs | 57 +++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 18 deletions(-) (limited to 'src/vm.rs') diff --git a/src/vm.rs b/src/vm.rs index f880b4a..eb4de31 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -4,6 +4,7 @@ use std::rc::Rc; use std::collections::HashMap; use owo_colors::OwoColorize; +use crate::compiler::Type; use crate::error::{Error, ErrorKind}; macro_rules! error { @@ -74,24 +75,36 @@ pub enum Op { #[derive(Debug)] pub struct Block { - name: String, - file: PathBuf, - ops: Vec, - last_line_offset: usize, - line_offsets: HashMap, + pub args: Vec, + pub ret: Type, + + pub name: String, + pub file: PathBuf, + pub ops: Vec, + pub last_line_offset: usize, + pub line_offsets: HashMap, + pub line: usize, } impl Block { - pub fn new(name: &str, file: &Path) -> Self { + pub fn new(name: &str, file: &Path, line: usize) -> Self { Self { + args: Vec::new(), + ret: Type::UnkownType, + name: String::from(name), file: file.to_owned(), ops: Vec::new(), last_line_offset: 0, line_offsets: HashMap::new(), + line, } } + pub fn id(&self) -> (PathBuf, usize) { + (self.file.clone(), self.line) + } + pub fn add_line(&mut self, token_position: usize) { if token_position != self.last_line_offset { self.line_offsets.insert(self.curr(), token_position); @@ -99,7 +112,7 @@ impl Block { } } - fn line(&self, ip: usize) -> usize { + pub fn line(&self, ip: usize) -> usize { for i in (0..=ip).rev() { if let Some(line) = self.line_offsets.get(&i) { return *line; @@ -121,6 +134,10 @@ impl Block { println!(""); } + pub fn last_instruction(&mut self) -> &Op { + self.ops.last().unwrap() + } + pub fn add(&mut self, op: Op, token_position: usize) -> usize { let len = self.curr(); self.add_line(token_position); @@ -211,6 +228,10 @@ impl VM { } pub fn run(&mut self, block: Rc) -> Result<(), Error>{ + if let Err(err) = crate::typer::VM::new().print_ops(true).typecheck(Rc::clone(&block)) { + println!("TYPE ERROR: {}", err); + } + self.frames.push(Frame { stack_offset: 0, block, @@ -261,7 +282,7 @@ impl VM { match self.stack.pop().unwrap() { Value::Float(a) => self.stack.push(Value::Float(-a)), Value::Int(a) => self.stack.push(Value::Int(-a)), - a => error!(self, ErrorKind::TypeError(op.clone(), vec![a])), + a => error!(self, ErrorKind::RuntimeTypeError(op.clone(), vec![a])), } } @@ -272,7 +293,7 @@ impl VM { (Value::String(a), Value::String(b)) => { self.stack.push(Value::String(Rc::from(format!("{}{}", a, b)))) } - (a, b) => error!(self, ErrorKind::TypeError(op.clone(), vec![a, b])), + (a, b) => error!(self, ErrorKind::RuntimeTypeError(op.clone(), vec![a, b])), } } @@ -280,7 +301,7 @@ impl VM { match self.pop_twice() { (Value::Float(a), Value::Float(b)) => self.stack.push(Value::Float(a - b)), (Value::Int(a), Value::Int(b)) => self.stack.push(Value::Int(a - b)), - (a, b) => error!(self, ErrorKind::TypeError(op.clone(), vec![a, b])), + (a, b) => error!(self, ErrorKind::RuntimeTypeError(op.clone(), vec![a, b])), } } @@ -288,7 +309,7 @@ impl VM { match self.pop_twice() { (Value::Float(a), Value::Float(b)) => self.stack.push(Value::Float(a * b)), (Value::Int(a), Value::Int(b)) => self.stack.push(Value::Int(a * b)), - (a, b) => error!(self, ErrorKind::TypeError(op.clone(), vec![a, b])), + (a, b) => error!(self, ErrorKind::RuntimeTypeError(op.clone(), vec![a, b])), } } @@ -296,7 +317,7 @@ impl VM { match self.pop_twice() { (Value::Float(a), Value::Float(b)) => self.stack.push(Value::Float(a / b)), (Value::Int(a), Value::Int(b)) => self.stack.push(Value::Int(a / b)), - (a, b) => error!(self, ErrorKind::TypeError(op.clone(), vec![a, b])), + (a, b) => error!(self, ErrorKind::RuntimeTypeError(op.clone(), vec![a, b])), } } @@ -306,7 +327,7 @@ impl VM { (Value::Int(a), Value::Int(b)) => self.stack.push(Value::Bool(a == b)), (Value::String(a), Value::String(b)) => self.stack.push(Value::Bool(a == b)), (Value::Bool(a), Value::Bool(b)) => self.stack.push(Value::Bool(a == b)), - (a, b) => error!(self, ErrorKind::TypeError(op.clone(), vec![a, b])), + (a, b) => error!(self, ErrorKind::RuntimeTypeError(op.clone(), vec![a, b])), } } @@ -316,7 +337,7 @@ impl VM { (Value::Int(a), Value::Int(b)) => self.stack.push(Value::Bool(a < b)), (Value::String(a), Value::String(b)) => self.stack.push(Value::Bool(a < b)), (Value::Bool(a), Value::Bool(b)) => self.stack.push(Value::Bool(a < b)), - (a, b) => error!(self, ErrorKind::TypeError(op.clone(), vec![a, b])), + (a, b) => error!(self, ErrorKind::RuntimeTypeError(op.clone(), vec![a, b])), } } @@ -326,28 +347,28 @@ impl VM { (Value::Int(a), Value::Int(b)) => self.stack.push(Value::Bool(a > b)), (Value::String(a), Value::String(b)) => self.stack.push(Value::Bool(a > b)), (Value::Bool(a), Value::Bool(b)) => self.stack.push(Value::Bool(a > b)), - (a, b) => error!(self, ErrorKind::TypeError(op.clone(), vec![a, b])), + (a, b) => error!(self, ErrorKind::RuntimeTypeError(op.clone(), vec![a, b])), } } Op::And => { match self.pop_twice() { (Value::Bool(a), Value::Bool(b)) => self.stack.push(Value::Bool(a && b)), - (a, b) => error!(self, ErrorKind::TypeError(op.clone(), vec![a, b])), + (a, b) => error!(self, ErrorKind::RuntimeTypeError(op.clone(), vec![a, b])), } } Op::Or => { match self.pop_twice() { (Value::Bool(a), Value::Bool(b)) => self.stack.push(Value::Bool(a || b)), - (a, b) => error!(self, ErrorKind::TypeError(op.clone(), vec![a, b])), + (a, b) => error!(self, ErrorKind::RuntimeTypeError(op.clone(), vec![a, b])), } } Op::Not => { match self.stack.pop().unwrap() { Value::Bool(a) => self.stack.push(Value::Bool(!a)), - a => error!(self, ErrorKind::TypeError(op.clone(), vec![a])), + a => error!(self, ErrorKind::RuntimeTypeError(op.clone(), vec![a])), } } -- cgit v1.2.1