diff options
8 files changed, 156 insertions, 13 deletions
diff --git a/crates/libsyntax2/src/grammar.ron b/crates/libsyntax2/src/grammar.ron index 2cec5b3e3..dff88cc4a 100644 --- a/crates/libsyntax2/src/grammar.ron +++ b/crates/libsyntax2/src/grammar.ron | |||
@@ -75,6 +75,8 @@ Grammar( | |||
75 | "for", | 75 | "for", |
76 | "loop", | 76 | "loop", |
77 | "while", | 77 | "while", |
78 | "continue", | ||
79 | "break", | ||
78 | "if", | 80 | "if", |
79 | "else", | 81 | "else", |
80 | "match", | 82 | "match", |
@@ -161,6 +163,8 @@ Grammar( | |||
161 | "IF_EXPR", | 163 | "IF_EXPR", |
162 | "WHILE_EXPR", | 164 | "WHILE_EXPR", |
163 | "LOOP_EXPR", | 165 | "LOOP_EXPR", |
166 | "CONTINUE_EXPR", | ||
167 | "BREAK_EXPR", | ||
164 | "FOR_EXPR", | 168 | "FOR_EXPR", |
165 | "BLOCK_EXPR", | 169 | "BLOCK_EXPR", |
166 | "RETURN_EXPR", | 170 | "RETURN_EXPR", |
diff --git a/crates/libsyntax2/src/grammar/expressions/atom.rs b/crates/libsyntax2/src/grammar/expressions/atom.rs index 57a887f84..9f470d561 100644 --- a/crates/libsyntax2/src/grammar/expressions/atom.rs +++ b/crates/libsyntax2/src/grammar/expressions/atom.rs | |||
@@ -30,7 +30,7 @@ pub(super) const ATOM_EXPR_FIRST: TokenSet = | |||
30 | token_set_union![ | 30 | token_set_union![ |
31 | LITERAL_FIRST, | 31 | LITERAL_FIRST, |
32 | token_set![L_PAREN, PIPE, MOVE_KW, IF_KW, WHILE_KW, MATCH_KW, UNSAFE_KW, L_CURLY, RETURN_KW, | 32 | token_set![L_PAREN, PIPE, MOVE_KW, IF_KW, WHILE_KW, MATCH_KW, UNSAFE_KW, L_CURLY, RETURN_KW, |
33 | IDENT, SELF_KW, SUPER_KW, COLONCOLON ], | 33 | IDENT, SELF_KW, SUPER_KW, COLONCOLON, BREAK_KW, CONTINUE_KW ], |
34 | ]; | 34 | ]; |
35 | 35 | ||
36 | pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<CompletedMarker> { | 36 | pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<CompletedMarker> { |
@@ -55,6 +55,8 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<CompletedMark | |||
55 | UNSAFE_KW if la == L_CURLY => block_expr(p), | 55 | UNSAFE_KW if la == L_CURLY => block_expr(p), |
56 | L_CURLY => block_expr(p), | 56 | L_CURLY => block_expr(p), |
57 | RETURN_KW => return_expr(p), | 57 | RETURN_KW => return_expr(p), |
58 | CONTINUE_KW => continue_expr(p), | ||
59 | BREAK_KW => break_expr(p), | ||
58 | _ => { | 60 | _ => { |
59 | p.err_and_bump("expected expression"); | 61 | p.err_and_bump("expected expression"); |
60 | return None; | 62 | return None; |
@@ -346,3 +348,38 @@ fn return_expr(p: &mut Parser) -> CompletedMarker { | |||
346 | } | 348 | } |
347 | m.complete(p, RETURN_EXPR) | 349 | m.complete(p, RETURN_EXPR) |
348 | } | 350 | } |
351 | |||
352 | // test continue_expr | ||
353 | // fn foo() { | ||
354 | // loop { | ||
355 | // continue; | ||
356 | // continue 'l; | ||
357 | // } | ||
358 | // } | ||
359 | fn continue_expr(p: &mut Parser) -> CompletedMarker { | ||
360 | assert!(p.at(CONTINUE_KW)); | ||
361 | let m = p.start(); | ||
362 | p.bump(); | ||
363 | p.eat(LIFETIME); | ||
364 | m.complete(p, CONTINUE_EXPR) | ||
365 | } | ||
366 | |||
367 | // test break_expr | ||
368 | // fn foo() { | ||
369 | // loop { | ||
370 | // break; | ||
371 | // break 'l; | ||
372 | // break 92; | ||
373 | // break 'l 92; | ||
374 | // } | ||
375 | // } | ||
376 | fn break_expr(p: &mut Parser) -> CompletedMarker { | ||
377 | assert!(p.at(BREAK_KW)); | ||
378 | let m = p.start(); | ||
379 | p.bump(); | ||
380 | p.eat(LIFETIME); | ||
381 | if EXPR_FIRST.contains(p.current()) { | ||
382 | expr(p); | ||
383 | } | ||
384 | m.complete(p, BREAK_EXPR) | ||
385 | } | ||
diff --git a/crates/libsyntax2/src/syntax_kinds/generated.rs b/crates/libsyntax2/src/syntax_kinds/generated.rs index fc387c93d..82b6c89cf 100644 --- a/crates/libsyntax2/src/syntax_kinds/generated.rs +++ b/crates/libsyntax2/src/syntax_kinds/generated.rs | |||
@@ -82,6 +82,8 @@ pub enum SyntaxKind { | |||
82 | FOR_KW, | 82 | FOR_KW, |
83 | LOOP_KW, | 83 | LOOP_KW, |
84 | WHILE_KW, | 84 | WHILE_KW, |
85 | CONTINUE_KW, | ||
86 | BREAK_KW, | ||
85 | IF_KW, | 87 | IF_KW, |
86 | ELSE_KW, | 88 | ELSE_KW, |
87 | MATCH_KW, | 89 | MATCH_KW, |
@@ -157,6 +159,8 @@ pub enum SyntaxKind { | |||
157 | IF_EXPR, | 159 | IF_EXPR, |
158 | WHILE_EXPR, | 160 | WHILE_EXPR, |
159 | LOOP_EXPR, | 161 | LOOP_EXPR, |
162 | CONTINUE_EXPR, | ||
163 | BREAK_EXPR, | ||
160 | FOR_EXPR, | 164 | FOR_EXPR, |
161 | BLOCK_EXPR, | 165 | BLOCK_EXPR, |
162 | RETURN_EXPR, | 166 | RETURN_EXPR, |
@@ -232,6 +236,8 @@ impl SyntaxKind { | |||
232 | | FOR_KW | 236 | | FOR_KW |
233 | | LOOP_KW | 237 | | LOOP_KW |
234 | | WHILE_KW | 238 | | WHILE_KW |
239 | | CONTINUE_KW | ||
240 | | BREAK_KW | ||
235 | | IF_KW | 241 | | IF_KW |
236 | | ELSE_KW | 242 | | ELSE_KW |
237 | | MATCH_KW | 243 | | MATCH_KW |
@@ -325,6 +331,8 @@ impl SyntaxKind { | |||
325 | FOR_KW => &SyntaxInfo { name: "FOR_KW" }, | 331 | FOR_KW => &SyntaxInfo { name: "FOR_KW" }, |
326 | LOOP_KW => &SyntaxInfo { name: "LOOP_KW" }, | 332 | LOOP_KW => &SyntaxInfo { name: "LOOP_KW" }, |
327 | WHILE_KW => &SyntaxInfo { name: "WHILE_KW" }, | 333 | WHILE_KW => &SyntaxInfo { name: "WHILE_KW" }, |
334 | CONTINUE_KW => &SyntaxInfo { name: "CONTINUE_KW" }, | ||
335 | BREAK_KW => &SyntaxInfo { name: "BREAK_KW" }, | ||
328 | IF_KW => &SyntaxInfo { name: "IF_KW" }, | 336 | IF_KW => &SyntaxInfo { name: "IF_KW" }, |
329 | ELSE_KW => &SyntaxInfo { name: "ELSE_KW" }, | 337 | ELSE_KW => &SyntaxInfo { name: "ELSE_KW" }, |
330 | MATCH_KW => &SyntaxInfo { name: "MATCH_KW" }, | 338 | MATCH_KW => &SyntaxInfo { name: "MATCH_KW" }, |
@@ -400,6 +408,8 @@ impl SyntaxKind { | |||
400 | IF_EXPR => &SyntaxInfo { name: "IF_EXPR" }, | 408 | IF_EXPR => &SyntaxInfo { name: "IF_EXPR" }, |
401 | WHILE_EXPR => &SyntaxInfo { name: "WHILE_EXPR" }, | 409 | WHILE_EXPR => &SyntaxInfo { name: "WHILE_EXPR" }, |
402 | LOOP_EXPR => &SyntaxInfo { name: "LOOP_EXPR" }, | 410 | LOOP_EXPR => &SyntaxInfo { name: "LOOP_EXPR" }, |
411 | CONTINUE_EXPR => &SyntaxInfo { name: "CONTINUE_EXPR" }, | ||
412 | BREAK_EXPR => &SyntaxInfo { name: "BREAK_EXPR" }, | ||
403 | FOR_EXPR => &SyntaxInfo { name: "FOR_EXPR" }, | 413 | FOR_EXPR => &SyntaxInfo { name: "FOR_EXPR" }, |
404 | BLOCK_EXPR => &SyntaxInfo { name: "BLOCK_EXPR" }, | 414 | BLOCK_EXPR => &SyntaxInfo { name: "BLOCK_EXPR" }, |
405 | RETURN_EXPR => &SyntaxInfo { name: "RETURN_EXPR" }, | 415 | RETURN_EXPR => &SyntaxInfo { name: "RETURN_EXPR" }, |
@@ -475,6 +485,8 @@ impl SyntaxKind { | |||
475 | "for" => FOR_KW, | 485 | "for" => FOR_KW, |
476 | "loop" => LOOP_KW, | 486 | "loop" => LOOP_KW, |
477 | "while" => WHILE_KW, | 487 | "while" => WHILE_KW, |
488 | "continue" => CONTINUE_KW, | ||
489 | "break" => BREAK_KW, | ||
478 | "if" => IF_KW, | 490 | "if" => IF_KW, |
479 | "else" => ELSE_KW, | 491 | "else" => ELSE_KW, |
480 | "match" => MATCH_KW, | 492 | "match" => MATCH_KW, |
diff --git a/crates/libsyntax2/tests/data/parser/err/0012_broken_lambda.rs b/crates/libsyntax2/tests/data/parser/err/0012_broken_lambda.rs deleted file mode 100644 index ad0d8eb4c..000000000 --- a/crates/libsyntax2/tests/data/parser/err/0012_broken_lambda.rs +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | pub(super) fn process<'a, S: Sink<'a>>(builder: &mut S, tokens: &[Token], events: Vec<Event>) { | ||
2 | let mut next_tok_idx = 0; | ||
3 | let eat_ws = |idx: &mut usize, &mut | { | ||
4 | while let Some(token) = tokens.get(*idx) { | ||
5 | if !token.kind.is_trivia() { | ||
6 | break; | ||
7 | } | ||
8 | builder.leaf(token.kind, token.len); | ||
9 | *idx += 1 | ||
10 | } | ||
11 | }; | ||
12 | } | ||
diff --git a/crates/libsyntax2/tests/data/parser/inline/0105_continue_expr.rs b/crates/libsyntax2/tests/data/parser/inline/0105_continue_expr.rs new file mode 100644 index 000000000..474cc3f0e --- /dev/null +++ b/crates/libsyntax2/tests/data/parser/inline/0105_continue_expr.rs | |||
@@ -0,0 +1,6 @@ | |||
1 | fn foo() { | ||
2 | loop { | ||
3 | continue; | ||
4 | continue 'l; | ||
5 | } | ||
6 | } | ||
diff --git a/crates/libsyntax2/tests/data/parser/inline/0105_continue_expr.txt b/crates/libsyntax2/tests/data/parser/inline/0105_continue_expr.txt new file mode 100644 index 000000000..05526fda6 --- /dev/null +++ b/crates/libsyntax2/tests/data/parser/inline/0105_continue_expr.txt | |||
@@ -0,0 +1,35 @@ | |||
1 | FILE@[0; 69) | ||
2 | FN_DEF@[0; 68) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK_EXPR@[9; 68) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | LOOP_EXPR@[15; 66) | ||
15 | LOOP_KW@[15; 19) | ||
16 | WHITESPACE@[19; 20) | ||
17 | BLOCK_EXPR@[20; 66) | ||
18 | L_CURLY@[20; 21) | ||
19 | WHITESPACE@[21; 30) | ||
20 | EXPR_STMT@[30; 39) | ||
21 | CONTINUE_EXPR@[30; 38) | ||
22 | CONTINUE_KW@[30; 38) | ||
23 | SEMI@[38; 39) | ||
24 | WHITESPACE@[39; 48) | ||
25 | EXPR_STMT@[48; 60) | ||
26 | CONTINUE_EXPR@[48; 59) | ||
27 | CONTINUE_KW@[48; 56) | ||
28 | WHITESPACE@[56; 57) | ||
29 | LIFETIME@[57; 59) "'l" | ||
30 | SEMI@[59; 60) | ||
31 | WHITESPACE@[60; 65) | ||
32 | R_CURLY@[65; 66) | ||
33 | WHITESPACE@[66; 67) | ||
34 | R_CURLY@[67; 68) | ||
35 | WHITESPACE@[68; 69) | ||
diff --git a/crates/libsyntax2/tests/data/parser/inline/0106_break_expr.rs b/crates/libsyntax2/tests/data/parser/inline/0106_break_expr.rs new file mode 100644 index 000000000..1b4094636 --- /dev/null +++ b/crates/libsyntax2/tests/data/parser/inline/0106_break_expr.rs | |||
@@ -0,0 +1,8 @@ | |||
1 | fn foo() { | ||
2 | loop { | ||
3 | break; | ||
4 | break 'l; | ||
5 | break 92; | ||
6 | break 'l 92; | ||
7 | } | ||
8 | } | ||
diff --git a/crates/libsyntax2/tests/data/parser/inline/0106_break_expr.txt b/crates/libsyntax2/tests/data/parser/inline/0106_break_expr.txt new file mode 100644 index 000000000..bb490e441 --- /dev/null +++ b/crates/libsyntax2/tests/data/parser/inline/0106_break_expr.txt | |||
@@ -0,0 +1,53 @@ | |||
1 | FILE@[0; 102) | ||
2 | FN_DEF@[0; 101) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK_EXPR@[9; 101) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | LOOP_EXPR@[15; 99) | ||
15 | LOOP_KW@[15; 19) | ||
16 | WHITESPACE@[19; 20) | ||
17 | BLOCK_EXPR@[20; 99) | ||
18 | L_CURLY@[20; 21) | ||
19 | WHITESPACE@[21; 30) | ||
20 | EXPR_STMT@[30; 36) | ||
21 | BREAK_EXPR@[30; 35) | ||
22 | BREAK_KW@[30; 35) | ||
23 | SEMI@[35; 36) | ||
24 | WHITESPACE@[36; 45) | ||
25 | EXPR_STMT@[45; 54) | ||
26 | BREAK_EXPR@[45; 53) | ||
27 | BREAK_KW@[45; 50) | ||
28 | WHITESPACE@[50; 51) | ||
29 | LIFETIME@[51; 53) "'l" | ||
30 | SEMI@[53; 54) | ||
31 | WHITESPACE@[54; 63) | ||
32 | EXPR_STMT@[63; 72) | ||
33 | BREAK_EXPR@[63; 71) | ||
34 | BREAK_KW@[63; 68) | ||
35 | WHITESPACE@[68; 69) | ||
36 | LITERAL@[69; 71) | ||
37 | INT_NUMBER@[69; 71) "92" | ||
38 | SEMI@[71; 72) | ||
39 | WHITESPACE@[72; 81) | ||
40 | EXPR_STMT@[81; 93) | ||
41 | BREAK_EXPR@[81; 92) | ||
42 | BREAK_KW@[81; 86) | ||
43 | WHITESPACE@[86; 87) | ||
44 | LIFETIME@[87; 89) "'l" | ||
45 | WHITESPACE@[89; 90) | ||
46 | LITERAL@[90; 92) | ||
47 | INT_NUMBER@[90; 92) "92" | ||
48 | SEMI@[92; 93) | ||
49 | WHITESPACE@[93; 98) | ||
50 | R_CURLY@[98; 99) | ||
51 | WHITESPACE@[99; 100) | ||
52 | R_CURLY@[100; 101) | ||
53 | WHITESPACE@[101; 102) | ||