Skip to content
Snippets Groups Projects
Commit 53a6eeba authored by Per Lindgren's avatar Per Lindgren
Browse files

borrow check, (scopes) wip1

parent 2db9d21c
No related branches found
No related tags found
No related merge requests found
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
"deque", "deque",
"ifmt", "ifmt",
"lalrpop", "lalrpop",
"lexpr",
"stmts", "stmts",
"typedecls", "typedecls",
"vec", "vec",
......
...@@ -59,7 +59,7 @@ fn expr_type( ...@@ -59,7 +59,7 @@ fn expr_type(
use Op::*; use Op::*;
match op { match op {
// Arithmetic and Boolen // Arithmetic and Boolean
Add | Mul | Div | Sub | And | Or => { Add | Mul | Div | Sub | And | Or => {
// check if op and args are compliant // check if op and args are compliant
let opt = op.get_type(); let opt = op.get_type();
...@@ -151,7 +151,7 @@ fn expr_type( ...@@ -151,7 +151,7 @@ fn expr_type(
} }
Id(id) => match var_env.get(id.to_string()) { 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)), None => Err(format!("variable not found {}", id)),
}, },
......
...@@ -22,12 +22,8 @@ pub fn new_fn_env(v: &Vec<FnDecl>) -> FnEnv { ...@@ -22,12 +22,8 @@ pub fn new_fn_env(v: &Vec<FnDecl>) -> FnEnv {
HashMap::from_iter(i) 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>; pub type IdType = HashMap<Id, Type>;
type Scope = i32;
#[derive(Debug)] #[derive(Debug)]
pub struct VarEnv(VecDeque<IdType>); pub struct VarEnv(VecDeque<IdType>);
...@@ -37,8 +33,11 @@ impl VarEnv { ...@@ -37,8 +33,11 @@ impl VarEnv {
VarEnv(VecDeque::new()) VarEnv(VecDeque::new())
} }
pub fn get(&self, id: String) -> Option<&Type> { pub fn get(&self, id: String) -> Option<(Scope, &Type)> {
self.0.iter().find_map(|hm| hm.get(id.as_str())) 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> { pub fn get_mut(&mut self, id: String) -> Option<&mut Type> {
...@@ -94,7 +93,7 @@ fn type_env_test() { ...@@ -94,7 +93,7 @@ fn type_env_test() {
println!("update a {:?}", var_env.update("a".to_owned(), I32)); println!("update a {:?}", var_env.update("a".to_owned(), I32));
println!("get a {:?}", var_env.get("a".to_owned())); 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)); println!("update a {:?}", var_env.update("a".to_owned(), I32));
assert!(var_env.update("a".to_owned(), I32).is_ok()); assert!(var_env.update("a".to_owned(), I32).is_ok());
...@@ -108,7 +107,9 @@ fn type_env_test() { ...@@ -108,7 +107,9 @@ fn type_env_test() {
assert!(var_env.update("b".to_owned(), Bool).is_err()); assert!(var_env.update("b".to_owned(), Bool).is_err());
var_env.push_empty_scope(); 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)); println!("update a {:?}", var_env.update("a".to_owned(), Bool));
assert!(var_env.update("a".to_owned(), Bool).is_err()); assert!(var_env.update("a".to_owned(), Bool).is_err());
println!("update a {:?}", var_env.update("a".to_owned(), I32)); println!("update a {:?}", var_env.update("a".to_owned(), I32));
...@@ -116,20 +117,20 @@ fn type_env_test() { ...@@ -116,20 +117,20 @@ fn type_env_test() {
var_env.new_id("a".to_owned(), Unknown); var_env.new_id("a".to_owned(), Unknown);
println!("get a {:?}", var_env.get("a".to_owned())); 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!("update a {:?}", var_env.update("a".to_owned(), Bool));
println!("get a {:?}", var_env.get("a".to_owned())); 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)); println!("update a {:?}", var_env.update("a".to_owned(), Bool));
assert!(var_env.update("a".to_owned(), Bool).is_ok()); assert!(var_env.update("a".to_owned(), Bool).is_ok());
println!("update a {:?}", var_env.update("a".to_owned(), Type::I32)); println!("update a {:?}", var_env.update("a".to_owned(), Type::I32));
assert!(var_env.update("a".to_owned(), I32).is_err()); assert!(var_env.update("a".to_owned(), I32).is_err());
println!("pop_scope"); println!("\n -- pop scope\n");
var_env.pop_scope(); var_env.pop_scope();
println!("get a {:?}", var_env.get("a".to_owned())); 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)); println!("update a {:?}", var_env.update("a".to_owned(), Bool));
assert!(var_env.update("a".to_owned(), Bool).is_err()); assert!(var_env.update("a".to_owned(), Bool).is_err());
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment