aboutsummaryrefslogtreecommitdiff
path: root/crates/libsyntax2/src/grammar/patterns.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/libsyntax2/src/grammar/patterns.rs')
-rw-r--r--crates/libsyntax2/src/grammar/patterns.rs204
1 files changed, 204 insertions, 0 deletions
diff --git a/crates/libsyntax2/src/grammar/patterns.rs b/crates/libsyntax2/src/grammar/patterns.rs
new file mode 100644
index 000000000..436f3b26d
--- /dev/null
+++ b/crates/libsyntax2/src/grammar/patterns.rs
@@ -0,0 +1,204 @@
1use super::*;
2
3pub(super) fn pattern(p: &mut Parser) {
4 if let Some(lhs) = atom_pat(p) {
5 // test range_pat
6 // fn main() {
7 // match 92 { 0 ... 100 => () }
8 // }
9 if p.at(DOTDOTDOT) {
10 let m = lhs.precede(p);
11 p.bump();
12 atom_pat(p);
13 m.complete(p, RANGE_PAT);
14 }
15 }
16}
17
18fn atom_pat(p: &mut Parser) -> Option<CompletedMarker> {
19 let la0 = p.nth(0);
20 let la1 = p.nth(1);
21 if la0 == REF_KW || la0 == MUT_KW
22 || (la0 == IDENT && !(la1 == COLONCOLON || la1 == L_PAREN || la1 == L_CURLY)) {
23 return Some(bind_pat(p, true));
24 }
25 if paths::is_path_start(p) {
26 return Some(path_pat(p));
27 }
28
29 // test literal_pattern
30 // fn main() {
31 // match () {
32 // 92 => (),
33 // 'c' => (),
34 // "hello" => (),
35 // }
36 // }
37 match expressions::literal(p) {
38 Some(m) => return Some(m),
39 None => (),
40 }
41
42 let m = match la0 {
43 UNDERSCORE => placeholder_pat(p),
44 AMP => ref_pat(p),
45 L_PAREN => tuple_pat(p),
46 L_BRACK => slice_pat(p),
47 _ => {
48 p.err_and_bump("expected pattern");
49 return None;
50 }
51 };
52 Some(m)
53}
54
55// test path_part
56// fn foo() {
57// let foo::Bar = ();
58// let ::Bar = ();
59// let Bar { .. } = ();
60// let Bar(..) = ();
61// }
62fn path_pat(p: &mut Parser) -> CompletedMarker {
63 let m = p.start();
64 paths::expr_path(p);
65 let kind = match p.current() {
66 L_PAREN => {
67 tuple_pat_fields(p);
68 TUPLE_STRUCT_PAT
69 }
70 L_CURLY => {
71 struct_pat_fields(p);
72 STRUCT_PAT
73 }
74 _ => PATH_PAT
75 };
76 m.complete(p, kind)
77}
78
79// test tuple_pat_fields
80// fn foo() {
81// let S() = ();
82// let S(_) = ();
83// let S(_,) = ();
84// let S(_, .. , x) = ();
85// }
86fn tuple_pat_fields(p: &mut Parser) {
87 assert!(p.at(L_PAREN));
88 p.bump();
89 while !p.at(EOF) && !p.at(R_PAREN) {
90 match p.current() {
91 DOTDOT => p.bump(),
92 _ => pattern(p),
93 }
94 if !p.at(R_PAREN) {
95 p.expect(COMMA);
96 }
97 }
98 p.expect(R_PAREN);
99}
100
101// test struct_pat_fields
102// fn foo() {
103// let S {} = ();
104// let S { f, ref mut g } = ();
105// let S { h: _, ..} = ();
106// let S { h: _, } = ();
107// }
108fn struct_pat_fields(p: &mut Parser) {
109 assert!(p.at(L_CURLY));
110 p.bump();
111 while !p.at(EOF) && !p.at(R_CURLY) {
112 match p.current() {
113 DOTDOT => p.bump(),
114 IDENT if p.nth(1) == COLON => {
115 p.bump();
116 p.bump();
117 pattern(p);
118 }
119 _ => {
120 bind_pat(p, false);
121 }
122 }
123 if !p.at(R_CURLY) {
124 p.expect(COMMA);
125 }
126 }
127 p.expect(R_CURLY);
128}
129
130// test placeholder_pat
131// fn main() { let _ = (); }
132fn placeholder_pat(p: &mut Parser) -> CompletedMarker {
133 assert!(p.at(UNDERSCORE));
134 let m = p.start();
135 p.bump();
136 m.complete(p, PLACEHOLDER_PAT)
137}
138
139// test ref_pat
140// fn main() {
141// let &a = ();
142// let &mut b = ();
143// }
144fn ref_pat(p: &mut Parser) -> CompletedMarker {
145 assert!(p.at(AMP));
146 let m = p.start();
147 p.bump();
148 p.eat(MUT_KW);
149 pattern(p);
150 m.complete(p, REF_PAT)
151}
152
153// test tuple_pat
154// fn main() {
155// let (a, b, ..) = ();
156// }
157fn tuple_pat(p: &mut Parser) -> CompletedMarker {
158 assert!(p.at(L_PAREN));
159 let m = p.start();
160 tuple_pat_fields(p);
161 m.complete(p, TUPLE_PAT)
162}
163
164// test slice_pat
165// fn main() {
166// let [a, b, ..] = [];
167// }
168fn slice_pat(p: &mut Parser) -> CompletedMarker {
169 assert!(p.at(L_BRACK));
170 let m = p.start();
171 p.bump();
172 while !p.at(EOF) && !p.at(R_BRACK) {
173 match p.current() {
174 DOTDOT => p.bump(),
175 _ => pattern(p),
176 }
177 if !p.at(R_BRACK) {
178 p.expect(COMMA);
179 }
180 }
181 p.expect(R_BRACK);
182
183 m.complete(p, SLICE_PAT)
184}
185
186// test bind_pat
187// fn main() {
188// let a = ();
189// let mut b = ();
190// let ref c = ();
191// let ref mut d = ();
192// let e @ _ = ();
193// let ref mut f @ g @ _ = ();
194// }
195fn bind_pat(p: &mut Parser, with_at: bool) -> CompletedMarker {
196 let m = p.start();
197 p.eat(REF_KW);
198 p.eat(MUT_KW);
199 name(p);
200 if with_at && p.eat(AT) {
201 pattern(p);
202 }
203 m.complete(p, BIND_PAT)
204}