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 @@
"deque",
"ifmt",
"lalrpop",
"lexpr",
"stmts",
"typedecls",
"vec",
......
......@@ -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)),
},
......
......@@ -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());
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment