diff options
author | Aleksey Kladov <[email protected]> | 2018-08-08 13:05:33 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-08-08 13:05:33 +0100 |
commit | 5e0fbd59645ad7a8808a7ae9f3ea394afa475852 (patch) | |
tree | a1a805e24ff84f2b7b94608a9f5cf2708fb838b6 /src/grammar | |
parent | bfb90dc4f1e9d86a24207b252c5f3405037928b1 (diff) |
Range patterns
Diffstat (limited to 'src/grammar')
-rw-r--r-- | src/grammar/patterns.rs | 64 |
1 files changed, 42 insertions, 22 deletions
diff --git a/src/grammar/patterns.rs b/src/grammar/patterns.rs index f23addfa3..436f3b26d 100644 --- a/src/grammar/patterns.rs +++ b/src/grammar/patterns.rs | |||
@@ -1,16 +1,29 @@ | |||
1 | use super::*; | 1 | use super::*; |
2 | 2 | ||
3 | pub(super) fn pattern(p: &mut Parser) { | 3 | pub(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 | |||
18 | fn atom_pat(p: &mut Parser) -> Option<CompletedMarker> { | ||
4 | let la0 = p.nth(0); | 19 | let la0 = p.nth(0); |
5 | let la1 = p.nth(1); | 20 | let la1 = p.nth(1); |
6 | if la0 == REF_KW || la0 == MUT_KW | 21 | if la0 == REF_KW || la0 == MUT_KW |
7 | || (la0 == IDENT && !(la1 == COLONCOLON || la1 == L_PAREN || la1 == L_CURLY)) { | 22 | || (la0 == IDENT && !(la1 == COLONCOLON || la1 == L_PAREN || la1 == L_CURLY)) { |
8 | bind_pat(p, true); | 23 | return Some(bind_pat(p, true)); |
9 | return; | ||
10 | } | 24 | } |
11 | if paths::is_path_start(p) { | 25 | if paths::is_path_start(p) { |
12 | path_pat(p); | 26 | return Some(path_pat(p)); |
13 | return; | ||
14 | } | 27 | } |
15 | 28 | ||
16 | // test literal_pattern | 29 | // test literal_pattern |
@@ -21,17 +34,22 @@ pub(super) fn pattern(p: &mut Parser) { | |||
21 | // "hello" => (), | 34 | // "hello" => (), |
22 | // } | 35 | // } |
23 | // } | 36 | // } |
24 | if expressions::literal(p).is_some() { | 37 | match expressions::literal(p) { |
25 | return; | 38 | Some(m) => return Some(m), |
39 | None => (), | ||
26 | } | 40 | } |
27 | 41 | ||
28 | match la0 { | 42 | let m = match la0 { |
29 | UNDERSCORE => placeholder_pat(p), | 43 | UNDERSCORE => placeholder_pat(p), |
30 | AMP => ref_pat(p), | 44 | AMP => ref_pat(p), |
31 | L_PAREN => tuple_pat(p), | 45 | L_PAREN => tuple_pat(p), |
32 | L_BRACK => slice_pat(p), | 46 | L_BRACK => slice_pat(p), |
33 | _ => p.err_and_bump("expected pattern"), | 47 | _ => { |
34 | } | 48 | p.err_and_bump("expected pattern"); |
49 | return None; | ||
50 | } | ||
51 | }; | ||
52 | Some(m) | ||
35 | } | 53 | } |
36 | 54 | ||
37 | // test path_part | 55 | // test path_part |
@@ -41,7 +59,7 @@ pub(super) fn pattern(p: &mut Parser) { | |||
41 | // let Bar { .. } = (); | 59 | // let Bar { .. } = (); |
42 | // let Bar(..) = (); | 60 | // let Bar(..) = (); |
43 | // } | 61 | // } |
44 | fn path_pat(p: &mut Parser) { | 62 | fn path_pat(p: &mut Parser) -> CompletedMarker { |
45 | let m = p.start(); | 63 | let m = p.start(); |
46 | paths::expr_path(p); | 64 | paths::expr_path(p); |
47 | let kind = match p.current() { | 65 | let kind = match p.current() { |
@@ -55,7 +73,7 @@ fn path_pat(p: &mut Parser) { | |||
55 | } | 73 | } |
56 | _ => PATH_PAT | 74 | _ => PATH_PAT |
57 | }; | 75 | }; |
58 | m.complete(p, kind); | 76 | m.complete(p, kind) |
59 | } | 77 | } |
60 | 78 | ||
61 | // test tuple_pat_fields | 79 | // test tuple_pat_fields |
@@ -98,7 +116,9 @@ fn struct_pat_fields(p: &mut Parser) { | |||
98 | p.bump(); | 116 | p.bump(); |
99 | pattern(p); | 117 | pattern(p); |
100 | } | 118 | } |
101 | _ => bind_pat(p, false), | 119 | _ => { |
120 | bind_pat(p, false); | ||
121 | } | ||
102 | } | 122 | } |
103 | if !p.at(R_CURLY) { | 123 | if !p.at(R_CURLY) { |
104 | p.expect(COMMA); | 124 | p.expect(COMMA); |
@@ -109,11 +129,11 @@ fn struct_pat_fields(p: &mut Parser) { | |||
109 | 129 | ||
110 | // test placeholder_pat | 130 | // test placeholder_pat |
111 | // fn main() { let _ = (); } | 131 | // fn main() { let _ = (); } |
112 | fn placeholder_pat(p: &mut Parser) { | 132 | fn placeholder_pat(p: &mut Parser) -> CompletedMarker { |
113 | assert!(p.at(UNDERSCORE)); | 133 | assert!(p.at(UNDERSCORE)); |
114 | let m = p.start(); | 134 | let m = p.start(); |
115 | p.bump(); | 135 | p.bump(); |
116 | m.complete(p, PLACEHOLDER_PAT); | 136 | m.complete(p, PLACEHOLDER_PAT) |
117 | } | 137 | } |
118 | 138 | ||
119 | // test ref_pat | 139 | // test ref_pat |
@@ -121,31 +141,31 @@ fn placeholder_pat(p: &mut Parser) { | |||
121 | // let &a = (); | 141 | // let &a = (); |
122 | // let &mut b = (); | 142 | // let &mut b = (); |
123 | // } | 143 | // } |
124 | fn ref_pat(p: &mut Parser) { | 144 | fn ref_pat(p: &mut Parser) -> CompletedMarker { |
125 | assert!(p.at(AMP)); | 145 | assert!(p.at(AMP)); |
126 | let m = p.start(); | 146 | let m = p.start(); |
127 | p.bump(); | 147 | p.bump(); |
128 | p.eat(MUT_KW); | 148 | p.eat(MUT_KW); |
129 | pattern(p); | 149 | pattern(p); |
130 | m.complete(p, REF_PAT); | 150 | m.complete(p, REF_PAT) |
131 | } | 151 | } |
132 | 152 | ||
133 | // test tuple_pat | 153 | // test tuple_pat |
134 | // fn main() { | 154 | // fn main() { |
135 | // let (a, b, ..) = (); | 155 | // let (a, b, ..) = (); |
136 | // } | 156 | // } |
137 | fn tuple_pat(p: &mut Parser) { | 157 | fn tuple_pat(p: &mut Parser) -> CompletedMarker { |
138 | assert!(p.at(L_PAREN)); | 158 | assert!(p.at(L_PAREN)); |
139 | let m = p.start(); | 159 | let m = p.start(); |
140 | tuple_pat_fields(p); | 160 | tuple_pat_fields(p); |
141 | m.complete(p, TUPLE_PAT); | 161 | m.complete(p, TUPLE_PAT) |
142 | } | 162 | } |
143 | 163 | ||
144 | // test slice_pat | 164 | // test slice_pat |
145 | // fn main() { | 165 | // fn main() { |
146 | // let [a, b, ..] = []; | 166 | // let [a, b, ..] = []; |
147 | // } | 167 | // } |
148 | fn slice_pat(p: &mut Parser) { | 168 | fn slice_pat(p: &mut Parser) -> CompletedMarker { |
149 | assert!(p.at(L_BRACK)); | 169 | assert!(p.at(L_BRACK)); |
150 | let m = p.start(); | 170 | let m = p.start(); |
151 | p.bump(); | 171 | p.bump(); |
@@ -160,7 +180,7 @@ fn slice_pat(p: &mut Parser) { | |||
160 | } | 180 | } |
161 | p.expect(R_BRACK); | 181 | p.expect(R_BRACK); |
162 | 182 | ||
163 | m.complete(p, SLICE_PAT); | 183 | m.complete(p, SLICE_PAT) |
164 | } | 184 | } |
165 | 185 | ||
166 | // test bind_pat | 186 | // test bind_pat |
@@ -172,7 +192,7 @@ fn slice_pat(p: &mut Parser) { | |||
172 | // let e @ _ = (); | 192 | // let e @ _ = (); |
173 | // let ref mut f @ g @ _ = (); | 193 | // let ref mut f @ g @ _ = (); |
174 | // } | 194 | // } |
175 | fn bind_pat(p: &mut Parser, with_at: bool) { | 195 | fn bind_pat(p: &mut Parser, with_at: bool) -> CompletedMarker { |
176 | let m = p.start(); | 196 | let m = p.start(); |
177 | p.eat(REF_KW); | 197 | p.eat(REF_KW); |
178 | p.eat(MUT_KW); | 198 | p.eat(MUT_KW); |
@@ -180,5 +200,5 @@ fn bind_pat(p: &mut Parser, with_at: bool) { | |||
180 | if with_at && p.eat(AT) { | 200 | if with_at && p.eat(AT) { |
181 | pattern(p); | 201 | pattern(p); |
182 | } | 202 | } |
183 | m.complete(p, BIND_PAT); | 203 | m.complete(p, BIND_PAT) |
184 | } | 204 | } |