From 2570830850c6dadadc2c86bf9d6f3203c9aba488 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Fri, 5 Mar 2021 19:07:13 +0100 Subject: convert tests to files --- src/vm.rs | 26 -------------------------- 1 file changed, 26 deletions(-) (limited to 'src/vm.rs') diff --git a/src/vm.rs b/src/vm.rs index f5e5c58..d056ded 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -824,29 +824,3 @@ impl VM { } } } - -#[cfg(test)] -mod tests { - mod typing { - use crate::error::ErrorKind; - use crate::{test_string, Type}; - - test_string!(uncallable_type, " - f := fn i: int { - i() - } - f", - [ErrorKind::InvalidProgram]); - - test_string!(invalid_assign, "a := 1\na = 0.1\na", - [ErrorKind::TypeMismatch(Type::Int, Type::Float)]); - - test_string!(wrong_params, " - f : fn -> int = fn a: int -> int {}\nf", - [ErrorKind::TypeMismatch(_, _), ErrorKind::TypeMismatch(Type::Void, Type::Int)]); - - test_string!(wrong_ret, " - f : fn -> int = fn {}\nf", - [ErrorKind::TypeMismatch(_, _)]); - } -} -- cgit v1.2.1 From ba7ebb200cc5560ba0a2237df4a4985fe927b08c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Fri, 5 Mar 2021 21:08:27 +0100 Subject: almost working capturing variables --- src/vm.rs | 77 ++++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 51 insertions(+), 26 deletions(-) (limited to 'src/vm.rs') diff --git a/src/vm.rs b/src/vm.rs index d056ded..2237896 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -6,7 +6,7 @@ use std::rc::Rc; use owo_colors::OwoColorize; -use crate::{Block, Op, Prog, UpValue, Value, op}; +use crate::{Block, BlockLinkState, Op, Prog, UpValue, Value, op}; use crate::error::{Error, ErrorKind}; use crate::RustFunction; use crate::Type; @@ -553,36 +553,37 @@ impl VM { match self.constant(value).clone() { Value::Function(_, block) => { self.push(Value::Function(Vec::new(), block.clone())); + if !matches!(block.borrow().linking, BlockLinkState::Linked) { + if block.borrow().needs_linking() { + error!(self, + ErrorKind::InvalidProgram, + format!("Calling function '{}' before all captured variables are declared.", + block.borrow().name)); + } - if block.borrow().needs_linking() { - error!(self, - ErrorKind::InvalidProgram, - format!("Calling function '{}' before all captured variables are declared.", - block.borrow().name)); - } - - let mut types = Vec::new(); - for (slot, is_up, ty) in block.borrow().upvalues.iter() { - if *is_up { - types.push(ty.clone()); - } else { - types.push(Type::from(&self.stack[*slot])); + let mut types = Vec::new(); + for (slot, is_up, ty) in block.borrow().upvalues.iter() { + if *is_up { + types.push(ty.clone()); + } else { + types.push(Type::from(&self.stack[*slot])); + } } - } - let mut block_mut = block.borrow_mut(); - for (i, (_, is_up, ty)) in block_mut.upvalues.iter_mut().enumerate() { - if *is_up { continue; } + let mut block_mut = block.borrow_mut(); + for (i, (_, is_up, ty)) in block_mut.upvalues.iter_mut().enumerate() { + if *is_up { continue; } - let suggestion = &types[i]; - if matches!(ty, Type::Unknown) { - *ty = suggestion.clone(); - } else { - if ty != suggestion { - error!(self, ErrorKind::CannotInfer(ty.clone(), suggestion.clone())); + let suggestion = &types[i]; + if matches!(ty, Type::Unknown) { + *ty = suggestion.clone(); + } else { + if ty != suggestion { + error!(self, ErrorKind::CannotInfer(ty.clone(), suggestion.clone())); + } } - } - }; + }; + } }, value => { self.push(value.clone()); @@ -652,6 +653,7 @@ impl VM { let inner = self.frame().block.borrow(); let ret = inner.ret(); if Type::from(&a) != *ret { + error!(self, ErrorKind::TypeMismatch(a.into(), ret.clone()), "Value does not match return type."); } @@ -679,6 +681,29 @@ impl VM { match self.constant(slot).clone() { Value::Function(_, block) => { block.borrow_mut().link(); + + let mut types = Vec::new(); + for (slot, is_up, ty) in block.borrow().upvalues.iter() { + if *is_up { + types.push(ty.clone()); + } else { + types.push(Type::from(&self.stack[*slot])); + } + } + + let mut block_mut = block.borrow_mut(); + for (i, (_, is_up, ty)) in block_mut.upvalues.iter_mut().enumerate() { + if *is_up { continue; } + + let suggestion = &types[i]; + if matches!(ty, Type::Unknown) { + *ty = suggestion.clone(); + } else { + if ty != suggestion { + error!(self, ErrorKind::CannotInfer(ty.clone(), suggestion.clone())); + } + } + } } value => { error!(self, -- cgit v1.2.1 From de7ddbe322b615eeeba17730486da4b9d024ebe2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edvard=20Th=C3=B6rnros?= Date: Fri, 5 Mar 2021 21:17:11 +0100 Subject: fix the hard test ;) --- src/vm.rs | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) (limited to 'src/vm.rs') diff --git a/src/vm.rs b/src/vm.rs index 2237896..7cfc8d3 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -236,22 +236,26 @@ impl VM { let offset = self.frame().stack_offset; let constant = self.constant(value).clone(); let value = match constant { - Value::Function(_, block) => { - let mut ups = Vec::new(); - for (slot, is_up, _) in block.borrow().upvalues.iter() { - let up = if *is_up { - if let Value::Function(local_ups, _) = &self.stack[offset] { - Rc::clone(&local_ups[*slot]) + Value::Function(ups, block) => { + if matches!(block.borrow().linking, BlockLinkState::Linked) { + Value::Function(ups.clone(), block) + } else { + let mut ups = Vec::new(); + for (slot, is_up, _) in block.borrow().upvalues.iter() { + let up = if *is_up { + if let Value::Function(local_ups, _) = &self.stack[offset] { + Rc::clone(&local_ups[*slot]) + } else { + unreachable!() + } } else { - unreachable!() - } - } else { - let slot = self.frame().stack_offset + slot; - Rc::clone(self.find_upvalue(slot)) - }; - ups.push(up); + let slot = self.frame().stack_offset + slot; + Rc::clone(self.find_upvalue(slot)) + }; + ups.push(up); + } + Value::Function(ups, block) } - Value::Function(ups, block) }, value => value, }; -- cgit v1.2.1