aboutsummaryrefslogtreecommitdiff
path: root/src/grammar/patterns.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/grammar/patterns.rs')
-rw-r--r--src/grammar/patterns.rs92
1 files changed, 88 insertions, 4 deletions
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);