aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/libsyntax2/src/grammar.ron5
-rw-r--r--crates/libsyntax2/src/grammar/expressions/atom.rs61
-rw-r--r--crates/libsyntax2/src/grammar/mod.rs2
-rw-r--r--crates/libsyntax2/src/syntax_kinds/generated.rs10
-rw-r--r--crates/libsyntax2/tests/data/parser/inline/0107_label.rs5
-rw-r--r--crates/libsyntax2/tests/data/parser/inline/0107_label.txt63
6 files changed, 123 insertions, 23 deletions
diff --git a/crates/libsyntax2/src/grammar.ron b/crates/libsyntax2/src/grammar.ron
index dff88cc4a..52764e664 100644
--- a/crates/libsyntax2/src/grammar.ron
+++ b/crates/libsyntax2/src/grammar.ron
@@ -161,11 +161,12 @@ Grammar(
161 "PATH_EXPR", 161 "PATH_EXPR",
162 "LAMBDA_EXPR", 162 "LAMBDA_EXPR",
163 "IF_EXPR", 163 "IF_EXPR",
164 "WHILE_EXPR",
165 "LOOP_EXPR", 164 "LOOP_EXPR",
165 "FOR_EXPR",
166 "WHILE_EXPR",
166 "CONTINUE_EXPR", 167 "CONTINUE_EXPR",
167 "BREAK_EXPR", 168 "BREAK_EXPR",
168 "FOR_EXPR", 169 "LABEL",
169 "BLOCK_EXPR", 170 "BLOCK_EXPR",
170 "RETURN_EXPR", 171 "RETURN_EXPR",
171 "MATCH_EXPR", 172 "MATCH_EXPR",
diff --git a/crates/libsyntax2/src/grammar/expressions/atom.rs b/crates/libsyntax2/src/grammar/expressions/atom.rs
index 9f470d561..9d98340af 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, BREAK_KW, CONTINUE_KW ], 33 IDENT, SELF_KW, SUPER_KW, COLONCOLON, BREAK_KW, CONTINUE_KW, LIFETIME ],
34 ]; 34 ];
35 35
36pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<CompletedMarker> { 36pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<CompletedMarker> {
@@ -48,9 +48,24 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<CompletedMark
48 PIPE => lambda_expr(p), 48 PIPE => lambda_expr(p),
49 MOVE_KW if la == PIPE => lambda_expr(p), 49 MOVE_KW if la == PIPE => lambda_expr(p),
50 IF_KW => if_expr(p), 50 IF_KW => if_expr(p),
51 WHILE_KW => while_expr(p), 51
52 LOOP_KW => loop_expr(p), 52 LOOP_KW => loop_expr(p, None),
53 FOR_KW => for_expr(p), 53 FOR_KW => for_expr(p, None),
54 WHILE_KW => while_expr(p, None),
55 LIFETIME if la == COLON => {
56 let m = p.start();
57 label(p);
58 match p.current() {
59 LOOP_KW => loop_expr(p, Some(m)),
60 FOR_KW => for_expr(p, Some(m)),
61 WHILE_KW => while_expr(p, Some(m)),
62 _ => {
63 p.error("expected a loop");
64 return None;
65 }
66 }
67 }
68
54 MATCH_KW => match_expr(p), 69 MATCH_KW => match_expr(p),
55 UNSAFE_KW if la == L_CURLY => block_expr(p), 70 UNSAFE_KW if la == L_CURLY => block_expr(p),
56 L_CURLY => block_expr(p), 71 L_CURLY => block_expr(p),
@@ -164,39 +179,53 @@ fn if_expr(p: &mut Parser) -> CompletedMarker {
164 m.complete(p, IF_EXPR) 179 m.complete(p, IF_EXPR)
165} 180}
166 181
167// test while_expr 182// test label
168// fn foo() { 183// fn foo() {
169// while true {}; 184// 'a: loop {}
170// while let Some(x) = it.next() {}; 185// 'b: while true {}
186// 'c: for x in () {}
171// } 187// }
172fn while_expr(p: &mut Parser) -> CompletedMarker { 188fn label(p: &mut Parser) {
173 assert!(p.at(WHILE_KW)); 189 assert!(p.at(LIFETIME) && p.nth(1) == COLON);
174 let m = p.start(); 190 let m = p.start();
175 p.bump(); 191 p.bump();
176 cond(p); 192 p.bump();
177 block(p); 193 m.complete(p, LABEL);
178 m.complete(p, WHILE_EXPR)
179} 194}
180 195
181// test loop_expr 196// test loop_expr
182// fn foo() { 197// fn foo() {
183// loop {}; 198// loop {};
184// } 199// }
185fn loop_expr(p: &mut Parser) -> CompletedMarker { 200fn loop_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
186 assert!(p.at(LOOP_KW)); 201 assert!(p.at(LOOP_KW));
187 let m = p.start(); 202 let m = m.unwrap_or_else(|| p.start());
188 p.bump(); 203 p.bump();
189 block(p); 204 block(p);
190 m.complete(p, LOOP_EXPR) 205 m.complete(p, LOOP_EXPR)
191} 206}
192 207
208// test while_expr
209// fn foo() {
210// while true {};
211// while let Some(x) = it.next() {};
212// }
213fn while_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
214 assert!(p.at(WHILE_KW));
215 let m = m.unwrap_or_else(|| p.start());
216 p.bump();
217 cond(p);
218 block(p);
219 m.complete(p, WHILE_EXPR)
220}
221
193// test for_expr 222// test for_expr
194// fn foo() { 223// fn foo() {
195// for x in [] {}; 224// for x in [] {};
196// } 225// }
197fn for_expr(p: &mut Parser) -> CompletedMarker { 226fn for_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
198 assert!(p.at(FOR_KW)); 227 assert!(p.at(FOR_KW));
199 let m = p.start(); 228 let m = m.unwrap_or_else(|| p.start());
200 p.bump(); 229 p.bump();
201 patterns::pattern(p); 230 patterns::pattern(p);
202 p.expect(IN_KW); 231 p.expect(IN_KW);
diff --git a/crates/libsyntax2/src/grammar/mod.rs b/crates/libsyntax2/src/grammar/mod.rs
index 0f168eb60..25887921b 100644
--- a/crates/libsyntax2/src/grammar/mod.rs
+++ b/crates/libsyntax2/src/grammar/mod.rs
@@ -32,7 +32,7 @@ mod type_params;
32mod types; 32mod types;
33 33
34use { 34use {
35 parser_api::{CompletedMarker, Parser, TokenSet}, 35 parser_api::{Marker, CompletedMarker, Parser, TokenSet},
36 SyntaxKind::{self, *}, 36 SyntaxKind::{self, *},
37}; 37};
38 38
diff --git a/crates/libsyntax2/src/syntax_kinds/generated.rs b/crates/libsyntax2/src/syntax_kinds/generated.rs
index 82b6c89cf..61d527f93 100644
--- a/crates/libsyntax2/src/syntax_kinds/generated.rs
+++ b/crates/libsyntax2/src/syntax_kinds/generated.rs
@@ -157,11 +157,12 @@ pub enum SyntaxKind {
157 PATH_EXPR, 157 PATH_EXPR,
158 LAMBDA_EXPR, 158 LAMBDA_EXPR,
159 IF_EXPR, 159 IF_EXPR,
160 WHILE_EXPR,
161 LOOP_EXPR, 160 LOOP_EXPR,
161 FOR_EXPR,
162 WHILE_EXPR,
162 CONTINUE_EXPR, 163 CONTINUE_EXPR,
163 BREAK_EXPR, 164 BREAK_EXPR,
164 FOR_EXPR, 165 LABEL,
165 BLOCK_EXPR, 166 BLOCK_EXPR,
166 RETURN_EXPR, 167 RETURN_EXPR,
167 MATCH_EXPR, 168 MATCH_EXPR,
@@ -406,11 +407,12 @@ impl SyntaxKind {
406 PATH_EXPR => &SyntaxInfo { name: "PATH_EXPR" }, 407 PATH_EXPR => &SyntaxInfo { name: "PATH_EXPR" },
407 LAMBDA_EXPR => &SyntaxInfo { name: "LAMBDA_EXPR" }, 408 LAMBDA_EXPR => &SyntaxInfo { name: "LAMBDA_EXPR" },
408 IF_EXPR => &SyntaxInfo { name: "IF_EXPR" }, 409 IF_EXPR => &SyntaxInfo { name: "IF_EXPR" },
409 WHILE_EXPR => &SyntaxInfo { name: "WHILE_EXPR" },
410 LOOP_EXPR => &SyntaxInfo { name: "LOOP_EXPR" }, 410 LOOP_EXPR => &SyntaxInfo { name: "LOOP_EXPR" },
411 FOR_EXPR => &SyntaxInfo { name: "FOR_EXPR" },
412 WHILE_EXPR => &SyntaxInfo { name: "WHILE_EXPR" },
411 CONTINUE_EXPR => &SyntaxInfo { name: "CONTINUE_EXPR" }, 413 CONTINUE_EXPR => &SyntaxInfo { name: "CONTINUE_EXPR" },
412 BREAK_EXPR => &SyntaxInfo { name: "BREAK_EXPR" }, 414 BREAK_EXPR => &SyntaxInfo { name: "BREAK_EXPR" },
413 FOR_EXPR => &SyntaxInfo { name: "FOR_EXPR" }, 415 LABEL => &SyntaxInfo { name: "LABEL" },
414 BLOCK_EXPR => &SyntaxInfo { name: "BLOCK_EXPR" }, 416 BLOCK_EXPR => &SyntaxInfo { name: "BLOCK_EXPR" },
415 RETURN_EXPR => &SyntaxInfo { name: "RETURN_EXPR" }, 417 RETURN_EXPR => &SyntaxInfo { name: "RETURN_EXPR" },
416 MATCH_EXPR => &SyntaxInfo { name: "MATCH_EXPR" }, 418 MATCH_EXPR => &SyntaxInfo { name: "MATCH_EXPR" },
diff --git a/crates/libsyntax2/tests/data/parser/inline/0107_label.rs b/crates/libsyntax2/tests/data/parser/inline/0107_label.rs
new file mode 100644
index 000000000..48e83f263
--- /dev/null
+++ b/crates/libsyntax2/tests/data/parser/inline/0107_label.rs
@@ -0,0 +1,5 @@
1fn foo() {
2 'a: loop {}
3 'b: while true {}
4 'c: for x in () {}
5}
diff --git a/crates/libsyntax2/tests/data/parser/inline/0107_label.txt b/crates/libsyntax2/tests/data/parser/inline/0107_label.txt
new file mode 100644
index 000000000..66ba792b8
--- /dev/null
+++ b/crates/libsyntax2/tests/data/parser/inline/0107_label.txt
@@ -0,0 +1,63 @@
1FILE@[0; 74)
2 FN_DEF@[0; 73)
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; 73)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 EXPR_STMT@[15; 26)
15 LOOP_EXPR@[15; 26)
16 LABEL@[15; 18)
17 LIFETIME@[15; 17) "'a"
18 COLON@[17; 18)
19 WHITESPACE@[18; 19)
20 LOOP_KW@[19; 23)
21 WHITESPACE@[23; 24)
22 BLOCK_EXPR@[24; 26)
23 L_CURLY@[24; 25)
24 R_CURLY@[25; 26)
25 WHITESPACE@[26; 31)
26 EXPR_STMT@[31; 48)
27 WHILE_EXPR@[31; 48)
28 LABEL@[31; 34)
29 LIFETIME@[31; 33) "'b"
30 COLON@[33; 34)
31 WHITESPACE@[34; 35)
32 WHILE_KW@[35; 40)
33 WHITESPACE@[40; 41)
34 LITERAL@[41; 45)
35 TRUE_KW@[41; 45)
36 WHITESPACE@[45; 46)
37 BLOCK_EXPR@[46; 48)
38 L_CURLY@[46; 47)
39 R_CURLY@[47; 48)
40 WHITESPACE@[48; 53)
41 FOR_EXPR@[53; 71)
42 LABEL@[53; 56)
43 LIFETIME@[53; 55) "'c"
44 COLON@[55; 56)
45 WHITESPACE@[56; 57)
46 FOR_KW@[57; 60)
47 WHITESPACE@[60; 61)
48 BIND_PAT@[61; 62)
49 NAME@[61; 62)
50 IDENT@[61; 62) "x"
51 WHITESPACE@[62; 63)
52 IN_KW@[63; 65)
53 WHITESPACE@[65; 66)
54 TUPLE_EXPR@[66; 68)
55 L_PAREN@[66; 67)
56 R_PAREN@[67; 68)
57 WHITESPACE@[68; 69)
58 BLOCK_EXPR@[69; 71)
59 L_CURLY@[69; 70)
60 R_CURLY@[70; 71)
61 WHITESPACE@[71; 72)
62 R_CURLY@[72; 73)
63 WHITESPACE@[73; 74)