refactor PatternAs

This commit is contained in:
Folkert 2022-12-30 18:22:10 +01:00
parent e9196f3c0b
commit aff70bb6bd
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
6 changed files with 94 additions and 52 deletions

View file

@ -656,6 +656,18 @@ impl<'a> CommentOrNewline<'a> {
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct PatternAs<'a> {
pub spaces_before: &'a [CommentOrNewline<'a>],
pub identifier: Loc<&'a str>,
}
impl<'a> PatternAs<'a> {
pub fn equivalent(&self, other: &Self) -> bool {
self.identifier.value == other.identifier.value
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Pattern<'a> {
// Identifier
@ -700,13 +712,9 @@ pub enum Pattern<'a> {
/// A list-rest pattern ".."
/// Can only occur inside of a [Pattern::List]
ListRest,
ListRest(Option<PatternAs<'a>>),
As(
&'a Loc<Pattern<'a>>,
&'a [CommentOrNewline<'a>],
Loc<&'a str>,
),
As(&'a Loc<Pattern<'a>>, PatternAs<'a>),
// Space
SpaceBefore(&'a Pattern<'a>, &'a [CommentOrNewline<'a>]),
@ -939,13 +947,23 @@ impl<'a> Pattern<'a> {
false
}
}
ListRest => matches!(other, ListRest),
As(pattern, _, identifier) => match other {
As(other_pattern, _, other_identifier) => {
identifier == other_identifier && pattern.value.equivalent(&other_pattern.value)
ListRest(pattern_as) => match other {
ListRest(other_pattern_as) => match (pattern_as, other_pattern_as) {
(Some(a), Some(b)) => a.equivalent(b),
_ => false,
},
_ => false,
},
As(pattern, pattern_as) => match other {
As(other_pattern, other_pattern_as) => {
pattern_as.equivalent(other_pattern_as)
&& pattern.value.equivalent(&other_pattern.value)
}
_ => false,
},
MalformedIdent(str_x, _) => {
if let MalformedIdent(str_y, _) = other {
str_x == str_y

View file

@ -1,4 +1,4 @@
use crate::ast::{CommentOrNewline, Has, Pattern, Spaceable};
use crate::ast::{Has, Pattern, PatternAs, Spaceable};
use crate::blankspace::{space0_before_e, space0_e};
use crate::ident::{lowercase_ident, parse_ident, Ident};
use crate::keyword;
@ -58,12 +58,12 @@ pub fn loc_pattern_help<'a>() -> impl Parser<'a, Loc<Pattern<'a>>, EPattern<'a>>
MadeProgress => Err((MadeProgress, e)),
NoProgress => Ok((MadeProgress, pattern, pattern_state)),
},
Ok((_, (spaces, identifier), state)) => {
let region = Region::span_across(&pattern.region, &identifier.region);
Ok((_, pattern_as, state)) => {
let region = Region::span_across(&pattern.region, &pattern_as.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);
let as_pattern = Pattern::As(arena.alloc(pattern), pattern_as);
Ok((MadeProgress, Loc::at(region, as_pattern), state))
}
@ -87,7 +87,7 @@ fn loc_pattern_help_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>> {
fn pattern_as<'a>() -> impl Parser<'a, PatternAs<'a>, EPattern<'a>> {
move |arena, state: State<'a>, min_indent| {
let (_, _, state) =
parser::keyword_e(keyword::AS, EPattern::As).parse(arena, state, min_indent)?;
@ -98,7 +98,14 @@ fn pattern_as<'a>() -> impl Parser<'a, (&'a [CommentOrNewline<'a>], Loc<&'a str>
let position = state.pos();
match loc!(lowercase_ident()).parse(arena, state, min_indent) {
Ok((_, identifier, state)) => Ok((MadeProgress, (spaces, identifier), state)),
Ok((_, identifier, state)) => Ok((
MadeProgress,
PatternAs {
spaces_before: spaces,
identifier,
},
state,
)),
Err((_, ())) => Err((MadeProgress, EPattern::AsIdentifier(position))),
}
}
@ -276,7 +283,7 @@ fn three_list_rest_pattern_error<'a>() -> impl Parser<'a, Loc<Pattern<'a>>, PLis
fn list_rest_pattern<'a>() -> impl Parser<'a, Loc<Pattern<'a>>, PList<'a>> {
map!(loc!(word2(b'.', b'.', PList::Open)), |loc_word: Loc<_>| {
loc_word.map(|_| Pattern::ListRest)
loc_word.map(|_| Pattern::ListRest(None))
})
}