diff --git a/examples/wip.rs b/examples/wip.rs index 7756966ec21967c3b91b3fdfc6fda02d9fc62bfb..b744af2b99a493c30311ce08df35df04451229e6 100644 --- a/examples/wip.rs +++ b/examples/wip.rs @@ -1,5 +1,9 @@ fn main() { - {} + {}; + + while true {} + + if a {} let mut a = 5; a = 5; diff --git a/src/ast.rs b/src/ast.rs index a95542c63a363de2928a982b6bb7db3846070f14..a0ca146894a4f379adb8d305d681b782f192eeb0 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -23,7 +23,7 @@ pub struct Path(pub Vec<Id>); #[derive(Debug, PartialEq, Clone)] pub struct Stmts { pub stmts: Vec<Stmt>, - pub ret: bool, + pub trailing_semi: bool, } #[derive(Debug, PartialEq, Clone)] @@ -221,11 +221,11 @@ impl Stmts { if i < len - 1 { match s { - Stmt::Block(_) | Stmt::If(_, _, _) => (), + Stmt::Block(_) | Stmt::If(_, _, _) | Stmt::While(_, _) => (), _ => write!(fmt, ";")?, } } else { - if self.ret { + if self.trailing_semi { write!(fmt, ";")?; } } diff --git a/src/check.rs b/src/check.rs index 5baafbdc6566abadc1b23f16ea3603bcf3c359d3..ddb772f0ac8d96158a2697a1118b47546137b459 100644 --- a/src/check.rs +++ b/src/check.rs @@ -229,6 +229,7 @@ fn lexpr_type<'a>( } } +// strip a "mut T" to a T fn strip_mut(t: Type) -> Type { match t { Type::Mut(t) => *t, @@ -236,6 +237,7 @@ fn strip_mut(t: Type) -> Type { } } +// determine if a type is declared recursively fn is_known(t: &Type) -> bool { use Type::*; match t { @@ -371,8 +373,6 @@ pub fn check_stmts( type_env: &TypeEnv, var_env: &mut VarEnv, ) -> Result<Type, Error> { - use Stmt::*; - var_env.push_empty_scope(); let t = stmts @@ -381,10 +381,10 @@ pub fn check_stmts( .try_fold(Type::Unit, |_, s| check_stmt(s, fn_env, type_env, var_env))?; var_env.pop_scope(); - if !stmts.ret { - Ok(t.clone()) - } else { + if stmts.trailing_semi { Ok(Type::Unit) + } else { + Ok(t.clone()) } } @@ -436,6 +436,8 @@ pub fn check(p: &Program) -> Result<(), Error> { for fd in p.fn_decls.iter() { trace!("check function\n{}", fd); + trace!("ast\n{:?}", fd); + let mut var_env = VarEnv::new(); // build a scope for the arguments diff --git a/src/grammar.lalrpop b/src/grammar.lalrpop index b978e1fd4b9dbff2f0628b8d3ffc499967e2f62f..a6ce8a2e32c9539ca68b7a5283cb75ffa72eb7a8 100644 --- a/src/grammar.lalrpop +++ b/src/grammar.lalrpop @@ -128,7 +128,7 @@ pub Block: Stmts = { }; Stmts { stmts, - ret: match st { + trailing_semi: match st { Some(_) => false, _ => true, } @@ -137,18 +137,19 @@ pub Block: Stmts = { } StmtSeq: Stmt = { + ";" => Stmt::Semi, <Stmt> ";" => <>, - StmtBlock => Stmt::Block(<>), + StmtBlock => <>, } -StmtBlock: Stmts = { - "while" Expr Block => panic!(), - "if" Expr Block ("else" Block)? => panic!(), - Block, +StmtBlock: Stmt = { + "while" <Expr> <Block> => Stmt::While(<>), + "if" <Expr> <Block> <("else" <Block>)?> => Stmt::If(<>), + Block => Stmt::Block(<>), } Stmt: Stmt = { - ";" => Stmt::Semi, + // ";" => Stmt::Semi, "let" <m: "mut"?> <id: Id> <t: (":" <Type>)?> <e: ("=" <Expr>)?> => Stmt::Let(id, m.is_some(), t, e), <Expr> "=" <Expr> => Stmt::Assign(<>), <ExprNoBlock> => Stmt::Expr(<>), diff --git a/src/vm.rs b/src/vm.rs index 6c53c48f03b1e9cfd190ae73b0236097729f58d5..8e0aa6236ec2a6028fad615754f7087ea7a92f6a 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -290,11 +290,11 @@ fn eval_stmts(stmts: &Stmts, m: &mut Mem, fn_env: &FnEnv) -> Val { } } m.pop_scope(); - if !stmts.ret { + if stmts.trailing_semi { + Val::Unit + } else { println!("statements with return value {:?}", stmt_val); stmt_val - } else { - Val::Unit } }