feat: finish when clauses
This commit is contained in:
parent
722dc4b477
commit
c7c11d1bd5
|
@ -25,6 +25,9 @@ pub fn lexer() -> impl Parser<char, Vec<(Token, Span)>, Error = ParseError> {
|
||||||
just("|>").to(Token::Pipe),
|
just("|>").to(Token::Pipe),
|
||||||
just(',').to(Token::Comma),
|
just(',').to(Token::Comma),
|
||||||
just(':').to(Token::Colon),
|
just(':').to(Token::Colon),
|
||||||
|
just('|').to(Token::Vbar),
|
||||||
|
just("||").to(Token::VbarVbar),
|
||||||
|
just("&&").to(Token::AmperAmper),
|
||||||
));
|
));
|
||||||
|
|
||||||
let grouping = choice((
|
let grouping = choice((
|
||||||
|
|
|
@ -236,7 +236,7 @@ pub fn expr_seq_parser() -> impl Parser<Token, expr::UntypedExpr, Error = ParseE
|
||||||
.ignore_then(pattern_parser())
|
.ignore_then(pattern_parser())
|
||||||
.then(just(Token::Colon).ignore_then(type_parser()).or_not())
|
.then(just(Token::Colon).ignore_then(type_parser()).or_not())
|
||||||
.then_ignore(just(Token::Equal))
|
.then_ignore(just(Token::Equal))
|
||||||
.then(expr_parser())
|
.then(expr_parser(r.clone()))
|
||||||
.then(r.clone())
|
.then(r.clone())
|
||||||
.map_with_span(|(((pattern, annotation), value), then_), span| {
|
.map_with_span(|(((pattern, annotation), value), then_), span| {
|
||||||
expr::UntypedExpr::Try {
|
expr::UntypedExpr::Try {
|
||||||
|
@ -247,14 +247,16 @@ pub fn expr_seq_parser() -> impl Parser<Token, expr::UntypedExpr, Error = ParseE
|
||||||
annotation,
|
annotation,
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
expr_parser()
|
expr_parser(r.clone())
|
||||||
.then(r.repeated())
|
.then(r.repeated())
|
||||||
.foldl(|current, next| current.append_in_sequence(next)),
|
.foldl(|current, next| current.append_in_sequence(next)),
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expr_parser() -> impl Parser<Token, expr::UntypedExpr, Error = ParseError> {
|
pub fn expr_parser(
|
||||||
|
seq_r: Recursive<'_, Token, expr::UntypedExpr, ParseError>,
|
||||||
|
) -> impl Parser<Token, expr::UntypedExpr, Error = ParseError> + '_ {
|
||||||
recursive(|r| {
|
recursive(|r| {
|
||||||
let string_parser =
|
let string_parser =
|
||||||
select! {Token::String {value} => value}.map_with_span(|value, span| {
|
select! {Token::String {value} => value}.map_with_span(|value, span| {
|
||||||
|
@ -323,30 +325,38 @@ pub fn expr_parser() -> impl Parser<Token, expr::UntypedExpr, Error = ParseError
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
let when_clause_guard_parser = just(Token::If);
|
let block_parser = seq_r.delimited_by(just(Token::LeftBrace), just(Token::RightBrace));
|
||||||
|
|
||||||
|
// TODO: do guards later
|
||||||
|
// let when_clause_guard_parser = just(Token::If);
|
||||||
|
|
||||||
let when_clause_parser = pattern_parser()
|
let when_clause_parser = pattern_parser()
|
||||||
.separated_by(just(Token::Comma))
|
.separated_by(just(Token::Comma))
|
||||||
|
.at_least(1)
|
||||||
.then(
|
.then(
|
||||||
|
just(Token::Vbar)
|
||||||
|
.ignore_then(
|
||||||
pattern_parser()
|
pattern_parser()
|
||||||
.separated_by(just(Token::Comma))
|
.separated_by(just(Token::Comma))
|
||||||
.separated_by(just(Token::Vbar))
|
.at_least(1),
|
||||||
.allow_leading()
|
)
|
||||||
|
.repeated()
|
||||||
.or_not(),
|
.or_not(),
|
||||||
)
|
)
|
||||||
.then(when_clause_guard_parser)
|
// TODO: do guards later
|
||||||
|
// .then(when_clause_guard_parser)
|
||||||
// TODO: add hint "Did you mean to wrap a multi line clause in curly braces?"
|
// TODO: add hint "Did you mean to wrap a multi line clause in curly braces?"
|
||||||
.then_ignore(just(Token::RArrow))
|
.then_ignore(just(Token::RArrow))
|
||||||
.then(r.clone())
|
.then(r.clone())
|
||||||
.map_with_span(
|
.map_with_span(|((patterns, alternative_patterns_opt), then), span| {
|
||||||
|(((patterns, alternative_patterns_opt), guard), then), span| ast::UntypedClause {
|
ast::UntypedClause {
|
||||||
location: span,
|
location: span,
|
||||||
pattern: patterns,
|
pattern: patterns,
|
||||||
alternative_patterns: alternative_patterns_opt.unwrap_or_default(),
|
alternative_patterns: alternative_patterns_opt.unwrap_or_default(),
|
||||||
guard,
|
guard: None,
|
||||||
then,
|
then,
|
||||||
},
|
}
|
||||||
);
|
});
|
||||||
|
|
||||||
let when_parser = just(Token::When)
|
let when_parser = just(Token::When)
|
||||||
// TODO: If subject is empty we should return ParseErrorType::ExpectedExpr,
|
// TODO: If subject is empty we should return ParseErrorType::ExpectedExpr,
|
||||||
|
@ -369,6 +379,7 @@ pub fn expr_parser() -> impl Parser<Token, expr::UntypedExpr, Error = ParseError
|
||||||
todo_parser,
|
todo_parser,
|
||||||
list_parser,
|
list_parser,
|
||||||
assignment_parser,
|
assignment_parser,
|
||||||
|
block_parser,
|
||||||
when_parser,
|
when_parser,
|
||||||
))
|
))
|
||||||
.boxed();
|
.boxed();
|
||||||
|
|
|
@ -52,10 +52,20 @@ fn module() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wow2(a: Int){
|
pub fn wow2(a: Int){
|
||||||
when a is {
|
let b = {
|
||||||
0 -> 3
|
let x = 4
|
||||||
1 | 2 -> 5
|
|
||||||
3 if a == 3 -> 9
|
x + 5
|
||||||
|
}
|
||||||
|
|
||||||
|
when a, b is {
|
||||||
|
1, 2 -> 3
|
||||||
|
1 | 4, 5 -> {
|
||||||
|
let amazing = 5
|
||||||
|
|
||||||
|
amazing
|
||||||
|
}
|
||||||
|
3 -> 9
|
||||||
_ -> 4
|
_ -> 4
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -445,6 +455,178 @@ fn module() {
|
||||||
return_annotation: None,
|
return_annotation: None,
|
||||||
return_type: (),
|
return_type: (),
|
||||||
},
|
},
|
||||||
|
ast::UntypedDefinition::Fn {
|
||||||
|
arguments: vec![ast::Arg {
|
||||||
|
arg_name: ast::ArgName::Named {
|
||||||
|
name: "a".to_string(),
|
||||||
|
location: Span::new(SrcId::empty(), 866..867),
|
||||||
|
},
|
||||||
|
location: Span::new(SrcId::empty(), 866..872),
|
||||||
|
annotation: Some(ast::Annotation::Constructor {
|
||||||
|
location: Span::new(SrcId::empty(), 869..872),
|
||||||
|
module: None,
|
||||||
|
name: "Int".to_string(),
|
||||||
|
arguments: vec![],
|
||||||
|
},),
|
||||||
|
tipo: (),
|
||||||
|
},],
|
||||||
|
body: expr::UntypedExpr::Sequence {
|
||||||
|
location: Span::new(SrcId::empty(), 889..1225),
|
||||||
|
expressions: vec![
|
||||||
|
expr::UntypedExpr::Assignment {
|
||||||
|
location: Span::new(SrcId::empty(), 889..980),
|
||||||
|
value: Box::new(expr::UntypedExpr::Sequence {
|
||||||
|
location: Span::new(SrcId::empty(), 915..964),
|
||||||
|
expressions: vec![
|
||||||
|
expr::UntypedExpr::Assignment {
|
||||||
|
location: Span::new(SrcId::empty(), 915..924),
|
||||||
|
value: Box::new(expr::UntypedExpr::Int {
|
||||||
|
location: Span::new(SrcId::empty(), 923..924),
|
||||||
|
value: "4".to_string(),
|
||||||
|
}),
|
||||||
|
pattern: ast::Pattern::Var {
|
||||||
|
location: Span::new(SrcId::empty(), 919..920),
|
||||||
|
name: "x".to_string(),
|
||||||
|
},
|
||||||
|
kind: ast::AssignmentKind::Let,
|
||||||
|
annotation: None,
|
||||||
|
},
|
||||||
|
expr::UntypedExpr::BinOp {
|
||||||
|
location: Span::new(SrcId::empty(), 959..964),
|
||||||
|
name: ast::BinOp::AddInt,
|
||||||
|
left: Box::new(expr::UntypedExpr::Var {
|
||||||
|
location: Span::new(SrcId::empty(), 959..960),
|
||||||
|
name: "x".to_string(),
|
||||||
|
}),
|
||||||
|
right: Box::new(expr::UntypedExpr::Int {
|
||||||
|
location: Span::new(SrcId::empty(), 963..964),
|
||||||
|
value: "5".to_string(),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
pattern: ast::Pattern::Var {
|
||||||
|
location: Span::new(SrcId::empty(), 893..894),
|
||||||
|
name: "b".to_string(),
|
||||||
|
},
|
||||||
|
kind: ast::AssignmentKind::Let,
|
||||||
|
annotation: None,
|
||||||
|
},
|
||||||
|
expr::UntypedExpr::When {
|
||||||
|
location: Span::new(SrcId::empty(), 996..1225),
|
||||||
|
subjects: vec![
|
||||||
|
expr::UntypedExpr::Var {
|
||||||
|
location: Span::new(SrcId::empty(), 1001..1002),
|
||||||
|
name: "a".to_string(),
|
||||||
|
},
|
||||||
|
expr::UntypedExpr::Var {
|
||||||
|
location: Span::new(SrcId::empty(), 1004..1005),
|
||||||
|
name: "b".to_string(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
clauses: vec![
|
||||||
|
ast::Clause {
|
||||||
|
location: Span::new(SrcId::empty(), 1027..1036),
|
||||||
|
pattern: vec![
|
||||||
|
ast::Pattern::Int {
|
||||||
|
location: Span::new(SrcId::empty(), 1027..1028),
|
||||||
|
value: "1".to_string(),
|
||||||
|
},
|
||||||
|
ast::Pattern::Int {
|
||||||
|
location: Span::new(SrcId::empty(), 1030..1031),
|
||||||
|
value: "2".to_string(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
alternative_patterns: vec![],
|
||||||
|
guard: None,
|
||||||
|
then: expr::UntypedExpr::Int {
|
||||||
|
location: Span::new(SrcId::empty(), 1035..1036),
|
||||||
|
value: "3".to_string(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ast::Clause {
|
||||||
|
location: Span::new(SrcId::empty(), 1053..1163),
|
||||||
|
pattern: vec![ast::Pattern::Int {
|
||||||
|
location: Span::new(SrcId::empty(), 1053..1054),
|
||||||
|
value: "1".to_string(),
|
||||||
|
},],
|
||||||
|
alternative_patterns: vec![vec![
|
||||||
|
ast::Pattern::Int {
|
||||||
|
location: Span::new(SrcId::empty(), 1057..1058),
|
||||||
|
value: "4".to_string(),
|
||||||
|
},
|
||||||
|
ast::Pattern::Int {
|
||||||
|
location: Span::new(SrcId::empty(), 1060..1061),
|
||||||
|
value: "5".to_string(),
|
||||||
|
},
|
||||||
|
],],
|
||||||
|
guard: None,
|
||||||
|
then: expr::UntypedExpr::Sequence {
|
||||||
|
location: Span::new(SrcId::empty(), 1085..1145),
|
||||||
|
expressions: vec![
|
||||||
|
expr::UntypedExpr::Assignment {
|
||||||
|
location: Span::new(SrcId::empty(), 1085..1100),
|
||||||
|
value: Box::new(expr::UntypedExpr::Int {
|
||||||
|
location: Span::new(
|
||||||
|
SrcId::empty(),
|
||||||
|
1099..1100
|
||||||
|
),
|
||||||
|
value: "5".to_string(),
|
||||||
|
}),
|
||||||
|
pattern: ast::Pattern::Var {
|
||||||
|
location: Span::new(
|
||||||
|
SrcId::empty(),
|
||||||
|
1089..1096
|
||||||
|
),
|
||||||
|
name: "amazing".to_string(),
|
||||||
|
},
|
||||||
|
kind: ast::AssignmentKind::Let,
|
||||||
|
annotation: None,
|
||||||
|
},
|
||||||
|
expr::UntypedExpr::Var {
|
||||||
|
location: Span::new(SrcId::empty(), 1138..1145),
|
||||||
|
name: "amazing".to_string(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ast::Clause {
|
||||||
|
location: Span::new(SrcId::empty(), 1180..1186),
|
||||||
|
pattern: vec![ast::Pattern::Int {
|
||||||
|
location: Span::new(SrcId::empty(), 1180..1181),
|
||||||
|
value: "3".to_string(),
|
||||||
|
},],
|
||||||
|
alternative_patterns: vec![],
|
||||||
|
guard: None,
|
||||||
|
then: expr::UntypedExpr::Int {
|
||||||
|
location: Span::new(SrcId::empty(), 1185..1186),
|
||||||
|
value: "9".to_string(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ast::Clause {
|
||||||
|
location: Span::new(SrcId::empty(), 1203..1209),
|
||||||
|
pattern: vec![ast::Pattern::Discard {
|
||||||
|
name: "_".to_string(),
|
||||||
|
location: Span::new(SrcId::empty(), 1203..1204),
|
||||||
|
},],
|
||||||
|
alternative_patterns: vec![],
|
||||||
|
guard: None,
|
||||||
|
then: expr::UntypedExpr::Int {
|
||||||
|
location: Span::new(SrcId::empty(), 1208..1209),
|
||||||
|
value: "4".to_string(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
doc: None,
|
||||||
|
location: Span::new(SrcId::empty(), 854..1239),
|
||||||
|
name: "wow2".to_string(),
|
||||||
|
public: true,
|
||||||
|
return_annotation: None,
|
||||||
|
return_type: (),
|
||||||
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue