diff --git a/compiler/cl-ast/src/ast.rs b/compiler/cl-ast/src/ast.rs index 1cf907f..526d9f3 100644 --- a/compiler/cl-ast/src/ast.rs +++ b/compiler/cl-ast/src/ast.rs @@ -146,7 +146,7 @@ pub struct Function { pub name: Sym, pub sign: TyFn, pub bind: Vec, - pub body: Option, + pub body: Option, } /// A single parameter for a [Function] diff --git a/compiler/cl-ast/src/ast_visitor/fold.rs b/compiler/cl-ast/src/ast_visitor/fold.rs index 4d28bbd..f8eb748 100644 --- a/compiler/cl-ast/src/ast_visitor/fold.rs +++ b/compiler/cl-ast/src/ast_visitor/fold.rs @@ -107,7 +107,7 @@ pub trait Fold { name: self.fold_sym(name), sign: self.fold_ty_fn(sign), bind: bind.into_iter().map(|p| self.fold_param(p)).collect(), - body: body.map(|b| self.fold_block(b)), + body: body.map(|b| self.fold_expr(b)), } } fn fold_param(&mut self, p: Param) -> Param { diff --git a/compiler/cl-ast/src/ast_visitor/visit.rs b/compiler/cl-ast/src/ast_visitor/visit.rs index cc71530..e17d8a8 100644 --- a/compiler/cl-ast/src/ast_visitor/visit.rs +++ b/compiler/cl-ast/src/ast_visitor/visit.rs @@ -85,7 +85,7 @@ pub trait Visit<'a>: Sized { self.visit_ty_fn(sign); bind.iter().for_each(|p| self.visit_param(p)); if let Some(b) = body { - self.visit_block(b) + self.visit_expr(b) } } fn visit_param(&mut self, p: &'a Param) { diff --git a/compiler/cl-interpret/src/function/collect_upvars.rs b/compiler/cl-interpret/src/function/collect_upvars.rs index f2a603f..10c6836 100644 --- a/compiler/cl-interpret/src/function/collect_upvars.rs +++ b/compiler/cl-interpret/src/function/collect_upvars.rs @@ -71,7 +71,7 @@ impl<'a> Visit<'a> for CollectUpvars<'_> { self.bind_name(name); } if let Some(body) = body { - self.visit_block(body); + self.visit_expr(body); } } diff --git a/compiler/cl-parser/src/parser.rs b/compiler/cl-parser/src/parser.rs index f2d649e..9a608d1 100644 --- a/compiler/cl-parser/src/parser.rs +++ b/compiler/cl-parser/src/parser.rs @@ -459,12 +459,11 @@ impl Parse<'_> for Function { sign, bind, body: match p.peek_kind(P)? { - TokenKind::LCurly => Some(Block::parse(p)?), TokenKind::Semi => { p.consume_peeked(); None } - t => Err(p.error(Unexpected(t), P))?, + _ => Some(Expr::parse(p)?), }, }) } diff --git a/compiler/cl-typeck/src/stage/populate.rs b/compiler/cl-typeck/src/stage/populate.rs index 4a280d3..5e890e5 100644 --- a/compiler/cl-typeck/src/stage/populate.rs +++ b/compiler/cl-typeck/src/stage/populate.rs @@ -108,7 +108,7 @@ impl<'a> Visit<'a> for Populator<'_, 'a> { self.visit_ty_fn(sign); bind.iter().for_each(|p| self.visit_param(p)); if let Some(b) = body { - self.visit_block(b) + self.visit_expr(b) } } diff --git a/grammar.ebnf b/grammar.ebnf index 928b70e..37447b6 100644 --- a/grammar.ebnf +++ b/grammar.ebnf @@ -26,7 +26,7 @@ Static = "static" Mutability Identifier ':' Ty '=' Expr ';' ; Module = "mod" Identifier ModuleKind ; ModuleKind = '{' Item* '}' | ';' ; -Function = "fn" Identifier '(' (Param ',')* Param? ')' ('->' Ty)? Block? ; +Function = "fn" Identifier '(' (Param ',')* Param? ')' ('->' Ty)? (Expr | ';') ; Param = Mutability Identifier ':' Ty ; Struct = "struct" Identifier (StructTuple | StructBody)?; @@ -127,6 +127,17 @@ Block = '{' Stmt* '}'; Group = Empty | '(' (Expr | Tuple) ')' ; Tuple = (Expr ',')* Expr? ; + +Match = "match" { (MatchArm ',')* MatchArm? } ; +MatchArm = Pattern '=>' Expr ; +Pattern = Path + | Literal + | '&' "mut"? Pattern + | '(' (Pattern ',')* (Pattern | '..' )? ')' + | '[' (Pattern ',')* (Pattern | '..' Identifier?)? ']' + | StructPattern + ; + Loop = "loop" Block ; While = "while" Expr Block Else ; If = "if" Expr Block Else ;