diff --git a/examples/call.rs b/examples/call.rs index 40e42fcf3e76ba7fb97995bfd8c54bceeba764a7..3609097f9a5e48db84fbaa3587b1956344227915 100644 --- a/examples/call.rs +++ b/examples/call.rs @@ -2,6 +2,6 @@ fn f(x: i32, y: i32) -> i32 { 3 + 5 + x + y } -fn main() -> i32 { - f(1, 2) +fn main() { + f(1, 2); } diff --git a/examples/ref2.rs b/examples/ref2.rs index 36b9fdebe6dc03f64d59a62ae13c9b496cde99c7..4c59dfe4154bce2fccd9b665d45e165ac4d3f28d 100644 --- a/examples/ref2.rs +++ b/examples/ref2.rs @@ -1,5 +1,5 @@ fn main() { let mut a = 1; let b = &mut a; - let c = b; + let c: &mut i32 = b; } diff --git a/src/ast.rs b/src/ast.rs index 3afa200a0a07a09ccd4b9b93244397235c6611d2..709bf3a8cfbc88cfa8528aabf0ecc7fa7930c9c4 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -47,7 +47,6 @@ pub struct Param { pub id: Id, pub ty: Type, } -// pub bool, pub Id, pub Type); #[derive(Debug, PartialEq)] pub enum TypeDecl { @@ -233,10 +232,12 @@ impl Stmt { match self { // Id mut? (: Type)? (= Expr)? Stmt::Let(id, m, ot, oe) => { - write!(fmt, "let {}", id)?; + write!(fmt, "let ")?; if *m { - write!(fmt, " mut")?; + write!(fmt, "mut ")?; } + write!(fmt, "{}", id)?; + if let Some(t) = ot { write!(fmt, ": {}", t)?; } diff --git a/src/check.rs b/src/check.rs index 8ebb84272329fcca7b0d115c2a94dae3c1b29866..42d2522d63039123c71891d0723cf5a2a94fe44f 100644 --- a/src/check.rs +++ b/src/check.rs @@ -112,20 +112,20 @@ fn expr_type( Call(s, args) => { trace!("call {} with {}", s, args); - let argt: Vec<Type> = args + let arg_t: Vec<Type> = args .clone() .0 .into_iter() .map(|e| expr_type(&*e, fn_env, type_env, var_env)) .collect::<Result<_, _>>()?; - trace!("arg types {:?}", argt); + trace!("arg types {:?}", arg_t); let f = match fn_env.get(s.as_str()) { Some(f) => f, None => Err(format!("{} not found", s))?, }; - let part: Vec<Type> = (f.params.0.clone()) + let par_t: Vec<Type> = (f.params.0.clone()) .into_iter() .map(|p| From::from(&p)) .collect(); @@ -134,15 +134,15 @@ fn expr_type( "fn to call {} with params {} and types {:?}", f, f.params, - part + par_t ); - if argt == part { + if arg_t == par_t { Ok(f.result.clone()) } else { Err(format!( "arguments types {:?} does not match parameter types {:?}", - argt, part + arg_t, par_t )) } } @@ -362,18 +362,27 @@ pub fn check(p: &Program) -> Result<(), Error> { // build a scope for the arguments let mut arg_ty = IdType::new(); + for Param { is_mut, id, ty } in fd.params.0.iter() { - // TODO move is_mut to Type in parser - arg_ty.insert(id.to_owned(), ty.clone()); + let ty = match *is_mut { + true => Type::Mut(Box::new(ty.clone())), + _ => ty.clone(), + }; + arg_ty.insert(id.to_owned(), ty); } var_env.push_param_scope(arg_ty); let stmt_type = check_stmts(&fd.body, &fn_env, &type_env, &mut var_env); - trace!("function id {}: {:?}", fd.id, stmt_type); + trace!("function id {}: {:?}", fd.id, &stmt_type); + + let stmt_type = stmt_type?; - if stmt_type? != fd.result { - Err(format!("return value does not match statements"))?; + if stmt_type != fd.result { + Err(format!( + "return type {} does not match statements type {}", + fd.result, stmt_type + ))?; } } Ok(())