mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 07:41:12 +00:00
Parse closures
This commit is contained in:
parent
8fe4c749a2
commit
2c61817c7c
3 changed files with 89 additions and 10 deletions
|
@ -50,7 +50,7 @@ pub enum Expr<'a> {
|
|||
|
||||
// Pattern Matching
|
||||
When(&'a [(Loc<Pattern<'a>>, Loc<Expr<'a>>)]),
|
||||
Closure(&'a (&'a [Loc<Pattern<'a>>], Loc<Expr<'a>>)),
|
||||
Closure(&'a (Loc<Vec<'a, Loc<Pattern<'a>>>>, Loc<Expr<'a>>)),
|
||||
// /// basically Assign(Vec<(Loc<Pattern>, Loc<Expr>)>, Loc<Expr>)
|
||||
// Assign(&'a (&'a [(Loc<Pattern<'a>>, Loc<Expr<'a>>)], Loc<Expr<'a>>)),
|
||||
|
||||
|
@ -87,9 +87,9 @@ pub enum Pattern<'a> {
|
|||
// Identifier
|
||||
Identifier(&'a str),
|
||||
|
||||
// Variant
|
||||
Variant(&'a VariantName),
|
||||
AppliedVariant(&'a (Loc<&'a VariantName>, [Loc<Pattern<'a>>])),
|
||||
// Variant, optionally qualified
|
||||
Variant(&'a [&'a str], &'a VariantName),
|
||||
Apply(&'a (Loc<&'a Pattern<'a>>, [Loc<Pattern<'a>>])),
|
||||
|
||||
// Literal
|
||||
IntLiteral(i64),
|
||||
|
@ -205,7 +205,7 @@ fn pattern_size() {
|
|||
// better performance, due to more data structures being inlinable,
|
||||
// and therefore having fewer pointers to chase. This seems worth
|
||||
// investigating as well.
|
||||
std::mem::size_of::<usize>() * 4
|
||||
std::mem::size_of::<usize>() * 5
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ use parse::blankspace::{space0, space0_around, space0_before, space1_before};
|
|||
use parse::ident::{ident, Ident};
|
||||
use parse::number_literal::number_literal;
|
||||
use parse::parser::{
|
||||
and, attempt, between, char, either, loc, map, map_with_arena, one_of2, one_of4, one_of8,
|
||||
and, attempt, between, char, either, loc, map, map_with_arena, one_of2, one_of4, one_of9,
|
||||
one_or_more, optional, sep_by0, skip_first, skip_second, string, unexpected, unexpected_eof,
|
||||
Either, ParseResult, Parser, State,
|
||||
};
|
||||
|
@ -36,11 +36,12 @@ fn loc_parse_expr_body_without_operators<'a>(
|
|||
arena: &'a Bump,
|
||||
state: State<'a>,
|
||||
) -> ParseResult<'a, Located<Expr<'a>>> {
|
||||
one_of8(
|
||||
one_of9(
|
||||
loc_parenthetical_expr(min_indent),
|
||||
loc(string_literal()),
|
||||
loc(number_literal()),
|
||||
loc(record_literal(min_indent)),
|
||||
loc(closure(min_indent)),
|
||||
loc(list_literal(min_indent)),
|
||||
loc(when(min_indent)),
|
||||
loc(conditional(min_indent)),
|
||||
|
@ -156,8 +157,24 @@ fn loc_function_arg<'a>(min_indent: u16) -> impl Parser<'a, Located<Expr<'a>>> {
|
|||
}
|
||||
|
||||
fn closure<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>> {
|
||||
map(skip_first(char('\\'), one_or_more(loc_closure_param(min_indent))),
|
||||
|params
|
||||
map_with_arena(
|
||||
skip_first(
|
||||
char('\\'),
|
||||
and(
|
||||
loc(one_or_more(space0_around(
|
||||
loc_closure_param(min_indent),
|
||||
min_indent,
|
||||
))),
|
||||
skip_first(
|
||||
string("->"),
|
||||
space0_before(
|
||||
loc(move |arena, state| parse_expr(min_indent, arena, state)),
|
||||
min_indent,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|arena, (params, loc_body)| Expr::Closure(arena.alloc((params, loc_body))),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -907,3 +907,65 @@ where
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn one_of9<'a, P1, P2, P3, P4, P5, P6, P7, P8, P9, A>(
|
||||
p1: P1,
|
||||
p2: P2,
|
||||
p3: P3,
|
||||
p4: P4,
|
||||
p5: P5,
|
||||
p6: P6,
|
||||
p7: P7,
|
||||
p8: P8,
|
||||
p9: P9,
|
||||
) -> impl Parser<'a, A>
|
||||
where
|
||||
P1: Parser<'a, A>,
|
||||
P2: Parser<'a, A>,
|
||||
P3: Parser<'a, A>,
|
||||
P4: Parser<'a, A>,
|
||||
P5: Parser<'a, A>,
|
||||
P6: Parser<'a, A>,
|
||||
P7: Parser<'a, A>,
|
||||
P8: Parser<'a, A>,
|
||||
P9: Parser<'a, A>,
|
||||
{
|
||||
move |arena: &'a Bump, state: State<'a>| {
|
||||
let original_attempting = state.attempting;
|
||||
|
||||
match p1.parse(arena, state) {
|
||||
valid @ Ok(_) => valid,
|
||||
Err((_, state)) => match p2.parse(arena, state) {
|
||||
valid @ Ok(_) => valid,
|
||||
Err((_, state)) => match p3.parse(arena, state) {
|
||||
valid @ Ok(_) => valid,
|
||||
Err((_, state)) => match p4.parse(arena, state) {
|
||||
valid @ Ok(_) => valid,
|
||||
Err((_, state)) => match p5.parse(arena, state) {
|
||||
valid @ Ok(_) => valid,
|
||||
Err((_, state)) => match p6.parse(arena, state) {
|
||||
valid @ Ok(_) => valid,
|
||||
Err((_, state)) => match p7.parse(arena, state) {
|
||||
valid @ Ok(_) => valid,
|
||||
Err((_, state)) => match p8.parse(arena, state) {
|
||||
valid @ Ok(_) => valid,
|
||||
Err((_, state)) => match p9.parse(arena, state) {
|
||||
valid @ Ok(_) => valid,
|
||||
Err((fail, state)) => Err((
|
||||
Fail {
|
||||
attempting: original_attempting,
|
||||
..fail
|
||||
},
|
||||
state,
|
||||
)),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue