mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 11:52:19 +00:00
add as
for list rest patterns
This commit is contained in:
parent
aff70bb6bd
commit
8305d078a0
4 changed files with 44 additions and 14 deletions
|
@ -60,7 +60,7 @@ impl<'a> Formattable for Pattern<'a> {
|
|||
Pattern::As(pattern, pattern_as) => pattern.is_multiline() || pattern_as.is_multiline(),
|
||||
Pattern::ListRest (opt_pattern_as) => match opt_pattern_as {
|
||||
None => false,
|
||||
Some(pattern_as) => pattern_as.is_multiline(),
|
||||
Some((list_rest_spaces, pattern_as)) => list_rest_spaces.iter().any(|s| s.is_comment()) || pattern_as.is_multiline(),
|
||||
},
|
||||
|
||||
Pattern::Identifier(_)
|
||||
|
@ -232,7 +232,10 @@ impl<'a> Formattable for Pattern<'a> {
|
|||
buf.indent(indent);
|
||||
buf.push_str("..");
|
||||
|
||||
if let Some(pattern_as) = opt_pattern_as {
|
||||
if let Some((list_rest_spaces, pattern_as)) = opt_pattern_as {
|
||||
// these spaces "belong" to the `..`, which can never be multiline
|
||||
fmt_comments_only(buf, list_rest_spaces.iter(), NewlineAt::Bottom, indent);
|
||||
|
||||
pattern_as.format(buf, indent + INDENT);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -712,7 +712,7 @@ pub enum Pattern<'a> {
|
|||
|
||||
/// A list-rest pattern ".."
|
||||
/// Can only occur inside of a [Pattern::List]
|
||||
ListRest(Option<PatternAs<'a>>),
|
||||
ListRest(Option<(&'a [CommentOrNewline<'a>], PatternAs<'a>)>),
|
||||
|
||||
As(&'a Loc<Pattern<'a>>, PatternAs<'a>),
|
||||
|
||||
|
@ -950,7 +950,7 @@ impl<'a> Pattern<'a> {
|
|||
|
||||
ListRest(pattern_as) => match other {
|
||||
ListRest(other_pattern_as) => match (pattern_as, other_pattern_as) {
|
||||
(Some(a), Some(b)) => a.equivalent(b),
|
||||
(Some((_, a)), Some((_, b))) => a.equivalent(b),
|
||||
_ => false,
|
||||
},
|
||||
_ => false,
|
||||
|
|
|
@ -555,9 +555,9 @@ pub enum EExpect<'a> {
|
|||
pub enum EPattern<'a> {
|
||||
Record(PRecord<'a>, Position),
|
||||
List(PList<'a>, Position),
|
||||
Underscore(Position),
|
||||
As(Position),
|
||||
AsKeyword(Position),
|
||||
AsIdentifier(Position),
|
||||
Underscore(Position),
|
||||
NotAPattern(Position),
|
||||
|
||||
Start(Position),
|
||||
|
|
|
@ -48,10 +48,11 @@ pub fn loc_pattern_help<'a>() -> impl Parser<'a, Loc<Pattern<'a>>, EPattern<'a>>
|
|||
|
||||
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),
|
||||
};
|
||||
let (pattern_spaces, state) =
|
||||
match space0_e(EPattern::AsKeyword).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 {
|
||||
|
@ -90,7 +91,7 @@ fn loc_pattern_help_help<'a>() -> impl Parser<'a, Loc<Pattern<'a>>, 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)?;
|
||||
parser::keyword_e(keyword::AS, EPattern::AsKeyword).parse(arena, state, min_indent)?;
|
||||
|
||||
let (_, spaces, state) =
|
||||
space0_e(EPattern::AsIdentifier).parse(arena, state, min_indent)?;
|
||||
|
@ -282,9 +283,35 @@ 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(None))
|
||||
})
|
||||
move |arena: &'a Bump, state: State<'a>, min_indent: u32| {
|
||||
let (_, loc_word, state) =
|
||||
loc!(word2(b'.', b'.', PList::Open)).parse(arena, state, min_indent)?;
|
||||
|
||||
let no_as = Loc::at(loc_word.region, Pattern::ListRest(None));
|
||||
|
||||
let pattern_state = state.clone();
|
||||
|
||||
let (pattern_spaces, state) =
|
||||
match space0_e(EPattern::AsKeyword).parse(arena, state, min_indent) {
|
||||
Err(_) => return Ok((MadeProgress, no_as, pattern_state)),
|
||||
Ok((_, pattern_spaces, state)) => (pattern_spaces, state),
|
||||
};
|
||||
|
||||
let position = state.pos();
|
||||
match pattern_as().parse(arena, state, min_indent) {
|
||||
Err((progress, e)) => match progress {
|
||||
MadeProgress => Err((MadeProgress, PList::Pattern(arena.alloc(e), position))),
|
||||
NoProgress => Ok((MadeProgress, no_as, pattern_state)),
|
||||
},
|
||||
Ok((_, pattern_as, state)) => {
|
||||
let region = Region::span_across(&loc_word.region, &pattern_as.identifier.region);
|
||||
|
||||
let as_pattern = Pattern::ListRest(Some((pattern_spaces, pattern_as)));
|
||||
|
||||
Ok((MadeProgress, Loc::at(region, as_pattern), state))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn loc_ident_pattern_help<'a>(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue