mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +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::As(pattern, pattern_as) => pattern.is_multiline() || pattern_as.is_multiline(),
|
||||||
Pattern::ListRest (opt_pattern_as) => match opt_pattern_as {
|
Pattern::ListRest (opt_pattern_as) => match opt_pattern_as {
|
||||||
None => false,
|
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(_)
|
Pattern::Identifier(_)
|
||||||
|
@ -232,7 +232,10 @@ impl<'a> Formattable for Pattern<'a> {
|
||||||
buf.indent(indent);
|
buf.indent(indent);
|
||||||
buf.push_str("..");
|
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);
|
pattern_as.format(buf, indent + INDENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -712,7 +712,7 @@ pub enum Pattern<'a> {
|
||||||
|
|
||||||
/// A list-rest pattern ".."
|
/// A list-rest pattern ".."
|
||||||
/// Can only occur inside of a [Pattern::List]
|
/// 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>),
|
As(&'a Loc<Pattern<'a>>, PatternAs<'a>),
|
||||||
|
|
||||||
|
@ -950,7 +950,7 @@ impl<'a> Pattern<'a> {
|
||||||
|
|
||||||
ListRest(pattern_as) => match other {
|
ListRest(pattern_as) => match other {
|
||||||
ListRest(other_pattern_as) => match (pattern_as, other_pattern_as) {
|
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,
|
||||||
},
|
},
|
||||||
_ => false,
|
_ => false,
|
||||||
|
|
|
@ -555,9 +555,9 @@ pub enum EExpect<'a> {
|
||||||
pub enum EPattern<'a> {
|
pub enum EPattern<'a> {
|
||||||
Record(PRecord<'a>, Position),
|
Record(PRecord<'a>, Position),
|
||||||
List(PList<'a>, Position),
|
List(PList<'a>, Position),
|
||||||
Underscore(Position),
|
AsKeyword(Position),
|
||||||
As(Position),
|
|
||||||
AsIdentifier(Position),
|
AsIdentifier(Position),
|
||||||
|
Underscore(Position),
|
||||||
NotAPattern(Position),
|
NotAPattern(Position),
|
||||||
|
|
||||||
Start(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_state = state.clone();
|
||||||
|
|
||||||
let (pattern_spaces, state) = match space0_e(EPattern::As).parse(arena, state, min_indent) {
|
let (pattern_spaces, state) =
|
||||||
Err(_) => return Ok((MadeProgress, pattern, pattern_state)),
|
match space0_e(EPattern::AsKeyword).parse(arena, state, min_indent) {
|
||||||
Ok((_, pattern_spaces, state)) => (pattern_spaces, state),
|
Err(_) => return Ok((MadeProgress, pattern, pattern_state)),
|
||||||
};
|
Ok((_, pattern_spaces, state)) => (pattern_spaces, state),
|
||||||
|
};
|
||||||
|
|
||||||
match pattern_as().parse(arena, state, min_indent) {
|
match pattern_as().parse(arena, state, min_indent) {
|
||||||
Err((progress, e)) => match progress {
|
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>> {
|
fn pattern_as<'a>() -> impl Parser<'a, PatternAs<'a>, EPattern<'a>> {
|
||||||
move |arena, state: State<'a>, min_indent| {
|
move |arena, state: State<'a>, min_indent| {
|
||||||
let (_, _, state) =
|
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) =
|
let (_, spaces, state) =
|
||||||
space0_e(EPattern::AsIdentifier).parse(arena, state, min_indent)?;
|
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>> {
|
fn list_rest_pattern<'a>() -> impl Parser<'a, Loc<Pattern<'a>>, PList<'a>> {
|
||||||
map!(loc!(word2(b'.', b'.', PList::Open)), |loc_word: Loc<_>| {
|
move |arena: &'a Bump, state: State<'a>, min_indent: u32| {
|
||||||
loc_word.map(|_| Pattern::ListRest(None))
|
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>(
|
fn loc_ident_pattern_help<'a>(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue