conlang: Single-expression functions
This commit is contained in:
parent
3b14186b70
commit
772286eefa
@ -146,7 +146,7 @@ pub struct Function {
|
|||||||
pub name: Sym,
|
pub name: Sym,
|
||||||
pub sign: TyFn,
|
pub sign: TyFn,
|
||||||
pub bind: Vec<Param>,
|
pub bind: Vec<Param>,
|
||||||
pub body: Option<Block>,
|
pub body: Option<Expr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A single parameter for a [Function]
|
/// A single parameter for a [Function]
|
||||||
|
@ -107,7 +107,7 @@ pub trait Fold {
|
|||||||
name: self.fold_sym(name),
|
name: self.fold_sym(name),
|
||||||
sign: self.fold_ty_fn(sign),
|
sign: self.fold_ty_fn(sign),
|
||||||
bind: bind.into_iter().map(|p| self.fold_param(p)).collect(),
|
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 {
|
fn fold_param(&mut self, p: Param) -> Param {
|
||||||
|
@ -85,7 +85,7 @@ pub trait Visit<'a>: Sized {
|
|||||||
self.visit_ty_fn(sign);
|
self.visit_ty_fn(sign);
|
||||||
bind.iter().for_each(|p| self.visit_param(p));
|
bind.iter().for_each(|p| self.visit_param(p));
|
||||||
if let Some(b) = body {
|
if let Some(b) = body {
|
||||||
self.visit_block(b)
|
self.visit_expr(b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn visit_param(&mut self, p: &'a Param) {
|
fn visit_param(&mut self, p: &'a Param) {
|
||||||
|
@ -71,7 +71,7 @@ impl<'a> Visit<'a> for CollectUpvars<'_> {
|
|||||||
self.bind_name(name);
|
self.bind_name(name);
|
||||||
}
|
}
|
||||||
if let Some(body) = body {
|
if let Some(body) = body {
|
||||||
self.visit_block(body);
|
self.visit_expr(body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -459,12 +459,11 @@ impl Parse<'_> for Function {
|
|||||||
sign,
|
sign,
|
||||||
bind,
|
bind,
|
||||||
body: match p.peek_kind(P)? {
|
body: match p.peek_kind(P)? {
|
||||||
TokenKind::LCurly => Some(Block::parse(p)?),
|
|
||||||
TokenKind::Semi => {
|
TokenKind::Semi => {
|
||||||
p.consume_peeked();
|
p.consume_peeked();
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
t => Err(p.error(Unexpected(t), P))?,
|
_ => Some(Expr::parse(p)?),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -108,7 +108,7 @@ impl<'a> Visit<'a> for Populator<'_, 'a> {
|
|||||||
self.visit_ty_fn(sign);
|
self.visit_ty_fn(sign);
|
||||||
bind.iter().for_each(|p| self.visit_param(p));
|
bind.iter().for_each(|p| self.visit_param(p));
|
||||||
if let Some(b) = body {
|
if let Some(b) = body {
|
||||||
self.visit_block(b)
|
self.visit_expr(b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
13
grammar.ebnf
13
grammar.ebnf
@ -26,7 +26,7 @@ Static = "static" Mutability Identifier ':' Ty '=' Expr ';' ;
|
|||||||
Module = "mod" Identifier ModuleKind ;
|
Module = "mod" Identifier ModuleKind ;
|
||||||
ModuleKind = '{' Item* '}' | ';' ;
|
ModuleKind = '{' Item* '}' | ';' ;
|
||||||
|
|
||||||
Function = "fn" Identifier '(' (Param ',')* Param? ')' ('->' Ty)? Block? ;
|
Function = "fn" Identifier '(' (Param ',')* Param? ')' ('->' Ty)? (Expr | ';') ;
|
||||||
Param = Mutability Identifier ':' Ty ;
|
Param = Mutability Identifier ':' Ty ;
|
||||||
|
|
||||||
Struct = "struct" Identifier (StructTuple | StructBody)?;
|
Struct = "struct" Identifier (StructTuple | StructBody)?;
|
||||||
@ -127,6 +127,17 @@ Block = '{' Stmt* '}';
|
|||||||
Group = Empty | '(' (Expr | Tuple) ')' ;
|
Group = Empty | '(' (Expr | Tuple) ')' ;
|
||||||
Tuple = (Expr ',')* Expr? ;
|
Tuple = (Expr ',')* Expr? ;
|
||||||
|
|
||||||
|
|
||||||
|
Match = "match" { (MatchArm ',')* MatchArm? } ;
|
||||||
|
MatchArm = Pattern '=>' Expr ;
|
||||||
|
Pattern = Path
|
||||||
|
| Literal
|
||||||
|
| '&' "mut"? Pattern
|
||||||
|
| '(' (Pattern ',')* (Pattern | '..' )? ')'
|
||||||
|
| '[' (Pattern ',')* (Pattern | '..' Identifier?)? ']'
|
||||||
|
| StructPattern
|
||||||
|
;
|
||||||
|
|
||||||
Loop = "loop" Block ;
|
Loop = "loop" Block ;
|
||||||
While = "while" Expr Block Else ;
|
While = "while" Expr Block Else ;
|
||||||
If = "if" Expr Block Else ;
|
If = "if" Expr Block Else ;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user