diff --git a/src/borrow.rs b/src/borrow.rs index 55306c43ee3195dfbed5ea65b20b78906b19f580..ad3963944451b2b771d9656df2db997c4343d1cc 100644 --- a/src/borrow.rs +++ b/src/borrow.rs @@ -13,8 +13,8 @@ enum Val { Bool(bool), Uninitialized, Unit, - Ref(Id), - RefMut(Id), + Ref(Scope, Id), + RefMut(Scope, Id), } #[derive(Debug, Clone)] @@ -25,6 +25,8 @@ pub enum Bc { UniqueRef(Id), // accessed through unique ref, e.g. let c = &mut a, _ = *c; } +type Scope = usize; + type IdVal = HashMap<Id, (bool, Val, Bc)>; #[derive(Debug)] @@ -35,11 +37,14 @@ impl Mem { Mem(VecDeque::new()) } - fn get(&self, id: String) -> Option<&Val> { - self.0.iter().find_map(|hm| match hm.get(id.as_str()) { - Some((_, v, _)) => Some(v), // always ok to go from mut to non mut - _ => None, - }) + fn get(&self, id: String) -> Option<(Scope, &Val)> { + self.0 + .iter() + .enumerate() + .find_map(|(scope, hm)| match hm.get(id.as_str()) { + Some((_, v, _)) => Some((self.0.len() - scope, v)), + _ => None, + }) } fn get_mut(&mut self, id: String) -> Option<&mut Val> { @@ -50,7 +55,7 @@ impl Mem { Some((_, v, _)) => { match v { Val::Uninitialized => Some(v), // an uninitialized - Val::RefMut(_) => { + Val::RefMut(_, _) => { // a ref mut println!("get &mut {:?}", v); Some(v) @@ -160,19 +165,19 @@ fn eval_expr(e: &Expr, m: &mut Mem, fn_env: &FnEnv) -> Val { eval_prefix(op, r) } Expr::Id(id) => match m.get(id.to_owned()) { - Some(v) => v.clone(), + Some(v) => v.1.clone(), None => panic!("identifier not found {:?}", id), }, Expr::Ref(e) => match &**e { Expr::Id(id) => match m.get(id.to_owned()) { - Some(_) => Val::Ref(id.to_owned()), + Some((scope, _)) => Val::Ref(scope, id.to_owned()), None => panic!("identifier not found {:?}", id), }, _ => panic!("ref of non identifier"), }, Expr::RefMut(e) => match &**e { Expr::Id(id) => match m.get(id.to_owned()) { - Some(_) => Val::RefMut(id.to_owned()), + Some((scope, _)) => Val::RefMut(scope, id.to_owned()), None => panic!("identifier not found {:?}", id), }, _ => panic!("ref on non identifier"), @@ -184,8 +189,8 @@ fn eval_expr(e: &Expr, m: &mut Mem, fn_env: &FnEnv) -> Val { println!("ev {:?}", ev); match ev { - Val::Ref(id) => eval_expr(&Expr::Id(id), m, fn_env), - Val::RefMut(id) => eval_expr(&Expr::Id(id), m, fn_env), + Val::Ref(scope, id) => eval_expr(&Expr::Id(id), m, fn_env), + Val::RefMut(scope, id) => eval_expr(&Expr::Id(id), m, fn_env), _ => panic!("cannot deref"), } } @@ -213,12 +218,12 @@ fn eval_left_expr(e: &Expr, m: &Mem, fn_env: &FnEnv) -> Id { println!("eval_left {:?}", ev); match m.get(ev) { - Some(Val::Ref(id)) => { - println!("Ref id {}", id); + Some((_, Val::Ref(s, id))) => { + println!("Ref id {} in scope {}", id, s); id.clone() } - Some(Val::RefMut(id)) => { - println!("RefMut id {}", id); + Some((_, Val::RefMut(s, id))) => { + println!("RefMut id {} in scope {}", id, s); id.clone() } _ => panic!("deref failed"), @@ -358,11 +363,11 @@ fn test_deref() { hm.insert("a".to_string(), (false, Val::Num(7), Bc::Fresh)); hm.insert( "b".to_string(), - (false, Val::Ref("a".to_string()), Bc::Fresh), + (false, Val::Ref(0, "a".to_string()), Bc::Fresh), ); hm.insert( "c".to_string(), - (false, Val::Ref("b".to_string()), Bc::Fresh), + (false, Val::Ref(0, "b".to_string()), Bc::Fresh), ); m.push_param_scope(hm); println!("mem {:?}", m); @@ -382,3 +387,32 @@ fn test_deref() { let v = eval_expr(&e, &mut m, &FnEnv::new()); println!("v {:?}", v); } + +#[test] +fn split() { + let mut v = VecDeque::<i32>::new(); + v.push_front(0); + v.push_front(1); + v.push_front(2); + v.push_front(3); + println!("{:?}", v); + + let mut v1 = v.split_off(2); + println!("{:?}, {:?}", v, v1); + + match v1.get_mut(0) { + Some(p0) => *p0 = 10, + _ => (), + } + + match v.get_mut(0) { + Some(p0) => *p0 = 30, + _ => (), + } + + println!("{:?}, {:?}", v, v1); + + v.append(&mut v1); + + println!("{:?}", v); +}