diff --git a/.vscode/settings.json b/.vscode/settings.json index 802fdcfe3e046806224f3a6cc297c0be02fbd479..6a7f2025f90b24bbc34ff285a2fdd4436b95c3a4 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 6dc0f9eaa8e56bd2db98afaddf639bf2242c3072..9a0fac4274d84e961058562b5c1673e79faf52e2 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 f7a0d9297711bc2eee8b095c534a41a197600f14..03f3ddc9c6a744bb3ee3460e85958134acd45bda 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());