parse and format pattern as

This commit is contained in:
Folkert 2022-12-30 17:50:17 +01:00
parent ea53a50447
commit e9196f3c0b
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
13 changed files with 189 additions and 7 deletions

View file

@ -1,10 +1,11 @@
use crate::ast::{Has, Pattern};
use crate::ast::{CommentOrNewline, Has, Pattern, Spaceable};
use crate::blankspace::{space0_before_e, space0_e};
use crate::ident::{lowercase_ident, parse_ident, Ident};
use crate::keyword;
use crate::parser::Progress::{self, *};
use crate::parser::{
backtrackable, fail_when, optional, specialize, specialize_ref, then, word1, word2, word3,
EPattern, PInParens, PList, PRecord, Parser,
self, backtrackable, fail_when, optional, specialize, specialize_ref, then, word1, word2,
word3, EPattern, PInParens, PList, PRecord, Parser,
};
use crate::state::State;
use bumpalo::collections::string::String;
@ -42,6 +43,35 @@ pub fn closure_param<'a>() -> impl Parser<'a, Loc<Pattern<'a>>, EPattern<'a>> {
}
pub fn loc_pattern_help<'a>() -> impl Parser<'a, Loc<Pattern<'a>>, EPattern<'a>> {
move |arena, state: State<'a>, min_indent| {
let (_, pattern, state) = loc_pattern_help_help().parse(arena, state, min_indent)?;
let pattern_state = state.clone();
let (pattern_spaces, state) = match space0_e(EPattern::As).parse(arena, state, min_indent) {
Err(_) => return Ok((MadeProgress, pattern, pattern_state)),
Ok((_, pattern_spaces, state)) => (pattern_spaces, state),
};
match pattern_as().parse(arena, state, min_indent) {
Err((progress, e)) => match progress {
MadeProgress => Err((MadeProgress, e)),
NoProgress => Ok((MadeProgress, pattern, pattern_state)),
},
Ok((_, (spaces, identifier), state)) => {
let region = Region::span_across(&pattern.region, &identifier.region);
let pattern = arena
.alloc(pattern.value)
.with_spaces_after(pattern_spaces, pattern.region);
let as_pattern = Pattern::As(arena.alloc(pattern), spaces, identifier);
Ok((MadeProgress, Loc::at(region, as_pattern), state))
}
}
}
}
fn loc_pattern_help_help<'a>() -> impl Parser<'a, Loc<Pattern<'a>>, EPattern<'a>> {
one_of!(
specialize(EPattern::PInParens, loc_pattern_in_parens_help()),
loc!(underscore_pattern_help()),
@ -57,6 +87,23 @@ pub fn loc_pattern_help<'a>() -> impl Parser<'a, Loc<Pattern<'a>>, EPattern<'a>>
)
}
fn pattern_as<'a>() -> impl Parser<'a, (&'a [CommentOrNewline<'a>], Loc<&'a str>), EPattern<'a>> {
move |arena, state: State<'a>, min_indent| {
let (_, _, state) =
parser::keyword_e(keyword::AS, EPattern::As).parse(arena, state, min_indent)?;
let (_, spaces, state) =
space0_e(EPattern::AsIdentifier).parse(arena, state, min_indent)?;
let position = state.pos();
match loc!(lowercase_ident()).parse(arena, state, min_indent) {
Ok((_, identifier, state)) => Ok((MadeProgress, (spaces, identifier), state)),
Err((_, ())) => Err((MadeProgress, EPattern::AsIdentifier(position))),
}
}
}
fn loc_tag_pattern_args_help<'a>() -> impl Parser<'a, Vec<'a, Loc<Pattern<'a>>>, EPattern<'a>> {
zero_or_more!(loc_tag_pattern_arg(false))
}