diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/grammar.ron | 3 | ||||
-rw-r--r-- | src/grammar/expressions.rs | 56 | ||||
-rw-r--r-- | src/syntax_kinds/generated.rs | 6 |
3 files changed, 63 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" }, |