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

simple ref/deref works

parent b47e562a
No related branches found
No related tags found
No related merge requests found
fn main() -> i32 {
fn main() {
let mut a = 7;
let b = &mut a;
*b = 9;
a
let c = a;
}
fn main() -> i32 {
fn main() {
let mut a = 7;
let b = &a;
let c = &b;
**c = 9;
a
let mut b = &a;
let c = &mut b;
*(*c) = 9;
let d = a;
}
fn main() {
let mut a = 1;
let b = &a;
let mut c: &mut &i32 = &mut b;
}
......@@ -183,149 +183,6 @@ fn strip_mut(t: Type) -> Type {
}
}
// // walk the left hand expression in an assignment.
// // Ok(Type), the type of the left hand
// // Err(), illegal left hand
// fn left_expr_type(e: &Expr, to_type: Type, var_env: &mut VarEnv) -> Result<(), Error> {
// match e {
// Expr::Id(id) => {
// match var_env.get(id.clone()) {
// Some((true, Some(t))) => {
// match *t == to_type {
// true => Ok(()), // mutable, defined of same type
// false => Err("types differ".to_string()),
// }
// }
// Some((true, None)) => unimplemented!(),
// Some((false, _)) => Err("variable declared immutable".to_string()),
// None => Err("variable not in scope".to_string()),
// }
// }
// Expr::DeRef(ref_mut_e) => {
// let e: &Expr = &*ref_mut_e;
// trace!("DeRef({})", e);
// match e {
// Expr::RefMut(e) => left_expr_type(&*e, to_type, var_env),
// _ => Err("cannot deref left hand expression".to_string()),
// }
// // }
// // let ref_mut_id = left_expr_type(ref_mut_e, var_env)?;
// // trace!("left: RefMut({})", ref_mut_id);
// // match var_env.get(ref_mut_id) {
// // Some(Val::Ref(id)) => {
// // println!("Ref id {}", id);
// // id.clone()
// // }
// // Some(Val::RefMut(id)) => {
// // println!("RefMut id {}", id);
// // id.clone()
// // }
// // _ => panic!("deref failed"),
// // }
// // Ok(ref_mut_id)
// }
// // let ev = eval_left_expr(e, m, fn_env);
// // println!("eval_left {:?}", ev);
// // match m.get(ev) {
// // Some(Val::Ref(id)) => {
// // println!("Ref id {}", id);
// // id.clone()
// // }
// // Some(Val::RefMut(id)) => {
// // println!("RefMut id {}", id);
// // id.clone()
// // }
// // _ => panic!("deref failed"),
// // }
// _ => Err(format!("illegal left hand expression {}", e)),
// }
// }
// walk the left hand expression in an assignment.
// Ok(Type), the type of the left hand
// Err(), illegal left hand
fn left_expr_type(e: &Expr, var_env: &mut VarEnv) -> Result<Id, Error> {
match e {
Expr::Id(id) => Ok(id.to_owned()),
// match var_env.get(id.clone()) {
// Some((true, Some(t))) => {
// match *t == to_type {
// true => Ok(()), // mutable, defined of same type
// false => Err("types differ".to_string()),
// }
// }
// Some((true, None)) => unimplemented!(),
// Some((false, _)) => Err("variable declared immutable".to_string()),
// None => Err("variable not in scope".to_string()),
// }
// }
Expr::DeRef(ref_mut_e) => {
trace!("DeRef({})", ref_mut_e);
let lh = left_expr_type(ref_mut_e, var_env)?;
trace!("DeRef({})", lh);
match var_env.get(lh) {
Some(t) => {
trace!("t {:?}", t);
panic!();
}
// match *t == to_type {
// true => Ok(()), // mutable, defined of same type
// false => Err("types differ".to_string()),
// }
// }
// Some((true, None)) => unimplemented!(),
// Some((false, _)) => Err("variable declared immutable".to_string()),
None => Err("variable not in scope".to_string()),
}
}
// match e {
// Expr::RefMut(e) => left_expr_type(&*e, to_type, var_env),
// _ => Err("cannot deref left hand expression".to_string()),
// }
// }
// println!("eval_left deref e {:?}", e);
// let ev = eval_left_expr(e, m, fn_env);
// println!("eval_left {:?}", ev);
// match m.get(ev) {
// Some(Val::Ref(id)) => {
// println!("Ref id {}", id);
// id.clone()
// }
// Some(Val::RefMut(id)) => {
// println!("RefMut id {}", id);
// id.clone()
// }
// _ => panic!("deref failed"),
// }
// Ok(ref_mut_id)
// }
// let ev = eval_left_expr(e, m, fn_env);
// println!("eval_left {:?}", ev);
// match m.get(ev) {
// Some(Val::Ref(id)) => {
// println!("Ref id {}", id);
// id.clone()
// }
// Some(Val::RefMut(id)) => {
// println!("RefMut id {}", id);
// id.clone()
// }
// _ => panic!("deref failed"),
// }
_ => Err(format!("illegal left hand expression {}", e)),
}
}
pub fn check_stmts(
stmts: &Stmts,
fn_env: &FnEnv,
......@@ -369,13 +226,22 @@ pub fn check_stmts(
}
Assign(lh, e) => {
let expr_type = expr_type(&*e, fn_env, type_env, var_env)?;
trace!("expr_type = {}", expr_type);
trace!("v = {:?}", lh);
let e_type = expr_type(&*e, fn_env, type_env, var_env)?;
trace!("e_type = {}", e_type);
trace!("lh = {:?}", lh);
let lh_type = expr_type(lh, fn_env, type_env, var_env)?;
trace!("lh_type {}", &lh_type);
if match &lh_type {
Type::Mut(t) => **t == e_type,
let id = left_expr_type(&*lh, var_env)?;
// var_env.update(id, expr_type)?;
_ => Err(format!("assignment to immutable"))?,
} {
Ok(Type::Unit)
} else {
Err(format!("cannot assign {} = {}", &lh_type, e_type))
}
}
While(e, block) => match expr_type(&*e, fn_env, type_env, var_env) {
......
......@@ -144,3 +144,8 @@ fn check_ref_err2() {
fn check_ref_err3() {
assert!(check(&read_file::parse("examples/ref_err3.rs")).is_err());
}
#[test]
fn check_ref_err4() {
assert!(check(&read_file::parse("examples/ref_err4.rs")).is_err());
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment