diff --git a/examples/w1_2.rs b/examples/w1_2.rs index fcf5cd9b46e5caa9bef00d11d71cb40be9a40ba6..83df078f15614ee705964a5a906c5eaded20f218 100644 --- a/examples/w1_2.rs +++ b/examples/w1_2.rs @@ -16,12 +16,11 @@ fn c(x: i32, y: i32) -> i32 { -a - (-b) * y // here we have prefix operator "-" } - // More advanced statements // a function taking two bool arguments returning the bool type // with some let statements and function calls -fn a(x: bool, y: bool) -> bool { +fn a1(x: bool, y: bool) -> bool { if x && y { let a: bool = true; y || a @@ -32,8 +31,8 @@ fn a(x: bool, y: bool) -> bool { // a function taking two bool arguments returning the i32 type // with some let statements and function calls -fn b(x: bool, y: bool) -> i32 { - let a: bool = a(x, y || false); +fn b1(x: bool, y: bool) -> i32 { + let a: bool = a1(x, y || false); let mut b: i32 = 0; if a && y { let a: bool = true; // shadowing @@ -50,7 +49,7 @@ fn b(x: bool, y: bool) -> i32 { // a function taking two bool arguments returning the i32 type // while -fn c(x: bool, y: bool) -> i32 { +fn c1(x: bool, y: bool) -> i32 { let mut b: i32 = 0; let mut c: i32 = 1; while (b < 10) { diff --git a/src/check.rs b/src/check.rs index 46c2d2a53031e18148408a3bdef1c4a6eb9c6486..9bda67bcb1d3e2d533caa7953d73887c318ca018 100644 --- a/src/check.rs +++ b/src/check.rs @@ -45,6 +45,8 @@ fn expr_type( ) -> Result<Type, Error> { use Expr::*; trace!("expr_type {}", e); + trace!("var_env {:?}", var_env); + match e { Num(_) => Ok(Type::I32), Bool(_) => Ok(Type::Bool), @@ -57,15 +59,16 @@ fn expr_type( use Op::*; match op { - // Arithmetic and Boolean + // Arithmetic and Boolen Add | Mul | Div | Sub | And | Or => { - // check if op and args are of i32 - if lt == Type::I32 && rt == Type::I32 { - Ok(Type::I32) + // check if op and args are compliant + let opt = op.get_type(); + if lt == opt && rt == opt { + Ok(opt) } else { Err(format!( - "Num operation requires i32, left {} right {}", - lt, rt + "Expected type {}, found, left {}: {}, {:?} right {}: {}, {:?}", + opt, l, lt, lt, r, rt, rt )) } } @@ -373,7 +376,7 @@ pub fn check(p: &Program) -> Result<(), Error> { trace!("Input program \n{}", &p); for fd in p.fn_decls.iter() { - trace!("function id {}", fd.id); + trace!("check function\n{}", fd); let mut var_env = VarEnv::new(); // build a scope for the arguments @@ -390,9 +393,9 @@ pub fn check(p: &Program) -> Result<(), Error> { 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!("result {}: {:?}", fd.id, &stmt_type); - let stmt_type = stmt_type?; + let stmt_type = strip_mut(stmt_type?); if stmt_type != fd.result { Err(format!( diff --git a/src/grammar.lalrpop b/src/grammar.lalrpop index eaa7f05cf4e83f96426974bccaac937f55ae7b40..239904f84072360ccac9c4d528e1e4c75f93bf86 100644 --- a/src/grammar.lalrpop +++ b/src/grammar.lalrpop @@ -150,9 +150,10 @@ Stmt : Stmt = { Type : Type = { - Id => Type::Named(<>), + "bool" => Type::Bool, "()" => Type::Unit, "i32" => Type::I32, // this should likely be a paratrized Num type later + Id => Type::Named(<>), "&" <Type> => Type::Ref(Box::new(<>)), "&" "mut" <Type> => Type::Ref(Box::new(Type::Mut(Box::new(<>)))), }