feat: anonymous functions
This commit is contained in:
parent
695ac409b7
commit
512431d27f
|
@ -176,12 +176,20 @@ pub fn fn_parser() -> impl Parser<Token, ast::UntypedDefinition, Error = ParseEr
|
||||||
.delimited_by(just(Token::LeftParen), just(Token::RightParen)),
|
.delimited_by(just(Token::LeftParen), just(Token::RightParen)),
|
||||||
)
|
)
|
||||||
.then(just(Token::RArrow).ignore_then(type_parser()).or_not())
|
.then(just(Token::RArrow).ignore_then(type_parser()).or_not())
|
||||||
.then(expr_seq_parser().delimited_by(just(Token::LeftBrace), just(Token::RightBrace)))
|
.then(
|
||||||
|
expr_seq_parser()
|
||||||
|
.or_not()
|
||||||
|
.delimited_by(just(Token::LeftBrace), just(Token::RightBrace)),
|
||||||
|
)
|
||||||
.map_with_span(
|
.map_with_span(
|
||||||
|((((opt_pub, name), arguments), return_annotation), body), span| {
|
|((((opt_pub, name), arguments), return_annotation), body), span| {
|
||||||
ast::UntypedDefinition::Fn {
|
ast::UntypedDefinition::Fn {
|
||||||
arguments,
|
arguments,
|
||||||
body,
|
body: body.unwrap_or(expr::UntypedExpr::Todo {
|
||||||
|
kind: TodoKind::EmptyFunction,
|
||||||
|
location: span,
|
||||||
|
label: None,
|
||||||
|
}),
|
||||||
doc: None,
|
doc: None,
|
||||||
location: span,
|
location: span,
|
||||||
name,
|
name,
|
||||||
|
@ -229,6 +237,29 @@ pub fn fn_param_parser() -> impl Parser<Token, ast::UntypedArg, Error = ParseErr
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn anon_fn_param_parser() -> impl Parser<Token, ast::UntypedArg, Error = ParseError> {
|
||||||
|
// TODO: return a better error when a label is provided `UnexpectedLabel`
|
||||||
|
choice((
|
||||||
|
select! {Token::DiscardName {name} => name}.map_with_span(|name, span| {
|
||||||
|
ast::ArgName::Discard {
|
||||||
|
name,
|
||||||
|
location: span,
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
select! {Token::Name {name} => name}.map_with_span(|name, span| ast::ArgName::Named {
|
||||||
|
name,
|
||||||
|
location: span,
|
||||||
|
}),
|
||||||
|
))
|
||||||
|
.then(just(Token::Colon).ignore_then(type_parser()).or_not())
|
||||||
|
.map_with_span(|(arg_name, annotation), span| ast::Arg {
|
||||||
|
location: span,
|
||||||
|
annotation,
|
||||||
|
tipo: (),
|
||||||
|
arg_name,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn expr_seq_parser() -> impl Parser<Token, expr::UntypedExpr, Error = ParseError> {
|
pub fn expr_seq_parser() -> impl Parser<Token, expr::UntypedExpr, Error = ParseError> {
|
||||||
recursive(|r| {
|
recursive(|r| {
|
||||||
choice((
|
choice((
|
||||||
|
@ -310,6 +341,28 @@ pub fn expr_parser(
|
||||||
tail,
|
tail,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let anon_fn_parser = just(Token::Fn)
|
||||||
|
.ignore_then(
|
||||||
|
anon_fn_param_parser()
|
||||||
|
.separated_by(just(Token::Comma))
|
||||||
|
.delimited_by(just(Token::LeftParen), just(Token::RightParen)),
|
||||||
|
)
|
||||||
|
.then(just(Token::RArrow).ignore_then(type_parser()).or_not())
|
||||||
|
.then(
|
||||||
|
seq_r
|
||||||
|
.clone()
|
||||||
|
.delimited_by(just(Token::LeftBrace), just(Token::RightBrace)),
|
||||||
|
)
|
||||||
|
.map_with_span(
|
||||||
|
|((arguments, return_annotation), body), span| expr::UntypedExpr::Fn {
|
||||||
|
arguments,
|
||||||
|
body: Box::new(body),
|
||||||
|
location: span,
|
||||||
|
is_capture: false,
|
||||||
|
return_annotation,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
let block_parser = seq_r.delimited_by(just(Token::LeftBrace), just(Token::RightBrace));
|
let block_parser = seq_r.delimited_by(just(Token::LeftBrace), just(Token::RightBrace));
|
||||||
|
|
||||||
// TODO: do guards later
|
// TODO: do guards later
|
||||||
|
@ -393,6 +446,7 @@ pub fn expr_parser(
|
||||||
var_parser,
|
var_parser,
|
||||||
todo_parser,
|
todo_parser,
|
||||||
list_parser,
|
list_parser,
|
||||||
|
anon_fn_parser,
|
||||||
block_parser,
|
block_parser,
|
||||||
when_parser,
|
when_parser,
|
||||||
let_parser,
|
let_parser,
|
||||||
|
|
|
@ -69,6 +69,12 @@ fn module() {
|
||||||
_ -> 4
|
_ -> 4
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn such() -> Int {
|
||||||
|
let add_one = fn (a: Int) -> Int { a + 1 }
|
||||||
|
|
||||||
|
2 |> add_one
|
||||||
|
}
|
||||||
"#;
|
"#;
|
||||||
let len = code.chars().count();
|
let len = code.chars().count();
|
||||||
|
|
||||||
|
@ -627,6 +633,82 @@ fn module() {
|
||||||
return_annotation: None,
|
return_annotation: None,
|
||||||
return_type: (),
|
return_type: (),
|
||||||
},
|
},
|
||||||
|
ast::UntypedDefinition::Fn {
|
||||||
|
arguments: vec![],
|
||||||
|
body: expr::UntypedExpr::Sequence {
|
||||||
|
location: Span::new(SrcId::empty(), 1292..1364),
|
||||||
|
expressions: vec![
|
||||||
|
expr::UntypedExpr::Assignment {
|
||||||
|
location: Span::new(SrcId::empty(), 1292..1334),
|
||||||
|
value: Box::new(expr::UntypedExpr::Fn {
|
||||||
|
location: Span::new(SrcId::empty(), 1306..1334),
|
||||||
|
is_capture: false,
|
||||||
|
arguments: vec![ast::Arg {
|
||||||
|
arg_name: ast::ArgName::Named {
|
||||||
|
name: "a".to_string(),
|
||||||
|
location: Span::new(SrcId::empty(), 1310..1311),
|
||||||
|
},
|
||||||
|
location: Span::new(SrcId::empty(), 1310..1316),
|
||||||
|
annotation: Some(ast::Annotation::Constructor {
|
||||||
|
location: Span::new(SrcId::empty(), 1313..1316),
|
||||||
|
module: None,
|
||||||
|
name: "Int".to_string(),
|
||||||
|
arguments: vec![],
|
||||||
|
},),
|
||||||
|
tipo: (),
|
||||||
|
},],
|
||||||
|
body: Box::new(expr::UntypedExpr::BinOp {
|
||||||
|
location: Span::new(SrcId::empty(), 1327..1332),
|
||||||
|
name: ast::BinOp::AddInt,
|
||||||
|
left: Box::new(expr::UntypedExpr::Var {
|
||||||
|
location: Span::new(SrcId::empty(), 1327..1328),
|
||||||
|
name: "a".to_string(),
|
||||||
|
}),
|
||||||
|
right: Box::new(expr::UntypedExpr::Int {
|
||||||
|
location: Span::new(SrcId::empty(), 1331..1332),
|
||||||
|
value: "1".to_string(),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
return_annotation: Some(ast::Annotation::Constructor {
|
||||||
|
location: Span::new(SrcId::empty(), 1321..1324),
|
||||||
|
module: None,
|
||||||
|
name: "Int".to_string(),
|
||||||
|
arguments: vec![],
|
||||||
|
},),
|
||||||
|
}),
|
||||||
|
pattern: ast::Pattern::Var {
|
||||||
|
location: Span::new(SrcId::empty(), 1296..1303),
|
||||||
|
name: "add_one".to_string(),
|
||||||
|
},
|
||||||
|
kind: ast::AssignmentKind::Let,
|
||||||
|
annotation: None,
|
||||||
|
},
|
||||||
|
expr::UntypedExpr::PipeLine {
|
||||||
|
expressions: vec1::vec1![
|
||||||
|
expr::UntypedExpr::Int {
|
||||||
|
location: Span::new(SrcId::empty(), 1352..1353),
|
||||||
|
value: "2".to_string(),
|
||||||
|
},
|
||||||
|
expr::UntypedExpr::Var {
|
||||||
|
location: Span::new(SrcId::empty(), 1357..1364),
|
||||||
|
name: "add_one".to_string(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
doc: None,
|
||||||
|
location: Span::new(SrcId::empty(), 1253..1378),
|
||||||
|
name: "such".to_string(),
|
||||||
|
public: true,
|
||||||
|
return_annotation: Some(ast::Annotation::Constructor {
|
||||||
|
location: Span::new(SrcId::empty(), 1270..1273),
|
||||||
|
module: None,
|
||||||
|
name: "Int".to_string(),
|
||||||
|
arguments: vec![],
|
||||||
|
},),
|
||||||
|
return_type: (),
|
||||||
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue