tuple patterns

This commit is contained in:
Aleksey Kladov 2018-08-04 15:47:45 +03:00
parent 8f1c645055
commit 4e4ad3d27c
9 changed files with 434 additions and 4 deletions

View file

@ -126,6 +126,9 @@ Grammar(
"REF_PAT",
"BIND_PAT",
"PLACEHOLDER_PAT",
"PATH_PAT",
"STRUCT_PAT",
"TUPLE_PAT",
"TUPLE_EXPR",
"PATH_EXPR",

View file

@ -1,14 +1,98 @@
use super::*;
pub(super) fn pattern(p: &mut Parser) {
match p.current() {
let la0 = p.nth(0);
let la1 = p.nth(1);
if la0 == REF_KW || la0 == MUT_KW
|| (la0 == IDENT && !(la1 == COLONCOLON || la1 == L_PAREN || la1 == L_CURLY)) {
bind_pat(p, true);
return;
}
if paths::is_path_start(p) {
path_pat(p);
return;
}
match la0 {
UNDERSCORE => placeholder_pat(p),
AMPERSAND => ref_pat(p),
IDENT | REF_KW | MUT_KW => bind_pat(p),
_ => p.err_and_bump("expected pattern"),
}
}
// test path_part
// fn foo() {
// let foo::Bar = ();
// let ::Bar = ();
// let Bar { .. } = ();
// let Bar(..) = ();
// }
fn path_pat(p: &mut Parser) {
let m = p.start();
paths::expr_path(p);
let kind = match p.current() {
L_PAREN => {
tuple_pat_fields(p);
TUPLE_PAT
}
L_CURLY => {
struct_pat_fields(p);
STRUCT_PAT
}
_ => PATH_PAT
};
m.complete(p, kind);
}
// test tuple_pat_fields
// fn foo() {
// let S() = ();
// let S(_) = ();
// let S(_,) = ();
// let S(_, .. , x) = ();
// }
fn tuple_pat_fields(p: &mut Parser) {
assert!(p.at(L_PAREN));
p.bump();
while !p.at(EOF) && !p.at(R_PAREN) {
match p.current() {
DOTDOT => p.bump(),
_ => pattern(p),
}
if !p.at(R_PAREN) {
p.expect(COMMA);
}
}
p.expect(R_PAREN);
}
// test struct_pat_fields
// fn foo() {
// let S {} = ();
// let S { f, ref mut g } = ();
// let S { h: _, ..} = ();
// let S { h: _, } = ();
// }
fn struct_pat_fields(p: &mut Parser) {
assert!(p.at(L_CURLY));
p.bump();
while !p.at(EOF) && !p.at(R_CURLY) {
match p.current() {
DOTDOT => p.bump(),
IDENT if p.nth(1) == COLON => {
p.bump();
p.bump();
pattern(p);
}
_ => bind_pat(p, false),
}
if !p.at(R_CURLY) {
p.expect(COMMA);
}
}
p.expect(R_CURLY);
}
// test placeholder_pat
// fn main() { let _ = (); }
fn placeholder_pat(p: &mut Parser) {
@ -41,12 +125,12 @@ fn ref_pat(p: &mut Parser) {
// let e @ _ = ();
// let ref mut f @ g @ _ = ();
// }
fn bind_pat(p: &mut Parser) {
fn bind_pat(p: &mut Parser, with_at: bool) {
let m = p.start();
p.eat(REF_KW);
p.eat(MUT_KW);
name(p);
if p.eat(AT) {
if with_at && p.eat(AT) {
pattern(p);
}
m.complete(p, BIND_PAT);

View file

@ -118,6 +118,9 @@ pub enum SyntaxKind {
REF_PAT,
BIND_PAT,
PLACEHOLDER_PAT,
PATH_PAT,
STRUCT_PAT,
TUPLE_PAT,
TUPLE_EXPR,
PATH_EXPR,
CALL_EXPR,
@ -331,6 +334,9 @@ impl SyntaxKind {
REF_PAT => &SyntaxInfo { name: "REF_PAT" },
BIND_PAT => &SyntaxInfo { name: "BIND_PAT" },
PLACEHOLDER_PAT => &SyntaxInfo { name: "PLACEHOLDER_PAT" },
PATH_PAT => &SyntaxInfo { name: "PATH_PAT" },
STRUCT_PAT => &SyntaxInfo { name: "STRUCT_PAT" },
TUPLE_PAT => &SyntaxInfo { name: "TUPLE_PAT" },
TUPLE_EXPR => &SyntaxInfo { name: "TUPLE_EXPR" },
PATH_EXPR => &SyntaxInfo { name: "PATH_EXPR" },
CALL_EXPR => &SyntaxInfo { name: "CALL_EXPR" },

View file

@ -0,0 +1,6 @@
fn foo() {
let S() = ();
let S(_) = ();
let S(_,) = ();
let S(_, .. , x) = ();
}

View file

@ -0,0 +1,103 @@
FILE@[0; 97)
FN_ITEM@[0; 97)
FN_KW@[0; 2)
NAME@[2; 6)
WHITESPACE@[2; 3)
IDENT@[3; 6) "foo"
PARAM_LIST@[6; 9)
L_PAREN@[6; 7)
R_PAREN@[7; 8)
WHITESPACE@[8; 9)
BLOCK_EXPR@[9; 97)
L_CURLY@[9; 10)
LET_STMT@[10; 33)
WHITESPACE@[10; 15)
LET_KW@[15; 18)
TUPLE_PAT@[18; 23)
PATH@[18; 20)
PATH_SEGMENT@[18; 20)
NAME_REF@[18; 20)
WHITESPACE@[18; 19)
IDENT@[19; 20) "S"
L_PAREN@[20; 21)
R_PAREN@[21; 22)
WHITESPACE@[22; 23)
EQ@[23; 24)
TUPLE_EXPR@[24; 27)
WHITESPACE@[24; 25)
L_PAREN@[25; 26)
R_PAREN@[26; 27)
SEMI@[27; 28)
WHITESPACE@[28; 33)
LET_STMT@[33; 52)
LET_KW@[33; 36)
TUPLE_PAT@[36; 42)
PATH@[36; 38)
PATH_SEGMENT@[36; 38)
NAME_REF@[36; 38)
WHITESPACE@[36; 37)
IDENT@[37; 38) "S"
L_PAREN@[38; 39)
PLACEHOLDER_PAT@[39; 40)
UNDERSCORE@[39; 40)
R_PAREN@[40; 41)
WHITESPACE@[41; 42)
EQ@[42; 43)
TUPLE_EXPR@[43; 46)
WHITESPACE@[43; 44)
L_PAREN@[44; 45)
R_PAREN@[45; 46)
SEMI@[46; 47)
WHITESPACE@[47; 52)
LET_STMT@[52; 72)
LET_KW@[52; 55)
TUPLE_PAT@[55; 62)
PATH@[55; 57)
PATH_SEGMENT@[55; 57)
NAME_REF@[55; 57)
WHITESPACE@[55; 56)
IDENT@[56; 57) "S"
L_PAREN@[57; 58)
PLACEHOLDER_PAT@[58; 59)
UNDERSCORE@[58; 59)
COMMA@[59; 60)
R_PAREN@[60; 61)
WHITESPACE@[61; 62)
EQ@[62; 63)
TUPLE_EXPR@[63; 66)
WHITESPACE@[63; 64)
L_PAREN@[64; 65)
R_PAREN@[65; 66)
SEMI@[66; 67)
WHITESPACE@[67; 72)
LET_STMT@[72; 95)
LET_KW@[72; 75)
TUPLE_PAT@[75; 89)
PATH@[75; 77)
PATH_SEGMENT@[75; 77)
NAME_REF@[75; 77)
WHITESPACE@[75; 76)
IDENT@[76; 77) "S"
L_PAREN@[77; 78)
PLACEHOLDER_PAT@[78; 79)
UNDERSCORE@[78; 79)
COMMA@[79; 80)
WHITESPACE@[80; 81)
DOTDOT@[81; 83)
WHITESPACE@[83; 84)
COMMA@[84; 85)
BIND_PAT@[85; 87)
NAME@[85; 87)
WHITESPACE@[85; 86)
IDENT@[86; 87) "x"
R_PAREN@[87; 88)
WHITESPACE@[88; 89)
EQ@[89; 90)
TUPLE_EXPR@[90; 93)
WHITESPACE@[90; 91)
L_PAREN@[91; 92)
R_PAREN@[92; 93)
SEMI@[93; 94)
WHITESPACE@[94; 95)
R_CURLY@[95; 96)
WHITESPACE@[96; 97)

View file

@ -0,0 +1,6 @@
fn foo() {
let foo::Bar = ();
let ::Bar = ();
let Bar { .. } = ();
let Bar(..) = ();
}

View file

@ -0,0 +1,94 @@
FILE@[0; 103)
FN_ITEM@[0; 103)
FN_KW@[0; 2)
NAME@[2; 6)
WHITESPACE@[2; 3)
IDENT@[3; 6) "foo"
PARAM_LIST@[6; 9)
L_PAREN@[6; 7)
R_PAREN@[7; 8)
WHITESPACE@[8; 9)
BLOCK_EXPR@[9; 103)
L_CURLY@[9; 10)
LET_STMT@[10; 38)
WHITESPACE@[10; 15)
LET_KW@[15; 18)
PATH_PAT@[18; 28)
PATH@[18; 28)
PATH@[18; 22)
PATH_SEGMENT@[18; 22)
NAME_REF@[18; 22)
WHITESPACE@[18; 19)
IDENT@[19; 22) "foo"
COLONCOLON@[22; 24)
PATH_SEGMENT@[24; 28)
NAME_REF@[24; 28)
IDENT@[24; 27) "Bar"
WHITESPACE@[27; 28)
EQ@[28; 29)
TUPLE_EXPR@[29; 32)
WHITESPACE@[29; 30)
L_PAREN@[30; 31)
R_PAREN@[31; 32)
SEMI@[32; 33)
WHITESPACE@[33; 38)
LET_STMT@[38; 58)
LET_KW@[38; 41)
PATH_PAT@[41; 48)
PATH@[41; 48)
PATH_SEGMENT@[41; 48)
WHITESPACE@[41; 42)
COLONCOLON@[42; 44)
NAME_REF@[44; 48)
IDENT@[44; 47) "Bar"
WHITESPACE@[47; 48)
EQ@[48; 49)
TUPLE_EXPR@[49; 52)
WHITESPACE@[49; 50)
L_PAREN@[50; 51)
R_PAREN@[51; 52)
SEMI@[52; 53)
WHITESPACE@[53; 58)
LET_STMT@[58; 83)
LET_KW@[58; 61)
STRUCT_PAT@[61; 73)
PATH@[61; 66)
PATH_SEGMENT@[61; 66)
NAME_REF@[61; 66)
WHITESPACE@[61; 62)
IDENT@[62; 65) "Bar"
WHITESPACE@[65; 66)
L_CURLY@[66; 67)
WHITESPACE@[67; 68)
DOTDOT@[68; 70)
WHITESPACE@[70; 71)
R_CURLY@[71; 72)
WHITESPACE@[72; 73)
EQ@[73; 74)
TUPLE_EXPR@[74; 77)
WHITESPACE@[74; 75)
L_PAREN@[75; 76)
R_PAREN@[76; 77)
SEMI@[77; 78)
WHITESPACE@[78; 83)
LET_STMT@[83; 101)
LET_KW@[83; 86)
TUPLE_PAT@[86; 95)
PATH@[86; 90)
PATH_SEGMENT@[86; 90)
NAME_REF@[86; 90)
WHITESPACE@[86; 87)
IDENT@[87; 90) "Bar"
L_PAREN@[90; 91)
DOTDOT@[91; 93)
R_PAREN@[93; 94)
WHITESPACE@[94; 95)
EQ@[95; 96)
TUPLE_EXPR@[96; 99)
WHITESPACE@[96; 97)
L_PAREN@[97; 98)
R_PAREN@[98; 99)
SEMI@[99; 100)
WHITESPACE@[100; 101)
R_CURLY@[101; 102)
WHITESPACE@[102; 103)

View file

@ -0,0 +1,6 @@
fn foo() {
let S {} = ();
let S { f, ref mut g } = ();
let S { h: _, ..} = ();
let S { h: _, } = ();
}

View file

@ -0,0 +1,122 @@
FILE@[0; 119)
FN_ITEM@[0; 119)
FN_KW@[0; 2)
NAME@[2; 6)
WHITESPACE@[2; 3)
IDENT@[3; 6) "foo"
PARAM_LIST@[6; 9)
L_PAREN@[6; 7)
R_PAREN@[7; 8)
WHITESPACE@[8; 9)
BLOCK_EXPR@[9; 119)
L_CURLY@[9; 10)
LET_STMT@[10; 34)
WHITESPACE@[10; 15)
LET_KW@[15; 18)
STRUCT_PAT@[18; 24)
PATH@[18; 21)
PATH_SEGMENT@[18; 21)
NAME_REF@[18; 21)
WHITESPACE@[18; 19)
IDENT@[19; 20) "S"
WHITESPACE@[20; 21)
L_CURLY@[21; 22)
R_CURLY@[22; 23)
WHITESPACE@[23; 24)
EQ@[24; 25)
TUPLE_EXPR@[25; 28)
WHITESPACE@[25; 26)
L_PAREN@[26; 27)
R_PAREN@[27; 28)
SEMI@[28; 29)
WHITESPACE@[29; 34)
LET_STMT@[34; 67)
LET_KW@[34; 37)
STRUCT_PAT@[37; 57)
PATH@[37; 40)
PATH_SEGMENT@[37; 40)
NAME_REF@[37; 40)
WHITESPACE@[37; 38)
IDENT@[38; 39) "S"
WHITESPACE@[39; 40)
L_CURLY@[40; 41)
BIND_PAT@[41; 43)
NAME@[41; 43)
WHITESPACE@[41; 42)
IDENT@[42; 43) "f"
COMMA@[43; 44)
BIND_PAT@[44; 55)
WHITESPACE@[44; 45)
REF_KW@[45; 48)
WHITESPACE@[48; 49)
MUT_KW@[49; 52)
NAME@[52; 55)
WHITESPACE@[52; 53)
IDENT@[53; 54) "g"
WHITESPACE@[54; 55)
R_CURLY@[55; 56)
WHITESPACE@[56; 57)
EQ@[57; 58)
TUPLE_EXPR@[58; 61)
WHITESPACE@[58; 59)
L_PAREN@[59; 60)
R_PAREN@[60; 61)
SEMI@[61; 62)
WHITESPACE@[62; 67)
LET_STMT@[67; 95)
LET_KW@[67; 70)
STRUCT_PAT@[70; 85)
PATH@[70; 73)
PATH_SEGMENT@[70; 73)
NAME_REF@[70; 73)
WHITESPACE@[70; 71)
IDENT@[71; 72) "S"
WHITESPACE@[72; 73)
L_CURLY@[73; 74)
WHITESPACE@[74; 75)
IDENT@[75; 76) "h"
COLON@[76; 77)
PLACEHOLDER_PAT@[77; 79)
WHITESPACE@[77; 78)
UNDERSCORE@[78; 79)
COMMA@[79; 80)
WHITESPACE@[80; 81)
DOTDOT@[81; 83)
R_CURLY@[83; 84)
WHITESPACE@[84; 85)
EQ@[85; 86)
TUPLE_EXPR@[86; 89)
WHITESPACE@[86; 87)
L_PAREN@[87; 88)
R_PAREN@[88; 89)
SEMI@[89; 90)
WHITESPACE@[90; 95)
LET_STMT@[95; 117)
LET_KW@[95; 98)
STRUCT_PAT@[98; 111)
PATH@[98; 101)
PATH_SEGMENT@[98; 101)
NAME_REF@[98; 101)
WHITESPACE@[98; 99)
IDENT@[99; 100) "S"
WHITESPACE@[100; 101)
L_CURLY@[101; 102)
WHITESPACE@[102; 103)
IDENT@[103; 104) "h"
COLON@[104; 105)
PLACEHOLDER_PAT@[105; 107)
WHITESPACE@[105; 106)
UNDERSCORE@[106; 107)
COMMA@[107; 108)
WHITESPACE@[108; 109)
R_CURLY@[109; 110)
WHITESPACE@[110; 111)
EQ@[111; 112)
TUPLE_EXPR@[112; 115)
WHITESPACE@[112; 113)
L_PAREN@[113; 114)
R_PAREN@[114; 115)
SEMI@[115; 116)
WHITESPACE@[116; 117)
R_CURLY@[117; 118)
WHITESPACE@[118; 119)