1848: Parse `..` as a full pattern r=matklad a=ecstatic-morse

Resolves #1479.

This PR implements [RFC 2707](https://github.com/rust-lang/rfcs/pull/2707) in the parser. It introduces a new `DotDotPat` AST node modeled on `PlaceholderPat` and changes the parsing of tuple and slice patterns to conform to the RFC.

Notably, this PR does *not* change the resulting AST when `..` appears in a struct pattern (e.g. `Struct { a, b: c, .. }`). I *think* this is the behavior mandated by RFC 2707, but someone should confirm this.

Co-authored-by: Dylan MacKenzie <ecstaticmorse@gmail.com>
This commit is contained in:
bors[bot] 2019-09-15 07:10:16 +00:00 committed by GitHub
commit 2d79a1ad83
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 573 additions and 17 deletions

View file

@ -573,6 +573,7 @@ where
}
// FIXME: implement
ast::Pat::DotDotPat(_) => Pat::Missing,
ast::Pat::BoxPat(_) => Pat::Missing,
ast::Pat::LiteralPat(_) => Pat::Missing,
ast::Pat::SlicePat(_) | ast::Pat::RangePat(_) => Pat::Missing,

View file

@ -2,7 +2,7 @@ use super::*;
pub(super) const PATTERN_FIRST: TokenSet = expressions::LITERAL_FIRST
.union(paths::PATH_FIRST)
.union(token_set![BOX_KW, REF_KW, MUT_KW, L_PAREN, L_BRACK, AMP, UNDERSCORE, MINUS]);
.union(token_set![BOX_KW, REF_KW, MUT_KW, L_PAREN, L_BRACK, AMP, UNDERSCORE, MINUS, DOT]);
pub(crate) fn pattern(p: &mut Parser) {
pattern_r(p, PAT_RECOVERY_SET);
@ -73,6 +73,7 @@ fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option<CompletedMarker> {
_ if paths::is_use_path_start(p) => path_pat(p),
_ if is_literal_pat_start(p) => literal_pat(p),
T![.] if p.at(T![..]) => dot_dot_pat(p),
T![_] => placeholder_pat(p),
T![&] => ref_pat(p),
T!['('] => tuple_pat(p),
@ -163,7 +164,9 @@ fn record_field_pat_list(p: &mut Parser) {
p.bump_any();
while !p.at(EOF) && !p.at(T!['}']) {
match p.current() {
// A trailing `..` is *not* treated as a DOT_DOT_PAT.
T![.] if p.at(T![..]) => p.bump(T![..]),
IDENT if p.nth(1) == T![:] => record_field_pat(p),
T!['{'] => error_block(p, "expected ident"),
T![box] => {
@ -201,6 +204,39 @@ fn placeholder_pat(p: &mut Parser) -> CompletedMarker {
m.complete(p, PLACEHOLDER_PAT)
}
// test dot_dot_pat
// fn main() {
// let .. = ();
// //
// // Tuples
// //
// let (a, ..) = ();
// let (a, ..,) = ();
// let Tuple(a, ..) = ();
// let Tuple(a, ..,) = ();
// let (.., ..) = ();
// let Tuple(.., ..) = ();
// let (.., a, ..) = ();
// let Tuple(.., a, ..) = ();
// //
// // Slices
// //
// let [..] = ();
// let [head, ..] = ();
// let [head, tail @ ..] = ();
// let [head, .., cons] = ();
// let [head, mid @ .., cons] = ();
// let [head, .., .., cons] = ();
// let [head, .., mid, tail @ ..] = ();
// let [head, .., mid, .., cons] = ();
// }
fn dot_dot_pat(p: &mut Parser) -> CompletedMarker {
assert!(p.at(T![..]));
let m = p.start();
p.bump(T![..]);
m.complete(p, DOT_DOT_PAT)
}
// test ref_pat
// fn main() {
// let &a = ();
@ -241,16 +277,12 @@ fn slice_pat(p: &mut Parser) -> CompletedMarker {
fn pat_list(p: &mut Parser, ket: SyntaxKind) {
while !p.at(EOF) && !p.at(ket) {
match p.current() {
T![.] if p.at(T![..]) => p.bump(T![..]),
_ => {
if !p.at_ts(PATTERN_FIRST) {
p.error("expected a pattern");
break;
}
pattern(p)
}
if !p.at_ts(PATTERN_FIRST) {
p.error("expected a pattern");
break;
}
pattern(p);
if !p.at(ket) {
p.expect(T![,]);
}

View file

@ -152,6 +152,7 @@ pub enum SyntaxKind {
BOX_PAT,
BIND_PAT,
PLACEHOLDER_PAT,
DOT_DOT_PAT,
PATH_PAT,
RECORD_PAT,
RECORD_FIELD_PAT_LIST,

View file

@ -532,6 +532,29 @@ impl AstNode for ContinueExpr {
}
impl ContinueExpr {}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct DotDotPat {
pub(crate) syntax: SyntaxNode,
}
impl AstNode for DotDotPat {
fn can_cast(kind: SyntaxKind) -> bool {
match kind {
DOT_DOT_PAT => true,
_ => false,
}
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
if Self::can_cast(syntax.kind()) {
Some(Self { syntax })
} else {
None
}
}
fn syntax(&self) -> &SyntaxNode {
&self.syntax
}
}
impl DotDotPat {}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct DynTraitType {
pub(crate) syntax: SyntaxNode,
}
@ -2128,6 +2151,7 @@ pub enum Pat {
BoxPat(BoxPat),
BindPat(BindPat),
PlaceholderPat(PlaceholderPat),
DotDotPat(DotDotPat),
PathPat(PathPat),
RecordPat(RecordPat),
TupleStructPat(TupleStructPat),
@ -2156,6 +2180,11 @@ impl From<PlaceholderPat> for Pat {
Pat::PlaceholderPat(node)
}
}
impl From<DotDotPat> for Pat {
fn from(node: DotDotPat) -> Pat {
Pat::DotDotPat(node)
}
}
impl From<PathPat> for Pat {
fn from(node: PathPat) -> Pat {
Pat::PathPat(node)
@ -2194,8 +2223,10 @@ impl From<LiteralPat> for Pat {
impl AstNode for Pat {
fn can_cast(kind: SyntaxKind) -> bool {
match kind {
REF_PAT | BOX_PAT | BIND_PAT | PLACEHOLDER_PAT | PATH_PAT | RECORD_PAT
| TUPLE_STRUCT_PAT | TUPLE_PAT | SLICE_PAT | RANGE_PAT | LITERAL_PAT => true,
REF_PAT | BOX_PAT | BIND_PAT | PLACEHOLDER_PAT | DOT_DOT_PAT | PATH_PAT
| RECORD_PAT | TUPLE_STRUCT_PAT | TUPLE_PAT | SLICE_PAT | RANGE_PAT | LITERAL_PAT => {
true
}
_ => false,
}
}
@ -2205,6 +2236,7 @@ impl AstNode for Pat {
BOX_PAT => Pat::BoxPat(BoxPat { syntax }),
BIND_PAT => Pat::BindPat(BindPat { syntax }),
PLACEHOLDER_PAT => Pat::PlaceholderPat(PlaceholderPat { syntax }),
DOT_DOT_PAT => Pat::DotDotPat(DotDotPat { syntax }),
PATH_PAT => Pat::PathPat(PathPat { syntax }),
RECORD_PAT => Pat::RecordPat(RecordPat { syntax }),
TUPLE_STRUCT_PAT => Pat::TupleStructPat(TupleStructPat { syntax }),
@ -2222,6 +2254,7 @@ impl AstNode for Pat {
Pat::BoxPat(it) => &it.syntax,
Pat::BindPat(it) => &it.syntax,
Pat::PlaceholderPat(it) => &it.syntax,
Pat::DotDotPat(it) => &it.syntax,
Pat::PathPat(it) => &it.syntax,
Pat::RecordPat(it) => &it.syntax,
Pat::TupleStructPat(it) => &it.syntax,

View file

@ -161,6 +161,7 @@ Grammar(
"BOX_PAT",
"BIND_PAT",
"PLACEHOLDER_PAT",
"DOT_DOT_PAT",
"PATH_PAT",
"RECORD_PAT",
"RECORD_FIELD_PAT_LIST",
@ -532,6 +533,7 @@ Grammar(
traits: ["NameOwner"]
),
"PlaceholderPat": (),
"DotDotPat": (),
"PathPat": ( options: [ "Path" ] ),
"RecordPat": ( options: ["RecordFieldPatList", "Path"] ),
"RecordFieldPatList": (
@ -559,6 +561,7 @@ Grammar(
"BoxPat",
"BindPat",
"PlaceholderPat",
"DotDotPat",
"PathPat",
"RecordPat",
"TupleStructPat",

View file

@ -82,7 +82,8 @@ SOURCE_FILE@[0; 103)
NAME_REF@[87; 90)
IDENT@[87; 90) "Bar"
L_PAREN@[90; 91) "("
DOTDOT@[91; 93) ".."
DOT_DOT_PAT@[91; 93)
DOTDOT@[91; 93) ".."
R_PAREN@[93; 94) ")"
WHITESPACE@[94; 95) " "
EQ@[95; 96) "="

View file

@ -27,7 +27,8 @@ SOURCE_FILE@[0; 39)
IDENT@[24; 25) "b"
COMMA@[25; 26) ","
WHITESPACE@[26; 27) " "
DOTDOT@[27; 29) ".."
DOT_DOT_PAT@[27; 29)
DOTDOT@[27; 29) ".."
R_BRACK@[29; 30) "]"
WHITESPACE@[30; 31) " "
EQ@[31; 32) "="

View file

@ -84,7 +84,8 @@ SOURCE_FILE@[0; 97)
UNDERSCORE@[78; 79) "_"
COMMA@[79; 80) ","
WHITESPACE@[80; 81) " "
DOTDOT@[81; 83) ".."
DOT_DOT_PAT@[81; 83)
DOTDOT@[81; 83) ".."
WHITESPACE@[83; 84) " "
COMMA@[84; 85) ","
WHITESPACE@[85; 86) " "

View file

@ -27,7 +27,8 @@ SOURCE_FILE@[0; 39)
IDENT@[24; 25) "b"
COMMA@[25; 26) ","
WHITESPACE@[26; 27) " "
DOTDOT@[27; 29) ".."
DOT_DOT_PAT@[27; 29)
DOTDOT@[27; 29) ".."
R_PAREN@[29; 30) ")"
WHITESPACE@[30; 31) " "
EQ@[31; 32) "="

View file

@ -0,0 +1,25 @@
fn main() {
let .. = ();
//
// Tuples
//
let (a, ..) = ();
let (a, ..,) = ();
let Tuple(a, ..) = ();
let Tuple(a, ..,) = ();
let (.., ..) = ();
let Tuple(.., ..) = ();
let (.., a, ..) = ();
let Tuple(.., a, ..) = ();
//
// Slices
//
let [..] = ();
let [head, ..] = ();
let [head, tail @ ..] = ();
let [head, .., cons] = ();
let [head, mid @ .., cons] = ();
let [head, .., .., cons] = ();
let [head, .., mid, tail @ ..] = ();
let [head, .., mid, .., cons] = ();
}

View file

@ -0,0 +1,456 @@
SOURCE_FILE@[0; 555)
FN_DEF@[0; 554)
FN_KW@[0; 2) "fn"
WHITESPACE@[2; 3) " "
NAME@[3; 7)
IDENT@[3; 7) "main"
PARAM_LIST@[7; 9)
L_PAREN@[7; 8) "("
R_PAREN@[8; 9) ")"
WHITESPACE@[9; 10) " "
BLOCK_EXPR@[10; 554)
BLOCK@[10; 554)
L_CURLY@[10; 11) "{"
WHITESPACE@[11; 16) "\n "
LET_STMT@[16; 28)
LET_KW@[16; 19) "let"
WHITESPACE@[19; 20) " "
DOT_DOT_PAT@[20; 22)
DOTDOT@[20; 22) ".."
WHITESPACE@[22; 23) " "
EQ@[23; 24) "="
WHITESPACE@[24; 25) " "
TUPLE_EXPR@[25; 27)
L_PAREN@[25; 26) "("
R_PAREN@[26; 27) ")"
SEMI@[27; 28) ";"
WHITESPACE@[28; 33) "\n "
COMMENT@[33; 35) "//"
WHITESPACE@[35; 40) "\n "
COMMENT@[40; 49) "// Tuples"
WHITESPACE@[49; 54) "\n "
COMMENT@[54; 56) "//"
WHITESPACE@[56; 61) "\n "
LET_STMT@[61; 78)
LET_KW@[61; 64) "let"
WHITESPACE@[64; 65) " "
TUPLE_PAT@[65; 72)
L_PAREN@[65; 66) "("
BIND_PAT@[66; 67)
NAME@[66; 67)
IDENT@[66; 67) "a"
COMMA@[67; 68) ","
WHITESPACE@[68; 69) " "
DOT_DOT_PAT@[69; 71)
DOTDOT@[69; 71) ".."
R_PAREN@[71; 72) ")"
WHITESPACE@[72; 73) " "
EQ@[73; 74) "="
WHITESPACE@[74; 75) " "
TUPLE_EXPR@[75; 77)
L_PAREN@[75; 76) "("
R_PAREN@[76; 77) ")"
SEMI@[77; 78) ";"
WHITESPACE@[78; 83) "\n "
LET_STMT@[83; 101)
LET_KW@[83; 86) "let"
WHITESPACE@[86; 87) " "
TUPLE_PAT@[87; 95)
L_PAREN@[87; 88) "("
BIND_PAT@[88; 89)
NAME@[88; 89)
IDENT@[88; 89) "a"
COMMA@[89; 90) ","
WHITESPACE@[90; 91) " "
DOT_DOT_PAT@[91; 93)
DOTDOT@[91; 93) ".."
COMMA@[93; 94) ","
R_PAREN@[94; 95) ")"
WHITESPACE@[95; 96) " "
EQ@[96; 97) "="
WHITESPACE@[97; 98) " "
TUPLE_EXPR@[98; 100)
L_PAREN@[98; 99) "("
R_PAREN@[99; 100) ")"
SEMI@[100; 101) ";"
WHITESPACE@[101; 106) "\n "
LET_STMT@[106; 128)
LET_KW@[106; 109) "let"
WHITESPACE@[109; 110) " "
TUPLE_STRUCT_PAT@[110; 122)
PATH@[110; 115)
PATH_SEGMENT@[110; 115)
NAME_REF@[110; 115)
IDENT@[110; 115) "Tuple"
L_PAREN@[115; 116) "("
BIND_PAT@[116; 117)
NAME@[116; 117)
IDENT@[116; 117) "a"
COMMA@[117; 118) ","
WHITESPACE@[118; 119) " "
DOT_DOT_PAT@[119; 121)
DOTDOT@[119; 121) ".."
R_PAREN@[121; 122) ")"
WHITESPACE@[122; 123) " "
EQ@[123; 124) "="
WHITESPACE@[124; 125) " "
TUPLE_EXPR@[125; 127)
L_PAREN@[125; 126) "("
R_PAREN@[126; 127) ")"
SEMI@[127; 128) ";"
WHITESPACE@[128; 133) "\n "
LET_STMT@[133; 156)
LET_KW@[133; 136) "let"
WHITESPACE@[136; 137) " "
TUPLE_STRUCT_PAT@[137; 150)
PATH@[137; 142)
PATH_SEGMENT@[137; 142)
NAME_REF@[137; 142)
IDENT@[137; 142) "Tuple"
L_PAREN@[142; 143) "("
BIND_PAT@[143; 144)
NAME@[143; 144)
IDENT@[143; 144) "a"
COMMA@[144; 145) ","
WHITESPACE@[145; 146) " "
DOT_DOT_PAT@[146; 148)
DOTDOT@[146; 148) ".."
COMMA@[148; 149) ","
R_PAREN@[149; 150) ")"
WHITESPACE@[150; 151) " "
EQ@[151; 152) "="
WHITESPACE@[152; 153) " "
TUPLE_EXPR@[153; 155)
L_PAREN@[153; 154) "("
R_PAREN@[154; 155) ")"
SEMI@[155; 156) ";"
WHITESPACE@[156; 161) "\n "
LET_STMT@[161; 179)
LET_KW@[161; 164) "let"
WHITESPACE@[164; 165) " "
TUPLE_PAT@[165; 173)
L_PAREN@[165; 166) "("
DOT_DOT_PAT@[166; 168)
DOTDOT@[166; 168) ".."
COMMA@[168; 169) ","
WHITESPACE@[169; 170) " "
DOT_DOT_PAT@[170; 172)
DOTDOT@[170; 172) ".."
R_PAREN@[172; 173) ")"
WHITESPACE@[173; 174) " "
EQ@[174; 175) "="
WHITESPACE@[175; 176) " "
TUPLE_EXPR@[176; 178)
L_PAREN@[176; 177) "("
R_PAREN@[177; 178) ")"
SEMI@[178; 179) ";"
WHITESPACE@[179; 184) "\n "
LET_STMT@[184; 207)
LET_KW@[184; 187) "let"
WHITESPACE@[187; 188) " "
TUPLE_STRUCT_PAT@[188; 201)
PATH@[188; 193)
PATH_SEGMENT@[188; 193)
NAME_REF@[188; 193)
IDENT@[188; 193) "Tuple"
L_PAREN@[193; 194) "("
DOT_DOT_PAT@[194; 196)
DOTDOT@[194; 196) ".."
COMMA@[196; 197) ","
WHITESPACE@[197; 198) " "
DOT_DOT_PAT@[198; 200)
DOTDOT@[198; 200) ".."
R_PAREN@[200; 201) ")"
WHITESPACE@[201; 202) " "
EQ@[202; 203) "="
WHITESPACE@[203; 204) " "
TUPLE_EXPR@[204; 206)
L_PAREN@[204; 205) "("
R_PAREN@[205; 206) ")"
SEMI@[206; 207) ";"
WHITESPACE@[207; 212) "\n "
LET_STMT@[212; 233)
LET_KW@[212; 215) "let"
WHITESPACE@[215; 216) " "
TUPLE_PAT@[216; 227)
L_PAREN@[216; 217) "("
DOT_DOT_PAT@[217; 219)
DOTDOT@[217; 219) ".."
COMMA@[219; 220) ","
WHITESPACE@[220; 221) " "
BIND_PAT@[221; 222)
NAME@[221; 222)
IDENT@[221; 222) "a"
COMMA@[222; 223) ","
WHITESPACE@[223; 224) " "
DOT_DOT_PAT@[224; 226)
DOTDOT@[224; 226) ".."
R_PAREN@[226; 227) ")"
WHITESPACE@[227; 228) " "
EQ@[228; 229) "="
WHITESPACE@[229; 230) " "
TUPLE_EXPR@[230; 232)
L_PAREN@[230; 231) "("
R_PAREN@[231; 232) ")"
SEMI@[232; 233) ";"
WHITESPACE@[233; 238) "\n "
LET_STMT@[238; 264)
LET_KW@[238; 241) "let"
WHITESPACE@[241; 242) " "
TUPLE_STRUCT_PAT@[242; 258)
PATH@[242; 247)
PATH_SEGMENT@[242; 247)
NAME_REF@[242; 247)
IDENT@[242; 247) "Tuple"
L_PAREN@[247; 248) "("
DOT_DOT_PAT@[248; 250)
DOTDOT@[248; 250) ".."
COMMA@[250; 251) ","
WHITESPACE@[251; 252) " "
BIND_PAT@[252; 253)
NAME@[252; 253)
IDENT@[252; 253) "a"
COMMA@[253; 254) ","
WHITESPACE@[254; 255) " "
DOT_DOT_PAT@[255; 257)
DOTDOT@[255; 257) ".."
R_PAREN@[257; 258) ")"
WHITESPACE@[258; 259) " "
EQ@[259; 260) "="
WHITESPACE@[260; 261) " "
TUPLE_EXPR@[261; 263)
L_PAREN@[261; 262) "("
R_PAREN@[262; 263) ")"
SEMI@[263; 264) ";"
WHITESPACE@[264; 269) "\n "
COMMENT@[269; 271) "//"
WHITESPACE@[271; 276) "\n "
COMMENT@[276; 285) "// Slices"
WHITESPACE@[285; 290) "\n "
COMMENT@[290; 292) "//"
WHITESPACE@[292; 297) "\n "
LET_STMT@[297; 311)
LET_KW@[297; 300) "let"
WHITESPACE@[300; 301) " "
SLICE_PAT@[301; 305)
L_BRACK@[301; 302) "["
DOT_DOT_PAT@[302; 304)
DOTDOT@[302; 304) ".."
R_BRACK@[304; 305) "]"
WHITESPACE@[305; 306) " "
EQ@[306; 307) "="
WHITESPACE@[307; 308) " "
TUPLE_EXPR@[308; 310)
L_PAREN@[308; 309) "("
R_PAREN@[309; 310) ")"
SEMI@[310; 311) ";"
WHITESPACE@[311; 316) "\n "
LET_STMT@[316; 336)
LET_KW@[316; 319) "let"
WHITESPACE@[319; 320) " "
SLICE_PAT@[320; 330)
L_BRACK@[320; 321) "["
BIND_PAT@[321; 325)
NAME@[321; 325)
IDENT@[321; 325) "head"
COMMA@[325; 326) ","
WHITESPACE@[326; 327) " "
DOT_DOT_PAT@[327; 329)
DOTDOT@[327; 329) ".."
R_BRACK@[329; 330) "]"
WHITESPACE@[330; 331) " "
EQ@[331; 332) "="
WHITESPACE@[332; 333) " "
TUPLE_EXPR@[333; 335)
L_PAREN@[333; 334) "("
R_PAREN@[334; 335) ")"
SEMI@[335; 336) ";"
WHITESPACE@[336; 341) "\n "
LET_STMT@[341; 368)
LET_KW@[341; 344) "let"
WHITESPACE@[344; 345) " "
SLICE_PAT@[345; 362)
L_BRACK@[345; 346) "["
BIND_PAT@[346; 350)
NAME@[346; 350)
IDENT@[346; 350) "head"
COMMA@[350; 351) ","
WHITESPACE@[351; 352) " "
BIND_PAT@[352; 361)
NAME@[352; 356)
IDENT@[352; 356) "tail"
WHITESPACE@[356; 357) " "
AT@[357; 358) "@"
WHITESPACE@[358; 359) " "
DOT_DOT_PAT@[359; 361)
DOTDOT@[359; 361) ".."
R_BRACK@[361; 362) "]"
WHITESPACE@[362; 363) " "
EQ@[363; 364) "="
WHITESPACE@[364; 365) " "
TUPLE_EXPR@[365; 367)
L_PAREN@[365; 366) "("
R_PAREN@[366; 367) ")"
SEMI@[367; 368) ";"
WHITESPACE@[368; 373) "\n "
LET_STMT@[373; 399)
LET_KW@[373; 376) "let"
WHITESPACE@[376; 377) " "
SLICE_PAT@[377; 393)
L_BRACK@[377; 378) "["
BIND_PAT@[378; 382)
NAME@[378; 382)
IDENT@[378; 382) "head"
COMMA@[382; 383) ","
WHITESPACE@[383; 384) " "
DOT_DOT_PAT@[384; 386)
DOTDOT@[384; 386) ".."
COMMA@[386; 387) ","
WHITESPACE@[387; 388) " "
BIND_PAT@[388; 392)
NAME@[388; 392)
IDENT@[388; 392) "cons"
R_BRACK@[392; 393) "]"
WHITESPACE@[393; 394) " "
EQ@[394; 395) "="
WHITESPACE@[395; 396) " "
TUPLE_EXPR@[396; 398)
L_PAREN@[396; 397) "("
R_PAREN@[397; 398) ")"
SEMI@[398; 399) ";"
WHITESPACE@[399; 404) "\n "
LET_STMT@[404; 436)
LET_KW@[404; 407) "let"
WHITESPACE@[407; 408) " "
SLICE_PAT@[408; 430)
L_BRACK@[408; 409) "["
BIND_PAT@[409; 413)
NAME@[409; 413)
IDENT@[409; 413) "head"
COMMA@[413; 414) ","
WHITESPACE@[414; 415) " "
BIND_PAT@[415; 423)
NAME@[415; 418)
IDENT@[415; 418) "mid"
WHITESPACE@[418; 419) " "
AT@[419; 420) "@"
WHITESPACE@[420; 421) " "
DOT_DOT_PAT@[421; 423)
DOTDOT@[421; 423) ".."
COMMA@[423; 424) ","
WHITESPACE@[424; 425) " "
BIND_PAT@[425; 429)
NAME@[425; 429)
IDENT@[425; 429) "cons"
R_BRACK@[429; 430) "]"
WHITESPACE@[430; 431) " "
EQ@[431; 432) "="
WHITESPACE@[432; 433) " "
TUPLE_EXPR@[433; 435)
L_PAREN@[433; 434) "("
R_PAREN@[434; 435) ")"
SEMI@[435; 436) ";"
WHITESPACE@[436; 441) "\n "
LET_STMT@[441; 471)
LET_KW@[441; 444) "let"
WHITESPACE@[444; 445) " "
SLICE_PAT@[445; 465)
L_BRACK@[445; 446) "["
BIND_PAT@[446; 450)
NAME@[446; 450)
IDENT@[446; 450) "head"
COMMA@[450; 451) ","
WHITESPACE@[451; 452) " "
DOT_DOT_PAT@[452; 454)
DOTDOT@[452; 454) ".."
COMMA@[454; 455) ","
WHITESPACE@[455; 456) " "
DOT_DOT_PAT@[456; 458)
DOTDOT@[456; 458) ".."
COMMA@[458; 459) ","
WHITESPACE@[459; 460) " "
BIND_PAT@[460; 464)
NAME@[460; 464)
IDENT@[460; 464) "cons"
R_BRACK@[464; 465) "]"
WHITESPACE@[465; 466) " "
EQ@[466; 467) "="
WHITESPACE@[467; 468) " "
TUPLE_EXPR@[468; 470)
L_PAREN@[468; 469) "("
R_PAREN@[469; 470) ")"
SEMI@[470; 471) ";"
WHITESPACE@[471; 476) "\n "
LET_STMT@[476; 512)
LET_KW@[476; 479) "let"
WHITESPACE@[479; 480) " "
SLICE_PAT@[480; 506)
L_BRACK@[480; 481) "["
BIND_PAT@[481; 485)
NAME@[481; 485)
IDENT@[481; 485) "head"
COMMA@[485; 486) ","
WHITESPACE@[486; 487) " "
DOT_DOT_PAT@[487; 489)
DOTDOT@[487; 489) ".."
COMMA@[489; 490) ","
WHITESPACE@[490; 491) " "
BIND_PAT@[491; 494)
NAME@[491; 494)
IDENT@[491; 494) "mid"
COMMA@[494; 495) ","
WHITESPACE@[495; 496) " "
BIND_PAT@[496; 505)
NAME@[496; 500)
IDENT@[496; 500) "tail"
WHITESPACE@[500; 501) " "
AT@[501; 502) "@"
WHITESPACE@[502; 503) " "
DOT_DOT_PAT@[503; 505)
DOTDOT@[503; 505) ".."
R_BRACK@[505; 506) "]"
WHITESPACE@[506; 507) " "
EQ@[507; 508) "="
WHITESPACE@[508; 509) " "
TUPLE_EXPR@[509; 511)
L_PAREN@[509; 510) "("
R_PAREN@[510; 511) ")"
SEMI@[511; 512) ";"
WHITESPACE@[512; 517) "\n "
LET_STMT@[517; 552)
LET_KW@[517; 520) "let"
WHITESPACE@[520; 521) " "
SLICE_PAT@[521; 546)
L_BRACK@[521; 522) "["
BIND_PAT@[522; 526)
NAME@[522; 526)
IDENT@[522; 526) "head"
COMMA@[526; 527) ","
WHITESPACE@[527; 528) " "
DOT_DOT_PAT@[528; 530)
DOTDOT@[528; 530) ".."
COMMA@[530; 531) ","
WHITESPACE@[531; 532) " "
BIND_PAT@[532; 535)
NAME@[532; 535)
IDENT@[532; 535) "mid"
COMMA@[535; 536) ","
WHITESPACE@[536; 537) " "
DOT_DOT_PAT@[537; 539)
DOTDOT@[537; 539) ".."
COMMA@[539; 540) ","
WHITESPACE@[540; 541) " "
BIND_PAT@[541; 545)
NAME@[541; 545)
IDENT@[541; 545) "cons"
R_BRACK@[545; 546) "]"
WHITESPACE@[546; 547) " "
EQ@[547; 548) "="
WHITESPACE@[548; 549) " "
TUPLE_EXPR@[549; 551)
L_PAREN@[549; 550) "("
R_PAREN@[550; 551) ")"
SEMI@[551; 552) ";"
WHITESPACE@[552; 553) "\n"
R_CURLY@[553; 554) "}"
WHITESPACE@[554; 555) "\n"

View file

@ -1656,7 +1656,8 @@ SOURCE_FILE@[0; 3813)
PARAM@[2952; 2962)
TUPLE_PAT@[2952; 2956)
L_PAREN@[2952; 2953) "("
DOTDOT@[2953; 2955) ".."
DOT_DOT_PAT@[2953; 2955)
DOTDOT@[2953; 2955) ".."
R_PAREN@[2955; 2956) ")"
COLON@[2956; 2957) ":"
TUPLE_TYPE@[2957; 2962)