aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/grammar.ron3
-rw-r--r--src/grammar/expressions.rs56
-rw-r--r--src/syntax_kinds/generated.rs6
-rw-r--r--tests/data/parser/inline/0069_match_arm.rs6
-rw-r--r--tests/data/parser/inline/0069_match_arm.txt65
-rw-r--r--tests/data/parser/inline/0070_match_expr.rs3
-rw-r--r--tests/data/parser/inline/0070_match_expr.txt28
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
29const EXPR_FIRST: TokenSet = PREFIX_EXPR_FIRST; 29const EXPR_FIRST: TokenSet = PREFIX_EXPR_FIRST;
30
30pub(super) fn expr(p: &mut Parser) { 31pub(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
90fn prefix_expr(p: &mut Parser) -> Option<CompletedMarker> { 92fn 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
143fn atom_expr(p: &mut Parser) -> Option<CompletedMarker> { 146fn 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 {
202fn if_expr(p: &mut Parser) -> CompletedMarker { 206fn 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
222fn 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// }
232fn 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// }
255fn 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 @@
1fn 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 @@
1FILE@[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 @@
1fn 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 @@
1FILE@[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)