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 ;