From 53a6eeba234e4e4cf771df2ea64cc99ff5c89558 Mon Sep 17 00:00:00 2001 From: Per Lindgren <per.lindgren@ltu.se> Date: Thu, 24 Sep 2020 15:48:52 +0200 Subject: [PATCH] borrow check, (scopes) wip1 --- .vscode/settings.json | 1 + src/check.rs | 4 ++-- src/env.rs | 27 ++++++++++++++------------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 802fdcf..6a7f202 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,6 +5,7 @@ "deque", "ifmt", "lalrpop", + "lexpr", "stmts", "typedecls", "vec", diff --git a/src/check.rs b/src/check.rs index 6dc0f9e..9a0fac4 100644 --- a/src/check.rs +++ b/src/check.rs @@ -59,7 +59,7 @@ fn expr_type( use Op::*; match op { - // Arithmetic and Boolen + // Arithmetic and Boolean Add | Mul | Div | Sub | And | Or => { // check if op and args are compliant let opt = op.get_type(); @@ -151,7 +151,7 @@ fn expr_type( } Id(id) => match var_env.get(id.to_string()) { - Some(t) => Ok(t.clone()), + Some((_, t)) => Ok(t.clone()), None => Err(format!("variable not found {}", id)), }, diff --git a/src/env.rs b/src/env.rs index f7a0d92..03f3ddc 100644 --- a/src/env.rs +++ b/src/env.rs @@ -22,12 +22,8 @@ pub fn new_fn_env(v: &Vec<FnDecl>) -> FnEnv { HashMap::from_iter(i) } -// Option<Type> -// -// Some<Type>, variable has a declared type -// None, variable has been introduced, but type not yet determined - pub type IdType = HashMap<Id, Type>; +type Scope = i32; #[derive(Debug)] pub struct VarEnv(VecDeque<IdType>); @@ -37,8 +33,11 @@ impl VarEnv { VarEnv(VecDeque::new()) } - pub fn get(&self, id: String) -> Option<&Type> { - self.0.iter().find_map(|hm| hm.get(id.as_str())) + pub fn get(&self, id: String) -> Option<(Scope, &Type)> { + self.0.iter().enumerate().find_map(|(scope, hm)| { + hm.get(id.as_str()) + .map(|t| ((self.0.len() - scope) as Scope, t)) + }) } pub fn get_mut(&mut self, id: String) -> Option<&mut Type> { @@ -94,7 +93,7 @@ fn type_env_test() { println!("update a {:?}", var_env.update("a".to_owned(), I32)); println!("get a {:?}", var_env.get("a".to_owned())); - assert_eq!(var_env.get("a".to_owned()), Some(&I32)); + assert_eq!(var_env.get("a".to_owned()), Some((1, &I32))); println!("update a {:?}", var_env.update("a".to_owned(), I32)); assert!(var_env.update("a".to_owned(), I32).is_ok()); @@ -108,7 +107,9 @@ fn type_env_test() { assert!(var_env.update("b".to_owned(), Bool).is_err()); var_env.push_empty_scope(); - println!("push empty scope"); + println!("\n -- push empty scope\n"); + assert_eq!(var_env.get("a".to_owned()), Some((1, &I32))); + println!("update a {:?}", var_env.update("a".to_owned(), Bool)); assert!(var_env.update("a".to_owned(), Bool).is_err()); println!("update a {:?}", var_env.update("a".to_owned(), I32)); @@ -116,20 +117,20 @@ fn type_env_test() { var_env.new_id("a".to_owned(), Unknown); println!("get a {:?}", var_env.get("a".to_owned())); - assert_eq!(var_env.get("a".to_owned()), Some(&Unknown)); + assert_eq!(var_env.get("a".to_owned()), Some((2, &Unknown))); println!("update a {:?}", var_env.update("a".to_owned(), Bool)); println!("get a {:?}", var_env.get("a".to_owned())); - assert_eq!(var_env.get("a".to_owned()), Some(&Bool)); + assert_eq!(var_env.get("a".to_owned()), Some((2, &Bool))); println!("update a {:?}", var_env.update("a".to_owned(), Bool)); assert!(var_env.update("a".to_owned(), Bool).is_ok()); println!("update a {:?}", var_env.update("a".to_owned(), Type::I32)); assert!(var_env.update("a".to_owned(), I32).is_err()); - println!("pop_scope"); + println!("\n -- pop scope\n"); var_env.pop_scope(); println!("get a {:?}", var_env.get("a".to_owned())); - assert_eq!(var_env.get("a".to_owned()), Some(&I32)); + assert_eq!(var_env.get("a".to_owned()), Some((1, &I32))); println!("update a {:?}", var_env.update("a".to_owned(), Bool)); assert!(var_env.update("a".to_owned(), Bool).is_err()); -- GitLab