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 | |
parent | bfb90dc4f1e9d86a24207b252c5f3405037928b1 (diff) |
Range patterns
-rw-r--r-- | src/grammar.ron | 1 | ||||
-rw-r--r-- | src/grammar/patterns.rs | 64 | ||||
-rw-r--r-- | src/syntax_kinds/generated.rs | 2 | ||||
-rw-r--r-- | tests/data/parser/inline/0094_range_pat.rs | 3 | ||||
-rw-r--r-- | tests/data/parser/inline/0094_range_pat.txt | 41 |
5 files changed, 89 insertions, 22 deletions
diff --git a/src/grammar.ron b/src/grammar.ron index f1c3502bc..df1dfe050 100644 --- a/src/grammar.ron +++ b/src/grammar.ron | |||
@@ -143,6 +143,7 @@ Grammar( | |||
143 | "TUPLE_STRUCT_PAT", | 143 | "TUPLE_STRUCT_PAT", |
144 | "TUPLE_PAT", | 144 | "TUPLE_PAT", |
145 | "SLICE_PAT", | 145 | "SLICE_PAT", |
146 | "RANGE_PAT", | ||
146 | 147 | ||
147 | // atoms | 148 | // atoms |
148 | "TUPLE_EXPR", | 149 | "TUPLE_EXPR", |
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 | } |
diff --git a/src/syntax_kinds/generated.rs b/src/syntax_kinds/generated.rs index 0c6a1f8e7..a74acf6eb 100644 --- a/src/syntax_kinds/generated.rs +++ b/src/syntax_kinds/generated.rs | |||
@@ -135,6 +135,7 @@ pub enum SyntaxKind { | |||
135 | TUPLE_STRUCT_PAT, | 135 | TUPLE_STRUCT_PAT, |
136 | TUPLE_PAT, | 136 | TUPLE_PAT, |
137 | SLICE_PAT, | 137 | SLICE_PAT, |
138 | RANGE_PAT, | ||
138 | TUPLE_EXPR, | 139 | TUPLE_EXPR, |
139 | ARRAY_EXPR, | 140 | ARRAY_EXPR, |
140 | PAREN_EXPR, | 141 | PAREN_EXPR, |
@@ -374,6 +375,7 @@ impl SyntaxKind { | |||
374 | TUPLE_STRUCT_PAT => &SyntaxInfo { name: "TUPLE_STRUCT_PAT" }, | 375 | TUPLE_STRUCT_PAT => &SyntaxInfo { name: "TUPLE_STRUCT_PAT" }, |
375 | TUPLE_PAT => &SyntaxInfo { name: "TUPLE_PAT" }, | 376 | TUPLE_PAT => &SyntaxInfo { name: "TUPLE_PAT" }, |
376 | SLICE_PAT => &SyntaxInfo { name: "SLICE_PAT" }, | 377 | SLICE_PAT => &SyntaxInfo { name: "SLICE_PAT" }, |
378 | RANGE_PAT => &SyntaxInfo { name: "RANGE_PAT" }, | ||
377 | TUPLE_EXPR => &SyntaxInfo { name: "TUPLE_EXPR" }, | 379 | TUPLE_EXPR => &SyntaxInfo { name: "TUPLE_EXPR" }, |
378 | ARRAY_EXPR => &SyntaxInfo { name: "ARRAY_EXPR" }, | 380 | ARRAY_EXPR => &SyntaxInfo { name: "ARRAY_EXPR" }, |
379 | PAREN_EXPR => &SyntaxInfo { name: "PAREN_EXPR" }, | 381 | PAREN_EXPR => &SyntaxInfo { name: "PAREN_EXPR" }, |
diff --git a/tests/data/parser/inline/0094_range_pat.rs b/tests/data/parser/inline/0094_range_pat.rs new file mode 100644 index 000000000..657467e75 --- /dev/null +++ b/tests/data/parser/inline/0094_range_pat.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | fn main() { | ||
2 | match 92 { 0 ... 100 => () } | ||
3 | } | ||
diff --git a/tests/data/parser/inline/0094_range_pat.txt b/tests/data/parser/inline/0094_range_pat.txt new file mode 100644 index 000000000..01aed336b --- /dev/null +++ b/tests/data/parser/inline/0094_range_pat.txt | |||
@@ -0,0 +1,41 @@ | |||
1 | FILE@[0; 47) | ||
2 | FN_ITEM@[0; 46) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 7) | ||
6 | IDENT@[3; 7) "main" | ||
7 | PARAM_LIST@[7; 9) | ||
8 | L_PAREN@[7; 8) | ||
9 | R_PAREN@[8; 9) | ||
10 | WHITESPACE@[9; 10) | ||
11 | BLOCK_EXPR@[10; 46) | ||
12 | L_CURLY@[10; 11) | ||
13 | WHITESPACE@[11; 16) | ||
14 | MATCH_EXPR@[16; 44) | ||
15 | MATCH_KW@[16; 21) | ||
16 | WHITESPACE@[21; 22) | ||
17 | LITERAL@[22; 24) | ||
18 | INT_NUMBER@[22; 24) "92" | ||
19 | WHITESPACE@[24; 25) | ||
20 | L_CURLY@[25; 26) | ||
21 | WHITESPACE@[26; 27) | ||
22 | MATCH_ARM@[27; 42) | ||
23 | RANGE_PAT@[27; 36) | ||
24 | LITERAL@[27; 28) | ||
25 | INT_NUMBER@[27; 28) "0" | ||
26 | WHITESPACE@[28; 29) | ||
27 | DOTDOTDOT@[29; 32) | ||
28 | WHITESPACE@[32; 33) | ||
29 | LITERAL@[33; 36) | ||
30 | INT_NUMBER@[33; 36) "100" | ||
31 | WHITESPACE@[36; 37) | ||
32 | FAT_ARROW@[37; 39) | ||
33 | WHITESPACE@[39; 40) | ||
34 | TUPLE_EXPR@[40; 42) | ||
35 | L_PAREN@[40; 41) | ||
36 | R_PAREN@[41; 42) | ||
37 | WHITESPACE@[42; 43) | ||
38 | R_CURLY@[43; 44) | ||
39 | WHITESPACE@[44; 45) | ||
40 | R_CURLY@[45; 46) | ||
41 | WHITESPACE@[46; 47) | ||