diff options
-rw-r--r-- | src/grammar.ron | 3 | ||||
-rw-r--r-- | src/grammar/expressions.rs | 56 | ||||
-rw-r--r-- | src/syntax_kinds/generated.rs | 6 | ||||
-rw-r--r-- | tests/data/parser/inline/0069_match_arm.rs | 6 | ||||
-rw-r--r-- | tests/data/parser/inline/0069_match_arm.txt | 65 | ||||
-rw-r--r-- | tests/data/parser/inline/0070_match_expr.rs | 3 | ||||
-rw-r--r-- | tests/data/parser/inline/0070_match_expr.txt | 28 |
7 files changed, 165 insertions, 2 deletions
diff --git a/src/grammar.ron b/src/grammar.ron index 8e8a71010..0239a3c1d 100644 --- a/src/grammar.ron +++ b/src/grammar.ron | |||
@@ -141,6 +141,9 @@ Grammar( | |||
141 | "IF_EXPR", | 141 | "IF_EXPR", |
142 | "BLOCK_EXPR", | 142 | "BLOCK_EXPR", |
143 | "RETURN_EXPR", | 143 | "RETURN_EXPR", |
144 | "MATCH_EXPR", | ||
145 | "MATCH_ARM", | ||
146 | "MATCH_GUARD", | ||
144 | 147 | ||
145 | "EXTERN_BLOCK_EXPR", | 148 | "EXTERN_BLOCK_EXPR", |
146 | "ENUM_VARIANT", | 149 | "ENUM_VARIANT", |
diff --git a/src/grammar/expressions.rs b/src/grammar/expressions.rs index c68419929..6506892e1 100644 --- a/src/grammar/expressions.rs +++ b/src/grammar/expressions.rs | |||
@@ -27,6 +27,7 @@ pub(super) fn literal(p: &mut Parser) -> Option<CompletedMarker> { | |||
27 | } | 27 | } |
28 | 28 | ||
29 | const EXPR_FIRST: TokenSet = PREFIX_EXPR_FIRST; | 29 | const EXPR_FIRST: TokenSet = PREFIX_EXPR_FIRST; |
30 | |||
30 | pub(super) fn expr(p: &mut Parser) { | 31 | pub(super) fn expr(p: &mut Parser) { |
31 | let mut lhs = match prefix_expr(p) { | 32 | let mut lhs = match prefix_expr(p) { |
32 | Some(lhs) => lhs, | 33 | Some(lhs) => lhs, |
@@ -87,6 +88,7 @@ const PREFIX_EXPR_FIRST: TokenSet = | |||
87 | token_set![AMPERSAND, STAR, EXCL], | 88 | token_set![AMPERSAND, STAR, EXCL], |
88 | ATOM_EXPR_FIRST, | 89 | ATOM_EXPR_FIRST, |
89 | ]; | 90 | ]; |
91 | |||
90 | fn prefix_expr(p: &mut Parser) -> Option<CompletedMarker> { | 92 | fn prefix_expr(p: &mut Parser) -> Option<CompletedMarker> { |
91 | let done = match p.current() { | 93 | let done = match p.current() { |
92 | AMPERSAND => ref_expr(p), | 94 | AMPERSAND => ref_expr(p), |
@@ -140,6 +142,7 @@ const ATOM_EXPR_FIRST: TokenSet = | |||
140 | LITERAL_FIRST, | 142 | LITERAL_FIRST, |
141 | token_set![L_PAREN, PIPE, MOVE_KW, IF_KW, UNSAFE_KW, L_CURLY, RETURN_KW], | 143 | token_set![L_PAREN, PIPE, MOVE_KW, IF_KW, UNSAFE_KW, L_CURLY, RETURN_KW], |
142 | ]; | 144 | ]; |
145 | |||
143 | fn atom_expr(p: &mut Parser) -> Option<CompletedMarker> { | 146 | fn atom_expr(p: &mut Parser) -> Option<CompletedMarker> { |
144 | match literal(p) { | 147 | match literal(p) { |
145 | Some(m) => return Some(m), | 148 | Some(m) => return Some(m), |
@@ -154,6 +157,7 @@ fn atom_expr(p: &mut Parser) -> Option<CompletedMarker> { | |||
154 | PIPE => lambda_expr(p), | 157 | PIPE => lambda_expr(p), |
155 | MOVE_KW if la == PIPE => lambda_expr(p), | 158 | MOVE_KW if la == PIPE => lambda_expr(p), |
156 | IF_KW => if_expr(p), | 159 | IF_KW => if_expr(p), |
160 | MATCH_KW => match_expr(p), | ||
157 | UNSAFE_KW if la == L_CURLY => block_expr(p), | 161 | UNSAFE_KW if la == L_CURLY => block_expr(p), |
158 | L_CURLY => block_expr(p), | 162 | L_CURLY => block_expr(p), |
159 | RETURN_KW => return_expr(p), | 163 | RETURN_KW => return_expr(p), |
@@ -202,8 +206,7 @@ fn lambda_expr(p: &mut Parser) -> CompletedMarker { | |||
202 | fn if_expr(p: &mut Parser) -> CompletedMarker { | 206 | fn if_expr(p: &mut Parser) -> CompletedMarker { |
203 | assert!(p.at(IF_KW)); | 207 | assert!(p.at(IF_KW)); |
204 | let m = p.start(); | 208 | let m = p.start(); |
205 | p.bump(); | 209 | if_head(p); |
206 | expr(p); | ||
207 | block(p); | 210 | block(p); |
208 | if p.at(ELSE_KW) { | 211 | if p.at(ELSE_KW) { |
209 | p.bump(); | 212 | p.bump(); |
@@ -216,6 +219,55 @@ fn if_expr(p: &mut Parser) -> CompletedMarker { | |||
216 | m.complete(p, IF_EXPR) | 219 | m.complete(p, IF_EXPR) |
217 | } | 220 | } |
218 | 221 | ||
222 | fn if_head(p: &mut Parser) { | ||
223 | assert!(p.at(IF_KW)); | ||
224 | p.bump(); | ||
225 | expr(p); | ||
226 | } | ||
227 | |||
228 | // test match_expr | ||
229 | // fn foo() { | ||
230 | // match () { }; | ||
231 | // } | ||
232 | fn match_expr(p: &mut Parser) -> CompletedMarker { | ||
233 | assert!(p.at(MATCH_KW)); | ||
234 | let m = p.start(); | ||
235 | p.bump(); | ||
236 | expr(p); | ||
237 | p.eat(L_CURLY); | ||
238 | while !p.at(EOF) && !p.at(R_CURLY) { | ||
239 | match_arm(p); | ||
240 | if !p.at(R_CURLY) { | ||
241 | p.expect(COMMA); | ||
242 | } | ||
243 | } | ||
244 | p.expect(R_CURLY); | ||
245 | m.complete(p, MATCH_EXPR) | ||
246 | } | ||
247 | |||
248 | // test match_arm | ||
249 | // fn foo() { | ||
250 | // match () { | ||
251 | // _ => (), | ||
252 | // X | Y if Z => (), | ||
253 | // }; | ||
254 | // } | ||
255 | fn match_arm(p: &mut Parser) { | ||
256 | let m = p.start(); | ||
257 | loop { | ||
258 | patterns::pattern(p); | ||
259 | if !p.eat(PIPE) { | ||
260 | break; | ||
261 | } | ||
262 | } | ||
263 | if p.at(IF_KW) { | ||
264 | if_head(p) | ||
265 | } | ||
266 | p.expect(FAT_ARROW); | ||
267 | expr(p); | ||
268 | m.complete(p, MATCH_ARM); | ||
269 | } | ||
270 | |||
219 | // test block_expr | 271 | // test block_expr |
220 | // fn foo() { | 272 | // fn foo() { |
221 | // {}; | 273 | // {}; |
diff --git a/src/syntax_kinds/generated.rs b/src/syntax_kinds/generated.rs index 50aa2b580..73b26b274 100644 --- a/src/syntax_kinds/generated.rs +++ b/src/syntax_kinds/generated.rs | |||
@@ -132,6 +132,9 @@ pub enum SyntaxKind { | |||
132 | IF_EXPR, | 132 | IF_EXPR, |
133 | BLOCK_EXPR, | 133 | BLOCK_EXPR, |
134 | RETURN_EXPR, | 134 | RETURN_EXPR, |
135 | MATCH_EXPR, | ||
136 | MATCH_ARM, | ||
137 | MATCH_GUARD, | ||
135 | EXTERN_BLOCK_EXPR, | 138 | EXTERN_BLOCK_EXPR, |
136 | ENUM_VARIANT, | 139 | ENUM_VARIANT, |
137 | NAMED_FIELD, | 140 | NAMED_FIELD, |
@@ -342,6 +345,9 @@ impl SyntaxKind { | |||
342 | IF_EXPR => &SyntaxInfo { name: "IF_EXPR" }, | 345 | IF_EXPR => &SyntaxInfo { name: "IF_EXPR" }, |
343 | BLOCK_EXPR => &SyntaxInfo { name: "BLOCK_EXPR" }, | 346 | BLOCK_EXPR => &SyntaxInfo { name: "BLOCK_EXPR" }, |
344 | RETURN_EXPR => &SyntaxInfo { name: "RETURN_EXPR" }, | 347 | RETURN_EXPR => &SyntaxInfo { name: "RETURN_EXPR" }, |
348 | MATCH_EXPR => &SyntaxInfo { name: "MATCH_EXPR" }, | ||
349 | MATCH_ARM => &SyntaxInfo { name: "MATCH_ARM" }, | ||
350 | MATCH_GUARD => &SyntaxInfo { name: "MATCH_GUARD" }, | ||
345 | EXTERN_BLOCK_EXPR => &SyntaxInfo { name: "EXTERN_BLOCK_EXPR" }, | 351 | EXTERN_BLOCK_EXPR => &SyntaxInfo { name: "EXTERN_BLOCK_EXPR" }, |
346 | ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" }, | 352 | ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" }, |
347 | NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" }, | 353 | NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" }, |
diff --git a/tests/data/parser/inline/0069_match_arm.rs b/tests/data/parser/inline/0069_match_arm.rs new file mode 100644 index 000000000..2c0e88414 --- /dev/null +++ b/tests/data/parser/inline/0069_match_arm.rs | |||
@@ -0,0 +1,6 @@ | |||
1 | fn foo() { | ||
2 | match () { | ||
3 | _ => (), | ||
4 | X | Y if Z => (), | ||
5 | }; | ||
6 | } | ||
diff --git a/tests/data/parser/inline/0069_match_arm.txt b/tests/data/parser/inline/0069_match_arm.txt new file mode 100644 index 000000000..efdee2568 --- /dev/null +++ b/tests/data/parser/inline/0069_match_arm.txt | |||
@@ -0,0 +1,65 @@ | |||
1 | FILE@[0; 78) | ||
2 | FN_ITEM@[0; 78) | ||
3 | FN_KW@[0; 2) | ||
4 | NAME@[2; 6) | ||
5 | WHITESPACE@[2; 3) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 9) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK_EXPR@[9; 78) | ||
12 | L_CURLY@[9; 10) | ||
13 | EXPR_STMT@[10; 76) | ||
14 | MATCH_EXPR@[10; 74) | ||
15 | WHITESPACE@[10; 15) | ||
16 | MATCH_KW@[15; 20) | ||
17 | TUPLE_EXPR@[20; 24) | ||
18 | WHITESPACE@[20; 21) | ||
19 | L_PAREN@[21; 22) | ||
20 | R_PAREN@[22; 23) | ||
21 | WHITESPACE@[23; 24) | ||
22 | L_CURLY@[24; 25) | ||
23 | MATCH_ARM@[25; 41) | ||
24 | PLACEHOLDER_PAT@[25; 36) | ||
25 | WHITESPACE@[25; 34) | ||
26 | UNDERSCORE@[34; 35) | ||
27 | WHITESPACE@[35; 36) | ||
28 | FAT_ARROW@[36; 38) | ||
29 | TUPLE_EXPR@[38; 41) | ||
30 | WHITESPACE@[38; 39) | ||
31 | L_PAREN@[39; 40) | ||
32 | R_PAREN@[40; 41) | ||
33 | COMMA@[41; 42) | ||
34 | MATCH_ARM@[42; 67) | ||
35 | BIND_PAT@[42; 53) | ||
36 | NAME@[42; 53) | ||
37 | WHITESPACE@[42; 51) | ||
38 | IDENT@[51; 52) "X" | ||
39 | WHITESPACE@[52; 53) | ||
40 | PIPE@[53; 54) | ||
41 | BIND_PAT@[54; 57) | ||
42 | NAME@[54; 57) | ||
43 | WHITESPACE@[54; 55) | ||
44 | IDENT@[55; 56) "Y" | ||
45 | WHITESPACE@[56; 57) | ||
46 | IF_KW@[57; 59) | ||
47 | PATH_EXPR@[59; 62) | ||
48 | PATH@[59; 62) | ||
49 | PATH_SEGMENT@[59; 62) | ||
50 | NAME_REF@[59; 62) | ||
51 | WHITESPACE@[59; 60) | ||
52 | IDENT@[60; 61) "Z" | ||
53 | WHITESPACE@[61; 62) | ||
54 | FAT_ARROW@[62; 64) | ||
55 | TUPLE_EXPR@[64; 67) | ||
56 | WHITESPACE@[64; 65) | ||
57 | L_PAREN@[65; 66) | ||
58 | R_PAREN@[66; 67) | ||
59 | COMMA@[67; 68) | ||
60 | WHITESPACE@[68; 73) | ||
61 | R_CURLY@[73; 74) | ||
62 | SEMI@[74; 75) | ||
63 | WHITESPACE@[75; 76) | ||
64 | R_CURLY@[76; 77) | ||
65 | WHITESPACE@[77; 78) | ||
diff --git a/tests/data/parser/inline/0070_match_expr.rs b/tests/data/parser/inline/0070_match_expr.rs new file mode 100644 index 000000000..40318b350 --- /dev/null +++ b/tests/data/parser/inline/0070_match_expr.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | fn foo() { | ||
2 | match () { }; | ||
3 | } | ||
diff --git a/tests/data/parser/inline/0070_match_expr.txt b/tests/data/parser/inline/0070_match_expr.txt new file mode 100644 index 000000000..2dc2f4130 --- /dev/null +++ b/tests/data/parser/inline/0070_match_expr.txt | |||
@@ -0,0 +1,28 @@ | |||
1 | FILE@[0; 31) | ||
2 | FN_ITEM@[0; 31) | ||
3 | FN_KW@[0; 2) | ||
4 | NAME@[2; 6) | ||
5 | WHITESPACE@[2; 3) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 9) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK_EXPR@[9; 31) | ||
12 | L_CURLY@[9; 10) | ||
13 | EXPR_STMT@[10; 29) | ||
14 | MATCH_EXPR@[10; 27) | ||
15 | WHITESPACE@[10; 15) | ||
16 | MATCH_KW@[15; 20) | ||
17 | TUPLE_EXPR@[20; 24) | ||
18 | WHITESPACE@[20; 21) | ||
19 | L_PAREN@[21; 22) | ||
20 | R_PAREN@[22; 23) | ||
21 | WHITESPACE@[23; 24) | ||
22 | L_CURLY@[24; 25) | ||
23 | WHITESPACE@[25; 26) | ||
24 | R_CURLY@[26; 27) | ||
25 | SEMI@[27; 28) | ||
26 | WHITESPACE@[28; 29) | ||
27 | R_CURLY@[29; 30) | ||
28 | WHITESPACE@[30; 31) | ||