aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/grammar.ron3
-rw-r--r--src/grammar/patterns.rs92
-rw-r--r--src/syntax_kinds/generated.rs6
3 files changed, 97 insertions, 4 deletions
diff --git a/src/grammar.ron b/src/grammar.ron
index 0239a3c1d..655ed2e40 100644
--- a/src/grammar.ron
+++ b/src/grammar.ron
@@ -126,6 +126,9 @@ Grammar(
126 "REF_PAT", 126 "REF_PAT",
127 "BIND_PAT", 127 "BIND_PAT",
128 "PLACEHOLDER_PAT", 128 "PLACEHOLDER_PAT",
129 "PATH_PAT",
130 "STRUCT_PAT",
131 "TUPLE_PAT",
129 132
130 "TUPLE_EXPR", 133 "TUPLE_EXPR",
131 "PATH_EXPR", 134 "PATH_EXPR",
diff --git a/src/grammar/patterns.rs b/src/grammar/patterns.rs
index 7216807fd..770274686 100644
--- a/src/grammar/patterns.rs
+++ b/src/grammar/patterns.rs
@@ -1,14 +1,98 @@
1use super::*; 1use super::*;
2 2
3pub(super) fn pattern(p: &mut Parser) { 3pub(super) fn pattern(p: &mut Parser) {
4 match p.current() { 4 let la0 = p.nth(0);
5 let la1 = p.nth(1);
6 if la0 == REF_KW || la0 == MUT_KW
7 || (la0 == IDENT && !(la1 == COLONCOLON || la1 == L_PAREN || la1 == L_CURLY)) {
8 bind_pat(p, true);
9 return;
10 }
11 if paths::is_path_start(p) {
12 path_pat(p);
13 return;
14 }
15
16 match la0 {
5 UNDERSCORE => placeholder_pat(p), 17 UNDERSCORE => placeholder_pat(p),
6 AMPERSAND => ref_pat(p), 18 AMPERSAND => ref_pat(p),
7 IDENT | REF_KW | MUT_KW => bind_pat(p),
8 _ => p.err_and_bump("expected pattern"), 19 _ => p.err_and_bump("expected pattern"),
9 } 20 }
10} 21}
11 22
23// test path_part
24// fn foo() {
25// let foo::Bar = ();
26// let ::Bar = ();
27// let Bar { .. } = ();
28// let Bar(..) = ();
29// }
30fn path_pat(p: &mut Parser) {
31 let m = p.start();
32 paths::expr_path(p);
33 let kind = match p.current() {
34 L_PAREN => {
35 tuple_pat_fields(p);
36 TUPLE_PAT
37 }
38 L_CURLY => {
39 struct_pat_fields(p);
40 STRUCT_PAT
41 }
42 _ => PATH_PAT
43 };
44 m.complete(p, kind);
45}
46
47// test tuple_pat_fields
48// fn foo() {
49// let S() = ();
50// let S(_) = ();
51// let S(_,) = ();
52// let S(_, .. , x) = ();
53// }
54fn tuple_pat_fields(p: &mut Parser) {
55 assert!(p.at(L_PAREN));
56 p.bump();
57 while !p.at(EOF) && !p.at(R_PAREN) {
58 match p.current() {
59 DOTDOT => p.bump(),
60 _ => pattern(p),
61 }
62 if !p.at(R_PAREN) {
63 p.expect(COMMA);
64 }
65 }
66 p.expect(R_PAREN);
67}
68
69// test struct_pat_fields
70// fn foo() {
71// let S {} = ();
72// let S { f, ref mut g } = ();
73// let S { h: _, ..} = ();
74// let S { h: _, } = ();
75// }
76fn struct_pat_fields(p: &mut Parser) {
77 assert!(p.at(L_CURLY));
78 p.bump();
79 while !p.at(EOF) && !p.at(R_CURLY) {
80 match p.current() {
81 DOTDOT => p.bump(),
82 IDENT if p.nth(1) == COLON => {
83 p.bump();
84 p.bump();
85 pattern(p);
86 }
87 _ => bind_pat(p, false),
88 }
89 if !p.at(R_CURLY) {
90 p.expect(COMMA);
91 }
92 }
93 p.expect(R_CURLY);
94}
95
12// test placeholder_pat 96// test placeholder_pat
13// fn main() { let _ = (); } 97// fn main() { let _ = (); }
14fn placeholder_pat(p: &mut Parser) { 98fn placeholder_pat(p: &mut Parser) {
@@ -41,12 +125,12 @@ fn ref_pat(p: &mut Parser) {
41// let e @ _ = (); 125// let e @ _ = ();
42// let ref mut f @ g @ _ = (); 126// let ref mut f @ g @ _ = ();
43// } 127// }
44fn bind_pat(p: &mut Parser) { 128fn bind_pat(p: &mut Parser, with_at: bool) {
45 let m = p.start(); 129 let m = p.start();
46 p.eat(REF_KW); 130 p.eat(REF_KW);
47 p.eat(MUT_KW); 131 p.eat(MUT_KW);
48 name(p); 132 name(p);
49 if p.eat(AT) { 133 if with_at && p.eat(AT) {
50 pattern(p); 134 pattern(p);
51 } 135 }
52 m.complete(p, BIND_PAT); 136 m.complete(p, BIND_PAT);
diff --git a/src/syntax_kinds/generated.rs b/src/syntax_kinds/generated.rs
index 73b26b274..d7a57f4d0 100644
--- a/src/syntax_kinds/generated.rs
+++ b/src/syntax_kinds/generated.rs
@@ -118,6 +118,9 @@ pub enum SyntaxKind {
118 REF_PAT, 118 REF_PAT,
119 BIND_PAT, 119 BIND_PAT,
120 PLACEHOLDER_PAT, 120 PLACEHOLDER_PAT,
121 PATH_PAT,
122 STRUCT_PAT,
123 TUPLE_PAT,
121 TUPLE_EXPR, 124 TUPLE_EXPR,
122 PATH_EXPR, 125 PATH_EXPR,
123 CALL_EXPR, 126 CALL_EXPR,
@@ -331,6 +334,9 @@ impl SyntaxKind {
331 REF_PAT => &SyntaxInfo { name: "REF_PAT" }, 334 REF_PAT => &SyntaxInfo { name: "REF_PAT" },
332 BIND_PAT => &SyntaxInfo { name: "BIND_PAT" }, 335 BIND_PAT => &SyntaxInfo { name: "BIND_PAT" },
333 PLACEHOLDER_PAT => &SyntaxInfo { name: "PLACEHOLDER_PAT" }, 336 PLACEHOLDER_PAT => &SyntaxInfo { name: "PLACEHOLDER_PAT" },
337 PATH_PAT => &SyntaxInfo { name: "PATH_PAT" },
338 STRUCT_PAT => &SyntaxInfo { name: "STRUCT_PAT" },
339 TUPLE_PAT => &SyntaxInfo { name: "TUPLE_PAT" },
334 TUPLE_EXPR => &SyntaxInfo { name: "TUPLE_EXPR" }, 340 TUPLE_EXPR => &SyntaxInfo { name: "TUPLE_EXPR" },
335 PATH_EXPR => &SyntaxInfo { name: "PATH_EXPR" }, 341 PATH_EXPR => &SyntaxInfo { name: "PATH_EXPR" },
336 CALL_EXPR => &SyntaxInfo { name: "CALL_EXPR" }, 342 CALL_EXPR => &SyntaxInfo { name: "CALL_EXPR" },