mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-21 15:59:20 +03:00
Merge pull request #4841 from roc-lang/parse-pattern-as
Parse pattern as
This commit is contained in:
commit
9171799c67
@ -449,7 +449,8 @@ pub fn to_pattern2<'a>(
|
|||||||
|
|
||||||
Tuple(..) => todo!(),
|
Tuple(..) => todo!(),
|
||||||
List(..) => todo!(),
|
List(..) => todo!(),
|
||||||
ListRest => todo!(),
|
ListRest(_) => todo!(),
|
||||||
|
As(_, _) => todo!(),
|
||||||
|
|
||||||
Malformed(_str) => {
|
Malformed(_str) => {
|
||||||
let problem = MalformedPatternProblem::Unknown;
|
let problem = MalformedPatternProblem::Unknown;
|
||||||
|
@ -689,7 +689,7 @@ pub fn canonicalize_pattern<'a>(
|
|||||||
|
|
||||||
for (i, loc_pattern) in patterns.iter().enumerate() {
|
for (i, loc_pattern) in patterns.iter().enumerate() {
|
||||||
match &loc_pattern.value {
|
match &loc_pattern.value {
|
||||||
ListRest => match rest_index {
|
ListRest(_opt_pattern_as) => match rest_index {
|
||||||
None => {
|
None => {
|
||||||
rest_index = Some(i);
|
rest_index = Some(i);
|
||||||
}
|
}
|
||||||
@ -731,13 +731,17 @@ pub fn canonicalize_pattern<'a>(
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
ListRest => {
|
ListRest(_opt_pattern_as) => {
|
||||||
// Parsing should make sure these only appear in list patterns, where we will generate
|
// Parsing should make sure these only appear in list patterns, where we will generate
|
||||||
// better contextual errors.
|
// better contextual errors.
|
||||||
let problem = MalformedPatternProblem::Unknown;
|
let problem = MalformedPatternProblem::Unknown;
|
||||||
malformed_pattern(env, problem, region)
|
malformed_pattern(env, problem, region)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
As(_pattern, _pattern_as) => {
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
|
||||||
Malformed(_str) => {
|
Malformed(_str) => {
|
||||||
let problem = MalformedPatternProblem::Unknown;
|
let problem = MalformedPatternProblem::Unknown;
|
||||||
malformed_pattern(env, problem, region)
|
malformed_pattern(env, problem, region)
|
||||||
|
@ -69,7 +69,11 @@ impl<'a> Buf<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_str_allow_spaces(&mut self, s: &str) {
|
pub fn push_str_allow_spaces(&mut self, s: &str) {
|
||||||
debug_assert!(!self.beginning_of_line);
|
debug_assert!(
|
||||||
|
!self.beginning_of_line,
|
||||||
|
"push_str: `{s}` with text:\n{}",
|
||||||
|
self.text
|
||||||
|
);
|
||||||
|
|
||||||
self.flush_spaces();
|
self.flush_spaces();
|
||||||
|
|
||||||
@ -77,8 +81,13 @@ impl<'a> Buf<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_str(&mut self, s: &str) {
|
pub fn push_str(&mut self, s: &str) {
|
||||||
debug_assert!(!self.beginning_of_line);
|
debug_assert!(
|
||||||
debug_assert!(!s.contains('\n') && !s.ends_with(' '));
|
!self.beginning_of_line,
|
||||||
|
"push_str: `{s}` with text:\n{}",
|
||||||
|
self.text
|
||||||
|
);
|
||||||
|
debug_assert!(!s.contains('\n'));
|
||||||
|
debug_assert!(!s.ends_with(' '));
|
||||||
|
|
||||||
if !s.is_empty() {
|
if !s.is_empty() {
|
||||||
self.flush_spaces();
|
self.flush_spaces();
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use crate::annotation::{Formattable, Newlines, Parens};
|
use crate::annotation::{Formattable, Newlines, Parens};
|
||||||
use crate::expr::{fmt_str_literal, format_sq_literal};
|
use crate::expr::{fmt_str_literal, format_sq_literal};
|
||||||
use crate::spaces::{fmt_comments_only, fmt_spaces, NewlineAt};
|
use crate::spaces::{fmt_comments_only, fmt_spaces, NewlineAt, INDENT};
|
||||||
use crate::Buf;
|
use crate::Buf;
|
||||||
use roc_parse::ast::{Base, CommentOrNewline, Pattern};
|
use roc_parse::ast::{Base, CommentOrNewline, Pattern, PatternAs};
|
||||||
|
|
||||||
pub fn fmt_pattern<'a, 'buf>(
|
pub fn fmt_pattern<'a, 'buf>(
|
||||||
buf: &mut Buf<'buf>,
|
buf: &mut Buf<'buf>,
|
||||||
@ -13,6 +13,35 @@ pub fn fmt_pattern<'a, 'buf>(
|
|||||||
pattern.format_with_options(buf, parens, Newlines::No, indent);
|
pattern.format_with_options(buf, parens, Newlines::No, indent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Formattable for PatternAs<'a> {
|
||||||
|
fn is_multiline(&self) -> bool {
|
||||||
|
self.spaces_before.iter().any(|s| s.is_comment())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format_with_options<'buf>(
|
||||||
|
&self,
|
||||||
|
buf: &mut Buf<'buf>,
|
||||||
|
_parens: Parens,
|
||||||
|
_newlines: Newlines,
|
||||||
|
indent: u16,
|
||||||
|
) {
|
||||||
|
buf.indent(indent);
|
||||||
|
|
||||||
|
if !buf.ends_with_space() {
|
||||||
|
buf.spaces(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.push_str("as");
|
||||||
|
buf.spaces(1);
|
||||||
|
|
||||||
|
// these spaces "belong" to the identifier, which can never be multiline
|
||||||
|
fmt_comments_only(buf, self.spaces_before.iter(), NewlineAt::Bottom, indent);
|
||||||
|
|
||||||
|
buf.indent(indent);
|
||||||
|
buf.push_str(self.identifier.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> Formattable for Pattern<'a> {
|
impl<'a> Formattable for Pattern<'a> {
|
||||||
fn is_multiline(&self) -> bool {
|
fn is_multiline(&self) -> bool {
|
||||||
// Theory: a pattern should only be multiline when it contains a comment
|
// Theory: a pattern should only be multiline when it contains a comment
|
||||||
@ -28,6 +57,14 @@ impl<'a> Formattable for Pattern<'a> {
|
|||||||
|
|
||||||
Pattern::OptionalField(_, expr) => expr.is_multiline(),
|
Pattern::OptionalField(_, expr) => expr.is_multiline(),
|
||||||
|
|
||||||
|
Pattern::As(pattern, pattern_as) => pattern.is_multiline() || pattern_as.is_multiline(),
|
||||||
|
Pattern::ListRest(opt_pattern_as) => match opt_pattern_as {
|
||||||
|
None => false,
|
||||||
|
Some((list_rest_spaces, pattern_as)) => {
|
||||||
|
list_rest_spaces.iter().any(|s| s.is_comment()) || pattern_as.is_multiline()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
Pattern::Identifier(_)
|
Pattern::Identifier(_)
|
||||||
| Pattern::Tag(_)
|
| Pattern::Tag(_)
|
||||||
| Pattern::OpaqueRef(_)
|
| Pattern::OpaqueRef(_)
|
||||||
@ -40,8 +77,7 @@ impl<'a> Formattable for Pattern<'a> {
|
|||||||
| Pattern::Underscore(_)
|
| Pattern::Underscore(_)
|
||||||
| Pattern::Malformed(_)
|
| Pattern::Malformed(_)
|
||||||
| Pattern::MalformedIdent(_, _)
|
| Pattern::MalformedIdent(_, _)
|
||||||
| Pattern::QualifiedIdentifier { .. }
|
| Pattern::QualifiedIdentifier { .. } => false,
|
||||||
| Pattern::ListRest => false,
|
|
||||||
|
|
||||||
Pattern::Tuple(patterns) | Pattern::List(patterns) => {
|
Pattern::Tuple(patterns) | Pattern::List(patterns) => {
|
||||||
patterns.iter().any(|p| p.is_multiline())
|
patterns.iter().any(|p| p.is_multiline())
|
||||||
@ -194,9 +230,22 @@ impl<'a> Formattable for Pattern<'a> {
|
|||||||
|
|
||||||
buf.push_str("]");
|
buf.push_str("]");
|
||||||
}
|
}
|
||||||
ListRest => {
|
ListRest(opt_pattern_as) => {
|
||||||
buf.indent(indent);
|
buf.indent(indent);
|
||||||
buf.push_str("..");
|
buf.push_str("..");
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
As(pattern, pattern_as) => {
|
||||||
|
fmt_pattern(buf, &pattern.value, indent, parens);
|
||||||
|
|
||||||
|
pattern_as.format(buf, indent + INDENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Space
|
// Space
|
||||||
|
@ -766,6 +766,9 @@ impl<'a> RemoveSpaces<'a> for Pattern<'a> {
|
|||||||
Pattern::OptionalField(a, b) => {
|
Pattern::OptionalField(a, b) => {
|
||||||
Pattern::OptionalField(a, arena.alloc(b.remove_spaces(arena)))
|
Pattern::OptionalField(a, arena.alloc(b.remove_spaces(arena)))
|
||||||
}
|
}
|
||||||
|
Pattern::As(pattern, pattern_as) => {
|
||||||
|
Pattern::As(arena.alloc(pattern.remove_spaces(arena)), pattern_as)
|
||||||
|
}
|
||||||
Pattern::NumLiteral(a) => Pattern::NumLiteral(a),
|
Pattern::NumLiteral(a) => Pattern::NumLiteral(a),
|
||||||
Pattern::NonBase10Literal {
|
Pattern::NonBase10Literal {
|
||||||
string,
|
string,
|
||||||
@ -789,7 +792,7 @@ impl<'a> RemoveSpaces<'a> for Pattern<'a> {
|
|||||||
Pattern::SingleQuote(a) => Pattern::SingleQuote(a),
|
Pattern::SingleQuote(a) => Pattern::SingleQuote(a),
|
||||||
Pattern::List(pats) => Pattern::List(pats.remove_spaces(arena)),
|
Pattern::List(pats) => Pattern::List(pats.remove_spaces(arena)),
|
||||||
Pattern::Tuple(pats) => Pattern::Tuple(pats.remove_spaces(arena)),
|
Pattern::Tuple(pats) => Pattern::Tuple(pats.remove_spaces(arena)),
|
||||||
Pattern::ListRest => Pattern::ListRest,
|
Pattern::ListRest(opt_pattern_as) => Pattern::ListRest(opt_pattern_as),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
pub enum Pattern<'a> {
|
pub enum Pattern<'a> {
|
||||||
// Identifier
|
// Identifier
|
||||||
@ -700,7 +712,9 @@ 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,
|
ListRest(Option<(&'a [CommentOrNewline<'a>], PatternAs<'a>)>),
|
||||||
|
|
||||||
|
As(&'a Loc<Pattern<'a>>, PatternAs<'a>),
|
||||||
|
|
||||||
// Space
|
// Space
|
||||||
SpaceBefore(&'a Pattern<'a>, &'a [CommentOrNewline<'a>]),
|
SpaceBefore(&'a Pattern<'a>, &'a [CommentOrNewline<'a>]),
|
||||||
@ -933,7 +947,23 @@ impl<'a> Pattern<'a> {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ListRest => matches!(other, ListRest),
|
|
||||||
|
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, _) => {
|
MalformedIdent(str_x, _) => {
|
||||||
if let MalformedIdent(str_y, _) = other {
|
if let MalformedIdent(str_y, _) = other {
|
||||||
str_x == str_y
|
str_x == str_y
|
||||||
|
@ -555,6 +555,8 @@ 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),
|
||||||
|
AsKeyword(Position),
|
||||||
|
AsIdentifier(Position),
|
||||||
Underscore(Position),
|
Underscore(Position),
|
||||||
NotAPattern(Position),
|
NotAPattern(Position),
|
||||||
|
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
use crate::ast::{Has, Pattern};
|
use crate::ast::{Has, Pattern, PatternAs, Spaceable};
|
||||||
use crate::blankspace::{space0_before_e, space0_e};
|
use crate::blankspace::{space0_before_e, space0_e};
|
||||||
use crate::ident::{lowercase_ident, parse_ident, Ident};
|
use crate::ident::{lowercase_ident, parse_ident, Ident};
|
||||||
|
use crate::keyword;
|
||||||
use crate::parser::Progress::{self, *};
|
use crate::parser::Progress::{self, *};
|
||||||
use crate::parser::{
|
use crate::parser::{
|
||||||
backtrackable, fail_when, optional, specialize, specialize_ref, then, word1, word2, word3,
|
self, backtrackable, fail_when, optional, specialize, specialize_ref, then, word1, word2,
|
||||||
EPattern, PInParens, PList, PRecord, Parser,
|
word3, EPattern, PInParens, PList, PRecord, Parser,
|
||||||
};
|
};
|
||||||
use crate::state::State;
|
use crate::state::State;
|
||||||
use bumpalo::collections::string::String;
|
use bumpalo::collections::string::String;
|
||||||
@ -42,6 +43,36 @@ 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>> {
|
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::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 {
|
||||||
|
MadeProgress => Err((MadeProgress, e)),
|
||||||
|
NoProgress => Ok((MadeProgress, pattern, pattern_state)),
|
||||||
|
},
|
||||||
|
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), pattern_as);
|
||||||
|
|
||||||
|
Ok((MadeProgress, Loc::at(region, as_pattern), state))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn loc_pattern_help_help<'a>() -> impl Parser<'a, Loc<Pattern<'a>>, EPattern<'a>> {
|
||||||
one_of!(
|
one_of!(
|
||||||
specialize(EPattern::PInParens, loc_pattern_in_parens_help()),
|
specialize(EPattern::PInParens, loc_pattern_in_parens_help()),
|
||||||
loc!(underscore_pattern_help()),
|
loc!(underscore_pattern_help()),
|
||||||
@ -57,6 +88,30 @@ pub fn loc_pattern_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::AsKeyword).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,
|
||||||
|
PatternAs {
|
||||||
|
spaces_before: 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>> {
|
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))
|
zero_or_more!(loc_tag_pattern_arg(false))
|
||||||
}
|
}
|
||||||
@ -228,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)
|
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>(
|
||||||
|
@ -24,7 +24,9 @@ When(
|
|||||||
@24-28 SpaceBefore(
|
@24-28 SpaceBefore(
|
||||||
List(
|
List(
|
||||||
[
|
[
|
||||||
@25-27 ListRest,
|
@25-27 ListRest(
|
||||||
|
None,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
[
|
[
|
||||||
@ -45,11 +47,15 @@ When(
|
|||||||
@38-39 Underscore(
|
@38-39 Underscore(
|
||||||
"",
|
"",
|
||||||
),
|
),
|
||||||
@41-43 ListRest,
|
@41-43 ListRest(
|
||||||
|
None,
|
||||||
|
),
|
||||||
@45-46 Underscore(
|
@45-46 Underscore(
|
||||||
"",
|
"",
|
||||||
),
|
),
|
||||||
@48-50 ListRest,
|
@48-50 ListRest(
|
||||||
|
None,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
[
|
[
|
||||||
@ -102,7 +108,9 @@ When(
|
|||||||
@85-86 Identifier(
|
@85-86 Identifier(
|
||||||
"b",
|
"b",
|
||||||
),
|
),
|
||||||
@88-90 ListRest,
|
@88-90 ListRest(
|
||||||
|
None,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
[
|
[
|
||||||
@ -120,7 +128,9 @@ When(
|
|||||||
@100-110 SpaceBefore(
|
@100-110 SpaceBefore(
|
||||||
List(
|
List(
|
||||||
[
|
[
|
||||||
@101-103 ListRest,
|
@101-103 ListRest(
|
||||||
|
None,
|
||||||
|
),
|
||||||
@105-106 Identifier(
|
@105-106 Identifier(
|
||||||
"c",
|
"c",
|
||||||
),
|
),
|
||||||
@ -153,7 +163,9 @@ When(
|
|||||||
),
|
),
|
||||||
@125-129 List(
|
@125-129 List(
|
||||||
[
|
[
|
||||||
@126-128 ListRest,
|
@126-128 ListRest(
|
||||||
|
None,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@131-134 List(
|
@131-134 List(
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
When(
|
||||||
|
@5-6 Num(
|
||||||
|
"0",
|
||||||
|
),
|
||||||
|
[
|
||||||
|
WhenBranch {
|
||||||
|
patterns: [
|
||||||
|
@14-20 SpaceBefore(
|
||||||
|
As(
|
||||||
|
@14-15 SpaceAfter(
|
||||||
|
Underscore(
|
||||||
|
"",
|
||||||
|
),
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
PatternAs {
|
||||||
|
spaces_before: [],
|
||||||
|
identifier: @19-20 "n",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
[
|
||||||
|
Newline,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
value: @24-25 Var {
|
||||||
|
module_name: "",
|
||||||
|
ident: "n",
|
||||||
|
},
|
||||||
|
guard: None,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
)
|
@ -0,0 +1,2 @@
|
|||||||
|
when 0 is
|
||||||
|
_ as n -> n
|
@ -0,0 +1,39 @@
|
|||||||
|
When(
|
||||||
|
@5-11 Var {
|
||||||
|
module_name: "",
|
||||||
|
ident: "myList",
|
||||||
|
},
|
||||||
|
[
|
||||||
|
WhenBranch {
|
||||||
|
patterns: [
|
||||||
|
@19-38 SpaceBefore(
|
||||||
|
List(
|
||||||
|
[
|
||||||
|
@20-25 Identifier(
|
||||||
|
"first",
|
||||||
|
),
|
||||||
|
@27-37 ListRest(
|
||||||
|
Some(
|
||||||
|
(
|
||||||
|
[],
|
||||||
|
PatternAs {
|
||||||
|
spaces_before: [],
|
||||||
|
identifier: @33-37 "rest",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
[
|
||||||
|
Newline,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
value: @42-43 Num(
|
||||||
|
"0",
|
||||||
|
),
|
||||||
|
guard: None,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
)
|
@ -0,0 +1,2 @@
|
|||||||
|
when myList is
|
||||||
|
[first, .. as rest] -> 0
|
@ -0,0 +1,40 @@
|
|||||||
|
When(
|
||||||
|
@5-6 Num(
|
||||||
|
"0",
|
||||||
|
),
|
||||||
|
[
|
||||||
|
WhenBranch {
|
||||||
|
patterns: [
|
||||||
|
@14-54 SpaceBefore(
|
||||||
|
As(
|
||||||
|
@14-15 SpaceAfter(
|
||||||
|
NumLiteral(
|
||||||
|
"0",
|
||||||
|
),
|
||||||
|
[
|
||||||
|
LineComment(
|
||||||
|
" foobar",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
PatternAs {
|
||||||
|
spaces_before: [
|
||||||
|
LineComment(
|
||||||
|
" barfoo",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
identifier: @53-54 "n",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
[
|
||||||
|
Newline,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
value: @58-60 Record(
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
guard: None,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
)
|
@ -0,0 +1,4 @@
|
|||||||
|
when 0 is
|
||||||
|
0 # foobar
|
||||||
|
as # barfoo
|
||||||
|
n -> {}
|
@ -354,6 +354,9 @@ mod test_snapshots {
|
|||||||
pass/parenthetical_var.expr,
|
pass/parenthetical_var.expr,
|
||||||
pass/parse_alias.expr,
|
pass/parse_alias.expr,
|
||||||
pass/parse_as_ann.expr,
|
pass/parse_as_ann.expr,
|
||||||
|
pass/pattern_as.expr,
|
||||||
|
pass/pattern_as_list_rest.expr,
|
||||||
|
pass/pattern_as_spaces.expr,
|
||||||
pass/pattern_with_space_in_parens.expr, // https://github.com/roc-lang/roc/issues/929
|
pass/pattern_with_space_in_parens.expr, // https://github.com/roc-lang/roc/issues/929
|
||||||
pass/plus_if.expr,
|
pass/plus_if.expr,
|
||||||
pass/plus_when.expr,
|
pass/plus_when.expr,
|
||||||
|
Loading…
Reference in New Issue
Block a user