aboutsummaryrefslogtreecommitdiff
path: root/crates/libsyntax2/src/grammar/expressions/atom.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-08-10 20:33:29 +0100
committerAleksey Kladov <[email protected]>2018-08-10 20:33:29 +0100
commit7c67612b8a894187fa3b64725531a5459f9211bf (patch)
tree9e2a536efa0c880d921fd8d4d74423afc9451fd4 /crates/libsyntax2/src/grammar/expressions/atom.rs
parent26262aaf05983c5b7f41cc438e287523268fe1eb (diff)
organizize
Diffstat (limited to 'crates/libsyntax2/src/grammar/expressions/atom.rs')
-rw-r--r--crates/libsyntax2/src/grammar/expressions/atom.rs348
1 files changed, 348 insertions, 0 deletions
diff --git a/crates/libsyntax2/src/grammar/expressions/atom.rs b/crates/libsyntax2/src/grammar/expressions/atom.rs
new file mode 100644
index 000000000..af9f47c5e
--- /dev/null
+++ b/crates/libsyntax2/src/grammar/expressions/atom.rs
@@ -0,0 +1,348 @@
1use super::*;
2
3// test expr_literals
4// fn foo() {
5// let _ = true;
6// let _ = false;
7// let _ = 1;
8// let _ = 2.0;
9// let _ = b'a';
10// let _ = 'b';
11// let _ = "c";
12// let _ = r"d";
13// let _ = b"e";
14// let _ = br"f";
15// }
16const LITERAL_FIRST: TokenSet =
17 token_set![TRUE_KW, FALSE_KW, INT_NUMBER, FLOAT_NUMBER, BYTE, CHAR,
18 STRING, RAW_STRING, BYTE_STRING, RAW_BYTE_STRING];
19
20pub(crate) fn literal(p: &mut Parser) -> Option<CompletedMarker> {
21 if !LITERAL_FIRST.contains(p.current()) {
22 return None;
23 }
24 let m = p.start();
25 p.bump();
26 Some(m.complete(p, LITERAL))
27}
28
29pub(super) const ATOM_EXPR_FIRST: TokenSet =
30 token_set_union![
31 LITERAL_FIRST,
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 ],
34 ];
35
36pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<CompletedMarker> {
37 match literal(p) {
38 Some(m) => return Some(m),
39 None => (),
40 }
41 if paths::is_path_start(p) {
42 return Some(path_expr(p, r));
43 }
44 let la = p.nth(1);
45 let done = match p.current() {
46 L_PAREN => tuple_expr(p),
47 L_BRACK => array_expr(p),
48 PIPE => lambda_expr(p),
49 MOVE_KW if la == PIPE => lambda_expr(p),
50 IF_KW => if_expr(p),
51 WHILE_KW => while_expr(p),
52 LOOP_KW => loop_expr(p),
53 FOR_KW => for_expr(p),
54 MATCH_KW => match_expr(p),
55 UNSAFE_KW if la == L_CURLY => block_expr(p),
56 L_CURLY => block_expr(p),
57 RETURN_KW => return_expr(p),
58 _ => {
59 p.err_and_bump("expected expression");
60 return None;
61 }
62 };
63 Some(done)
64}
65
66// test tuple_expr
67// fn foo() {
68// ();
69// (1);
70// (1,);
71// }
72fn tuple_expr(p: &mut Parser) -> CompletedMarker {
73 assert!(p.at(L_PAREN));
74 let m = p.start();
75 p.expect(L_PAREN);
76
77 let mut saw_comma = false;
78 let mut saw_expr = false;
79 while !p.at(EOF) && !p.at(R_PAREN) {
80 saw_expr = true;
81 expr(p);
82 if !p.at(R_PAREN) {
83 saw_comma = true;
84 p.expect(COMMA);
85 }
86 }
87 p.expect(R_PAREN);
88 m.complete(p, if saw_expr && !saw_comma { PAREN_EXPR } else { TUPLE_EXPR })
89}
90
91// test array_expr
92// fn foo() {
93// [];
94// [1];
95// [1, 2,];
96// [1; 2];
97// }
98fn array_expr(p: &mut Parser) -> CompletedMarker {
99 assert!(p.at(L_BRACK));
100 let m = p.start();
101 p.bump();
102 if p.eat(R_BRACK) {
103 return m.complete(p, ARRAY_EXPR);
104 }
105 expr(p);
106 if p.eat(SEMI) {
107 expr(p);
108 p.expect(R_BRACK);
109 return m.complete(p, ARRAY_EXPR);
110 }
111 while !p.at(EOF) && !p.at(R_BRACK) {
112 p.expect(COMMA);
113 if !p.at(R_BRACK) {
114 expr(p);
115 }
116 }
117 p.expect(R_BRACK);
118 m.complete(p, ARRAY_EXPR)
119}
120
121// test lambda_expr
122// fn foo() {
123// || ();
124// || -> i32 { 92 };
125// |x| x;
126// move |x: i32,| x;
127// }
128fn lambda_expr(p: &mut Parser) -> CompletedMarker {
129 assert!(p.at(PIPE) || (p.at(MOVE_KW) && p.nth(1) == PIPE));
130 let m = p.start();
131 p.eat(MOVE_KW);
132 params::param_list_opt_types(p);
133 if fn_ret_type(p) {
134 block(p);
135 } else {
136 expr(p);
137 }
138 m.complete(p, LAMBDA_EXPR)
139}
140
141// test if_expr
142// fn foo() {
143// if true {};
144// if true {} else {};
145// if true {} else if false {} else {};
146// if S {};
147// }
148fn if_expr(p: &mut Parser) -> CompletedMarker {
149 assert!(p.at(IF_KW));
150 let m = p.start();
151 p.bump();
152 cond(p);
153 block(p);
154 if p.at(ELSE_KW) {
155 p.bump();
156 if p.at(IF_KW) {
157 if_expr(p);
158 } else {
159 block(p);
160 }
161 }
162 m.complete(p, IF_EXPR)
163}
164
165// test while_expr
166// fn foo() {
167// while true {};
168// while let Some(x) = it.next() {};
169// }
170fn while_expr(p: &mut Parser) -> CompletedMarker {
171 assert!(p.at(WHILE_KW));
172 let m = p.start();
173 p.bump();
174 cond(p);
175 block(p);
176 m.complete(p, WHILE_EXPR)
177}
178
179// test loop_expr
180// fn foo() {
181// loop {};
182// }
183fn loop_expr(p: &mut Parser) -> CompletedMarker {
184 assert!(p.at(LOOP_KW));
185 let m = p.start();
186 p.bump();
187 block(p);
188 m.complete(p, LOOP_EXPR)
189}
190
191// test for_expr
192// fn foo() {
193// for x in [] {};
194// }
195fn for_expr(p: &mut Parser) -> CompletedMarker {
196 assert!(p.at(FOR_KW));
197 let m = p.start();
198 p.bump();
199 patterns::pattern(p);
200 p.expect(IN_KW);
201 expr_no_struct(p);
202 block(p);
203 m.complete(p, FOR_EXPR)
204}
205
206// test cond
207// fn foo() { if let Some(_) = None {} }
208fn cond(p: &mut Parser) {
209 if p.eat(LET_KW) {
210 patterns::pattern(p);
211 p.expect(EQ);
212 }
213 expr_no_struct(p)
214}
215
216// test match_expr
217// fn foo() {
218// match () { };
219// match S {};
220// }
221fn match_expr(p: &mut Parser) -> CompletedMarker {
222 assert!(p.at(MATCH_KW));
223 let m = p.start();
224 p.bump();
225 expr_no_struct(p);
226 p.eat(L_CURLY);
227 while !p.at(EOF) && !p.at(R_CURLY) {
228 // test match_arms_commas
229 // fn foo() {
230 // match () {
231 // _ => (),
232 // _ => {}
233 // _ => ()
234 // }
235 // }
236 if match_arm(p).is_block() {
237 p.eat(COMMA);
238 } else if !p.at(R_CURLY) {
239 p.expect(COMMA);
240 }
241 }
242 p.expect(R_CURLY);
243 m.complete(p, MATCH_EXPR)
244}
245
246// test match_arm
247// fn foo() {
248// match () {
249// _ => (),
250// X | Y if Z => (),
251// };
252// }
253fn match_arm(p: &mut Parser) -> BlockLike {
254 let m = p.start();
255 loop {
256 patterns::pattern(p);
257 if !p.eat(PIPE) {
258 break;
259 }
260 }
261 if p.eat(IF_KW) {
262 expr_no_struct(p);
263 }
264 p.expect(FAT_ARROW);
265 let ret = expr_stmt(p);
266 m.complete(p, MATCH_ARM);
267 ret
268}
269
270// test block_expr
271// fn foo() {
272// {};
273// unsafe {};
274// }
275pub(super) fn block_expr(p: &mut Parser) -> CompletedMarker {
276 assert!(p.at(L_CURLY) || p.at(UNSAFE_KW) && p.nth(1) == L_CURLY);
277 let m = p.start();
278 p.eat(UNSAFE_KW);
279 p.bump();
280 while !p.at(EOF) && !p.at(R_CURLY) {
281 match p.current() {
282 LET_KW => let_stmt(p),
283 _ => {
284 // test block_items
285 // fn a() { fn b() {} }
286 let m = p.start();
287 match items::maybe_item(p) {
288 items::MaybeItem::Item(kind) => {
289 m.complete(p, kind);
290 }
291 items::MaybeItem::Modifiers => {
292 m.abandon(p);
293 p.error("expected an item");
294 }
295 // test pub_expr
296 // fn foo() { pub 92; } //FIXME
297 items::MaybeItem::None => {
298 let is_blocklike = expressions::expr_stmt(p) == BlockLike::Block;
299 if p.eat(SEMI) || (is_blocklike && !p.at(R_CURLY)) {
300 m.complete(p, EXPR_STMT);
301 } else {
302 m.abandon(p);
303 }
304 }
305 }
306 }
307 }
308 }
309 p.expect(R_CURLY);
310 m.complete(p, BLOCK_EXPR)
311}
312
313// test let_stmt;
314// fn foo() {
315// let a;
316// let b: i32;
317// let c = 92;
318// let d: i32 = 92;
319// }
320fn let_stmt(p: &mut Parser) {
321 assert!(p.at(LET_KW));
322 let m = p.start();
323 p.bump();
324 patterns::pattern(p);
325 if p.at(COLON) {
326 types::ascription(p);
327 }
328 if p.eat(EQ) {
329 expressions::expr(p);
330 }
331 p.expect(SEMI);
332 m.complete(p, LET_STMT);
333}
334
335// test return_expr
336// fn foo() {
337// return;
338// return 92;
339// }
340fn return_expr(p: &mut Parser) -> CompletedMarker {
341 assert!(p.at(RETURN_KW));
342 let m = p.start();
343 p.bump();
344 if EXPR_FIRST.contains(p.current()) {
345 expr(p);
346 }
347 m.complete(p, RETURN_EXPR)
348}