simplify expr in parens

This commit is contained in:
Folkert 2021-03-17 21:11:37 +01:00
parent e49860c1cd
commit 35e7f01362

View file

@ -93,41 +93,44 @@ fn loc_expr_in_parens_help_help<'a>(
fn loc_expr_in_parens_etc_help<'a>( fn loc_expr_in_parens_etc_help<'a>(
min_indent: u16, min_indent: u16,
) -> impl Parser<'a, Located<Expr<'a>>, EExpr<'a>> { ) -> impl Parser<'a, Located<Expr<'a>>, EExpr<'a>> {
then( move |arena, state: State<'a>| {
loc!(and!( let parser = loc!(and!(
specialize(EExpr::InParens, loc_expr_in_parens_help(min_indent)), specialize(EExpr::InParens, loc_expr_in_parens_help(min_indent)),
and!(
one_of![record_field_access_chain(), |a, s| Ok(( one_of![record_field_access_chain(), |a, s| Ok((
NoProgress, NoProgress,
Vec::new_in(a), Vec::new_in(a),
s s
))], ))]
// TODO remove the either ));
optional(
// There may optionally be function args after the ')' let (
// e.g. ((foo bar) baz) _,
// loc_function_args_help(min_indent), Located {
// If there aren't any args, there may be a '=' or ':' after it. mut region,
// value: (loc_expr, field_accesses),
// (It's a syntax error to write e.g. `foo bar =` - so if there },
// were any args, there is definitely no need to parse '=' or ':'!) state,
// ) = parser.parse(arena, state)?;
// Also, there may be a '.' for field access (e.g. `(foo).bar`),
// but we only want to look for that if there weren't any args, let mut value = loc_expr.value;
// as if there were any args they'd have consumed it anyway
// e.g. in `((foo bar) baz.blah)` the `.blah` will be consumed by the `baz` parser // if there are field accesses, include the parentheses in the region
map!( // otherwise, don't include the parentheses
and!( if field_accesses.is_empty() {
space0_e(min_indent, EExpr::Space, EExpr::IndentEquals), region = loc_expr.region;
equals_with_indent_help() } else {
), for field in field_accesses {
Either::Second // Wrap the previous answer in the new one, so we end up
) // with a nested Expr. That way, `foo.bar.baz` gets represented
) // in the AST as if it had been written (foo.bar).baz all along.
) value = Expr::Access(arena.alloc(value), field);
)), }
move |arena, state, _progress, parsed| helper_help(arena, state, parsed, min_indent), }
)
let loc_expr = Located::at(region, value);
Ok((MadeProgress, loc_expr, state))
}
} }
fn record_field_access_chain<'a>() -> impl Parser<'a, Vec<'a, &'a str>, EExpr<'a>> { fn record_field_access_chain<'a>() -> impl Parser<'a, Vec<'a, &'a str>, EExpr<'a>> {