mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 15:51: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
|
// Pattern Matching
|
||||||
When(&'a [(Loc<Pattern<'a>>, Loc<Expr<'a>>)]),
|
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>)
|
// /// basically Assign(Vec<(Loc<Pattern>, Loc<Expr>)>, Loc<Expr>)
|
||||||
// Assign(&'a (&'a [(Loc<Pattern<'a>>, Loc<Expr<'a>>)], Loc<Expr<'a>>)),
|
// Assign(&'a (&'a [(Loc<Pattern<'a>>, Loc<Expr<'a>>)], Loc<Expr<'a>>)),
|
||||||
|
|
||||||
|
@ -87,9 +87,9 @@ pub enum Pattern<'a> {
|
||||||
// Identifier
|
// Identifier
|
||||||
Identifier(&'a str),
|
Identifier(&'a str),
|
||||||
|
|
||||||
// Variant
|
// Variant, optionally qualified
|
||||||
Variant(&'a VariantName),
|
Variant(&'a [&'a str], &'a VariantName),
|
||||||
AppliedVariant(&'a (Loc<&'a VariantName>, [Loc<Pattern<'a>>])),
|
Apply(&'a (Loc<&'a Pattern<'a>>, [Loc<Pattern<'a>>])),
|
||||||
|
|
||||||
// Literal
|
// Literal
|
||||||
IntLiteral(i64),
|
IntLiteral(i64),
|
||||||
|
@ -205,7 +205,7 @@ fn pattern_size() {
|
||||||
// better performance, due to more data structures being inlinable,
|
// better performance, due to more data structures being inlinable,
|
||||||
// and therefore having fewer pointers to chase. This seems worth
|
// and therefore having fewer pointers to chase. This seems worth
|
||||||
// investigating as well.
|
// 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::ident::{ident, Ident};
|
||||||
use parse::number_literal::number_literal;
|
use parse::number_literal::number_literal;
|
||||||
use parse::parser::{
|
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,
|
one_or_more, optional, sep_by0, skip_first, skip_second, string, unexpected, unexpected_eof,
|
||||||
Either, ParseResult, Parser, State,
|
Either, ParseResult, Parser, State,
|
||||||
};
|
};
|
||||||
|
@ -36,11 +36,12 @@ fn loc_parse_expr_body_without_operators<'a>(
|
||||||
arena: &'a Bump,
|
arena: &'a Bump,
|
||||||
state: State<'a>,
|
state: State<'a>,
|
||||||
) -> ParseResult<'a, Located<Expr<'a>>> {
|
) -> ParseResult<'a, Located<Expr<'a>>> {
|
||||||
one_of8(
|
one_of9(
|
||||||
loc_parenthetical_expr(min_indent),
|
loc_parenthetical_expr(min_indent),
|
||||||
loc(string_literal()),
|
loc(string_literal()),
|
||||||
loc(number_literal()),
|
loc(number_literal()),
|
||||||
loc(record_literal(min_indent)),
|
loc(record_literal(min_indent)),
|
||||||
|
loc(closure(min_indent)),
|
||||||
loc(list_literal(min_indent)),
|
loc(list_literal(min_indent)),
|
||||||
loc(when(min_indent)),
|
loc(when(min_indent)),
|
||||||
loc(conditional(min_indent)),
|
loc(conditional(min_indent)),
|
||||||
|
@ -156,9 +157,25 @@ 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>> {
|
fn closure<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>> {
|
||||||
map(skip_first(char('\\'), one_or_more(loc_closure_param(min_indent))),
|
map_with_arena(
|
||||||
|params
|
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))),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn loc_closure_param<'a>(min_indent: u16) -> impl Parser<'a, Located<Pattern<'a>>> {
|
fn loc_closure_param<'a>(min_indent: u16) -> impl Parser<'a, Located<Pattern<'a>>> {
|
||||||
|
|
|
@ -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