diff options
Diffstat (limited to 'crates/libsyntax2/src/grammar/expressions')
-rw-r--r-- | crates/libsyntax2/src/grammar/expressions/atom.rs | 73 | ||||
-rw-r--r-- | crates/libsyntax2/src/grammar/expressions/mod.rs | 67 |
2 files changed, 78 insertions, 62 deletions
diff --git a/crates/libsyntax2/src/grammar/expressions/atom.rs b/crates/libsyntax2/src/grammar/expressions/atom.rs index 9d98340af..417366026 100644 --- a/crates/libsyntax2/src/grammar/expressions/atom.rs +++ b/crates/libsyntax2/src/grammar/expressions/atom.rs | |||
@@ -148,7 +148,11 @@ fn lambda_expr(p: &mut Parser) -> CompletedMarker { | |||
148 | p.eat(MOVE_KW); | 148 | p.eat(MOVE_KW); |
149 | params::param_list_opt_types(p); | 149 | params::param_list_opt_types(p); |
150 | if opt_fn_ret_type(p) { | 150 | if opt_fn_ret_type(p) { |
151 | block(p); | 151 | if p.at(L_CURLY) { |
152 | block(p); | ||
153 | } else { | ||
154 | p.error("expected a block"); | ||
155 | } | ||
152 | } else { | 156 | } else { |
153 | expr(p); | 157 | expr(p); |
154 | } | 158 | } |
@@ -254,6 +258,17 @@ fn match_expr(p: &mut Parser) -> CompletedMarker { | |||
254 | let m = p.start(); | 258 | let m = p.start(); |
255 | p.bump(); | 259 | p.bump(); |
256 | expr_no_struct(p); | 260 | expr_no_struct(p); |
261 | if p.at(L_CURLY) { | ||
262 | match_arm_list(p); | ||
263 | } else { | ||
264 | p.error("expected `{`") | ||
265 | } | ||
266 | m.complete(p, MATCH_EXPR) | ||
267 | } | ||
268 | |||
269 | fn match_arm_list(p: &mut Parser) { | ||
270 | assert!(p.at(L_CURLY)); | ||
271 | let m = p.start(); | ||
257 | p.eat(L_CURLY); | 272 | p.eat(L_CURLY); |
258 | while !p.at(EOF) && !p.at(R_CURLY) { | 273 | while !p.at(EOF) && !p.at(R_CURLY) { |
259 | // test match_arms_commas | 274 | // test match_arms_commas |
@@ -271,7 +286,7 @@ fn match_expr(p: &mut Parser) -> CompletedMarker { | |||
271 | } | 286 | } |
272 | } | 287 | } |
273 | p.expect(R_CURLY); | 288 | p.expect(R_CURLY); |
274 | m.complete(p, MATCH_EXPR) | 289 | m.complete(p, MATCH_ARM_LIST); |
275 | } | 290 | } |
276 | 291 | ||
277 | // test match_arm | 292 | // test match_arm |
@@ -307,62 +322,10 @@ pub(super) fn block_expr(p: &mut Parser) -> CompletedMarker { | |||
307 | assert!(p.at(L_CURLY) || p.at(UNSAFE_KW) && p.nth(1) == L_CURLY); | 322 | assert!(p.at(L_CURLY) || p.at(UNSAFE_KW) && p.nth(1) == L_CURLY); |
308 | let m = p.start(); | 323 | let m = p.start(); |
309 | p.eat(UNSAFE_KW); | 324 | p.eat(UNSAFE_KW); |
310 | p.bump(); | 325 | block(p); |
311 | while !p.at(EOF) && !p.at(R_CURLY) { | ||
312 | match p.current() { | ||
313 | LET_KW => let_stmt(p), | ||
314 | _ => { | ||
315 | // test block_items | ||
316 | // fn a() { fn b() {} } | ||
317 | let m = p.start(); | ||
318 | match items::maybe_item(p, items::ItemFlavor::Mod) { | ||
319 | items::MaybeItem::Item(kind) => { | ||
320 | m.complete(p, kind); | ||
321 | } | ||
322 | items::MaybeItem::Modifiers => { | ||
323 | m.abandon(p); | ||
324 | p.error("expected an item"); | ||
325 | } | ||
326 | // test pub_expr | ||
327 | // fn foo() { pub 92; } //FIXME | ||
328 | items::MaybeItem::None => { | ||
329 | let is_blocklike = expressions::expr_stmt(p) == BlockLike::Block; | ||
330 | if p.eat(SEMI) || (is_blocklike && !p.at(R_CURLY)) { | ||
331 | m.complete(p, EXPR_STMT); | ||
332 | } else { | ||
333 | m.abandon(p); | ||
334 | } | ||
335 | } | ||
336 | } | ||
337 | } | ||
338 | } | ||
339 | } | ||
340 | p.expect(R_CURLY); | ||
341 | m.complete(p, BLOCK_EXPR) | 326 | m.complete(p, BLOCK_EXPR) |
342 | } | 327 | } |
343 | 328 | ||
344 | // test let_stmt; | ||
345 | // fn foo() { | ||
346 | // let a; | ||
347 | // let b: i32; | ||
348 | // let c = 92; | ||
349 | // let d: i32 = 92; | ||
350 | // } | ||
351 | fn let_stmt(p: &mut Parser) { | ||
352 | assert!(p.at(LET_KW)); | ||
353 | let m = p.start(); | ||
354 | p.bump(); | ||
355 | patterns::pattern(p); | ||
356 | if p.at(COLON) { | ||
357 | types::ascription(p); | ||
358 | } | ||
359 | if p.eat(EQ) { | ||
360 | expressions::expr(p); | ||
361 | } | ||
362 | p.expect(SEMI); | ||
363 | m.complete(p, LET_STMT); | ||
364 | } | ||
365 | |||
366 | // test return_expr | 329 | // test return_expr |
367 | // fn foo() { | 330 | // fn foo() { |
368 | // return; | 331 | // return; |
diff --git a/crates/libsyntax2/src/grammar/expressions/mod.rs b/crates/libsyntax2/src/grammar/expressions/mod.rs index 9ce0c1f8f..e133c1d9b 100644 --- a/crates/libsyntax2/src/grammar/expressions/mod.rs +++ b/crates/libsyntax2/src/grammar/expressions/mod.rs | |||
@@ -26,11 +26,62 @@ fn expr_no_struct(p: &mut Parser) { | |||
26 | // fn c() { 1; 2; } | 26 | // fn c() { 1; 2; } |
27 | // fn d() { 1; 2 } | 27 | // fn d() { 1; 2 } |
28 | pub(super) fn block(p: &mut Parser) { | 28 | pub(super) fn block(p: &mut Parser) { |
29 | if !p.at(L_CURLY) { | 29 | assert!(p.at(L_CURLY)); |
30 | p.error("expected block"); | 30 | let m = p.start(); |
31 | return; | 31 | p.bump(); |
32 | while !p.at(EOF) && !p.at(R_CURLY) { | ||
33 | match p.current() { | ||
34 | LET_KW => let_stmt(p), | ||
35 | _ => { | ||
36 | // test block_items | ||
37 | // fn a() { fn b() {} } | ||
38 | let m = p.start(); | ||
39 | match items::maybe_item(p, items::ItemFlavor::Mod) { | ||
40 | items::MaybeItem::Item(kind) => { | ||
41 | m.complete(p, kind); | ||
42 | } | ||
43 | items::MaybeItem::Modifiers => { | ||
44 | m.abandon(p); | ||
45 | p.error("expected an item"); | ||
46 | } | ||
47 | // test pub_expr | ||
48 | // fn foo() { pub 92; } //FIXME | ||
49 | items::MaybeItem::None => { | ||
50 | let is_blocklike = expressions::expr_stmt(p) == BlockLike::Block; | ||
51 | if p.eat(SEMI) || (is_blocklike && !p.at(R_CURLY)) { | ||
52 | m.complete(p, EXPR_STMT); | ||
53 | } else { | ||
54 | m.abandon(p); | ||
55 | } | ||
56 | } | ||
57 | } | ||
58 | } | ||
59 | } | ||
60 | } | ||
61 | p.expect(R_CURLY); | ||
62 | m.complete(p, BLOCK); | ||
63 | |||
64 | // test let_stmt; | ||
65 | // fn foo() { | ||
66 | // let a; | ||
67 | // let b: i32; | ||
68 | // let c = 92; | ||
69 | // let d: i32 = 92; | ||
70 | // } | ||
71 | fn let_stmt(p: &mut Parser) { | ||
72 | assert!(p.at(LET_KW)); | ||
73 | let m = p.start(); | ||
74 | p.bump(); | ||
75 | patterns::pattern(p); | ||
76 | if p.at(COLON) { | ||
77 | types::ascription(p); | ||
78 | } | ||
79 | if p.eat(EQ) { | ||
80 | expressions::expr(p); | ||
81 | } | ||
82 | p.expect(SEMI); | ||
83 | m.complete(p, LET_STMT); | ||
32 | } | 84 | } |
33 | atom::block_expr(p); | ||
34 | } | 85 | } |
35 | 86 | ||
36 | #[derive(Clone, Copy)] | 87 | #[derive(Clone, Copy)] |
@@ -339,7 +390,7 @@ fn path_expr(p: &mut Parser, r: Restrictions) -> CompletedMarker { | |||
339 | paths::expr_path(p); | 390 | paths::expr_path(p); |
340 | match p.current() { | 391 | match p.current() { |
341 | L_CURLY if !r.forbid_structs => { | 392 | L_CURLY if !r.forbid_structs => { |
342 | struct_lit(p); | 393 | named_field_list(p); |
343 | m.complete(p, STRUCT_LIT) | 394 | m.complete(p, STRUCT_LIT) |
344 | } | 395 | } |
345 | EXCL => { | 396 | EXCL => { |
@@ -356,8 +407,9 @@ fn path_expr(p: &mut Parser, r: Restrictions) -> CompletedMarker { | |||
356 | // S { x, y: 32, }; | 407 | // S { x, y: 32, }; |
357 | // S { x, y: 32, ..Default::default() }; | 408 | // S { x, y: 32, ..Default::default() }; |
358 | // } | 409 | // } |
359 | fn struct_lit(p: &mut Parser) { | 410 | fn named_field_list(p: &mut Parser) { |
360 | assert!(p.at(L_CURLY)); | 411 | assert!(p.at(L_CURLY)); |
412 | let m = p.start(); | ||
361 | p.bump(); | 413 | p.bump(); |
362 | while !p.at(EOF) && !p.at(R_CURLY) { | 414 | while !p.at(EOF) && !p.at(R_CURLY) { |
363 | match p.current() { | 415 | match p.current() { |
@@ -367,7 +419,7 @@ fn struct_lit(p: &mut Parser) { | |||
367 | if p.eat(COLON) { | 419 | if p.eat(COLON) { |
368 | expr(p); | 420 | expr(p); |
369 | } | 421 | } |
370 | m.complete(p, STRUCT_LIT_FIELD); | 422 | m.complete(p, NAMED_FIELD); |
371 | } | 423 | } |
372 | DOTDOT => { | 424 | DOTDOT => { |
373 | p.bump(); | 425 | p.bump(); |
@@ -380,4 +432,5 @@ fn struct_lit(p: &mut Parser) { | |||
380 | } | 432 | } |
381 | } | 433 | } |
382 | p.expect(R_CURLY); | 434 | p.expect(R_CURLY); |
435 | m.complete(p, NAMED_FIELD_LIST); | ||
383 | } | 436 | } |