From 4e4ad3d27cd662b790395b61f3cda560fd4e2146 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 4 Aug 2018 15:47:45 +0300 Subject: [PATCH] tuple patterns --- src/grammar.ron | 3 + src/grammar/patterns.rs | 92 ++++++++++++- src/syntax_kinds/generated.rs | 6 + .../parser/inline/0071_tuple_pat_fields.rs | 6 + .../parser/inline/0071_tuple_pat_fields.txt | 103 +++++++++++++++ tests/data/parser/inline/0072_path_part.rs | 6 + tests/data/parser/inline/0072_path_part.txt | 94 ++++++++++++++ .../parser/inline/0073_struct_pat_fields.rs | 6 + .../parser/inline/0073_struct_pat_fields.txt | 122 ++++++++++++++++++ 9 files changed, 434 insertions(+), 4 deletions(-) create mode 100644 tests/data/parser/inline/0071_tuple_pat_fields.rs create mode 100644 tests/data/parser/inline/0071_tuple_pat_fields.txt create mode 100644 tests/data/parser/inline/0072_path_part.rs create mode 100644 tests/data/parser/inline/0072_path_part.txt create mode 100644 tests/data/parser/inline/0073_struct_pat_fields.rs create mode 100644 tests/data/parser/inline/0073_struct_pat_fields.txt diff --git a/src/grammar.ron b/src/grammar.ron index 0239a3c1dcf5..655ed2e404c0 100644 --- a/src/grammar.ron +++ b/src/grammar.ron @@ -126,6 +126,9 @@ Grammar( "REF_PAT", "BIND_PAT", "PLACEHOLDER_PAT", + "PATH_PAT", + "STRUCT_PAT", + "TUPLE_PAT", "TUPLE_EXPR", "PATH_EXPR", diff --git a/src/grammar/patterns.rs b/src/grammar/patterns.rs index 7216807fda4e..770274686c12 100644 --- a/src/grammar/patterns.rs +++ b/src/grammar/patterns.rs @@ -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); diff --git a/src/syntax_kinds/generated.rs b/src/syntax_kinds/generated.rs index 73b26b274a9e..d7a57f4d09e3 100644 --- a/src/syntax_kinds/generated.rs +++ b/src/syntax_kinds/generated.rs @@ -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" }, diff --git a/tests/data/parser/inline/0071_tuple_pat_fields.rs b/tests/data/parser/inline/0071_tuple_pat_fields.rs new file mode 100644 index 000000000000..0dfe63629679 --- /dev/null +++ b/tests/data/parser/inline/0071_tuple_pat_fields.rs @@ -0,0 +1,6 @@ +fn foo() { + let S() = (); + let S(_) = (); + let S(_,) = (); + let S(_, .. , x) = (); +} diff --git a/tests/data/parser/inline/0071_tuple_pat_fields.txt b/tests/data/parser/inline/0071_tuple_pat_fields.txt new file mode 100644 index 000000000000..f0b3198f5765 --- /dev/null +++ b/tests/data/parser/inline/0071_tuple_pat_fields.txt @@ -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) diff --git a/tests/data/parser/inline/0072_path_part.rs b/tests/data/parser/inline/0072_path_part.rs new file mode 100644 index 000000000000..f6e32c7c1493 --- /dev/null +++ b/tests/data/parser/inline/0072_path_part.rs @@ -0,0 +1,6 @@ +fn foo() { + let foo::Bar = (); + let ::Bar = (); + let Bar { .. } = (); + let Bar(..) = (); +} diff --git a/tests/data/parser/inline/0072_path_part.txt b/tests/data/parser/inline/0072_path_part.txt new file mode 100644 index 000000000000..227046fcc21c --- /dev/null +++ b/tests/data/parser/inline/0072_path_part.txt @@ -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) diff --git a/tests/data/parser/inline/0073_struct_pat_fields.rs b/tests/data/parser/inline/0073_struct_pat_fields.rs new file mode 100644 index 000000000000..da3412fa8a94 --- /dev/null +++ b/tests/data/parser/inline/0073_struct_pat_fields.rs @@ -0,0 +1,6 @@ +fn foo() { + let S {} = (); + let S { f, ref mut g } = (); + let S { h: _, ..} = (); + let S { h: _, } = (); +} diff --git a/tests/data/parser/inline/0073_struct_pat_fields.txt b/tests/data/parser/inline/0073_struct_pat_fields.txt new file mode 100644 index 000000000000..639c34dcbc64 --- /dev/null +++ b/tests/data/parser/inline/0073_struct_pat_fields.txt @@ -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)