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

all tests pass

parent 34054d02
No related branches found
No related tags found
No related merge requests found
fn main() -> i32 {
fn main() {
let mut a = 0;
a = 2;
a
let b = a;
}
fn main() -> i32 {
fn main() {
let mut a = 0;
a = 2;
let mut b = a; // copy semantics
a = 3;
b = b + 1;
a + b
let c = a + b;
}
......@@ -190,6 +190,41 @@ fn expr_type(
}
}
fn lexpr_type<'a>(
e: &Expr,
fn_env: &FnEnv,
type_env: &TypeEnv,
var_env: &'a mut VarEnv,
) -> Result<&'a mut Type, Error> {
use Expr::*;
trace!("expr_type {}", e);
trace!("var_env {:?}", var_env);
match e {
Id(id) => match var_env.get_mut(id.to_string()) {
Some(t) => Ok(t),
None => Err(format!("variable not found {}", id)),
},
DeRef(deref_e) => {
let t = lexpr_type(deref_e, fn_env, type_env, var_env)?;
trace!("deref_t {}", &t);
// strip mut
let t = match t {
Type::Mut(t) => t,
_ => t,
};
trace!("strip deref_t {}", t);
match t {
Type::Ref(dt) => Ok(dt),
_ => Err(format!("cannot deref {} of type {}", e, t)),
}
}
_ => Err(format!("Illegal left hand expression {}", e)),
}
}
fn strip_mut(t: Type) -> Type {
match t {
Type::Mut(t) => *t,
......@@ -228,7 +263,8 @@ pub fn check_stmts(
let t: Type = match (ot, oe) {
(Some(t), Some(e)) => {
let e_type = expr_type(&*e, fn_env, type_env, var_env)?;
match *t == e_type {
let e_type = strip_mut(e_type);
match strip_mut(t.clone()) == e_type {
true => t.clone(),
false => {
trace!("e {}", e);
......@@ -237,9 +273,9 @@ pub fn check_stmts(
}
}
(None, Some(e)) => {
let et = expr_type(&*e, fn_env, type_env, var_env)?;
match is_known(&et) {
true => et,
let e_type = strip_mut(expr_type(&*e, fn_env, type_env, var_env)?);
match is_known(&e_type) {
true => e_type,
_ => Err("reference to unknown type".to_string())?,
}
}
......@@ -256,21 +292,28 @@ pub fn check_stmts(
}
Assign(lh, e) => {
trace!("assign");
let e_type = expr_type(&*e, fn_env, type_env, var_env)?;
trace!("e_type = {}", e_type);
trace!("lh = {:?}", lh);
trace!("e_type = {}", &e_type);
let e_type = strip_mut(e_type);
trace!("e_type stripped = {}", &e_type);
trace!("lh expr = {:?}", lh);
let lh_type = expr_type(lh, fn_env, type_env, var_env)?;
trace!("lh_type {}", &lh_type);
let lh_type = lexpr_type(lh, fn_env, type_env, var_env)?;
trace!("lh_type {}", lh_type);
if match &lh_type {
if match lh_type {
Type::Unknown => {
trace!("assign to unknown");
*lh_type = e_type.clone();
true
}
Type::Mut(t) => match **t {
Type::Unknown => {
trace!("assign to `mut Unknown`");
*t = Box::new(e_type.clone());
true
}
_ => **t == e_type,
......
......@@ -21,6 +21,11 @@ fn check_assign2() {
assert!(check(&read_file::parse("examples/assign2.rs")).is_ok());
}
#[test]
fn check_assign3() {
assert!(check(&read_file::parse("examples/assign3.rs")).is_ok());
}
#[test]
fn check_assign_err() {
assert!(check(&read_file::parse("examples/assign_err.rs")).is_err());
......@@ -154,3 +159,13 @@ fn check_ref_err3() {
fn check_ref_err4() {
assert!(check(&read_file::parse("examples/ref_err4.rs")).is_err());
}
#[test]
fn check_scopes() {
assert!(check(&read_file::parse("examples/scopes.rs")).is_ok());
}
#[test]
fn check_scopes_err() {
assert!(check(&read_file::parse("examples/scopes_err.rs")).is_err());
}
......@@ -35,6 +35,10 @@ fn scopes_test() {
eval_prog("examples/scopes.rs");
}
#[test]
fn scopes_err_test() {
eval_prog("examples/scopes_err.rs");
}
#[test]
fn vm_test() {
eval_prog("examples/vm.rs");
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment