diff options
Diffstat (limited to 'src/grammar/expressions.rs')
-rw-r--r-- | src/grammar/expressions.rs | 284 |
1 files changed, 284 insertions, 0 deletions
diff --git a/src/grammar/expressions.rs b/src/grammar/expressions.rs new file mode 100644 index 000000000..06f9105c6 --- /dev/null +++ b/src/grammar/expressions.rs | |||
@@ -0,0 +1,284 @@ | |||
1 | use 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 | // } | ||
16 | pub(super) fn literal(p: &mut Parser) -> Option<CompletedMarker> { | ||
17 | match p.current() { | ||
18 | TRUE_KW | FALSE_KW | INT_NUMBER | FLOAT_NUMBER | BYTE | CHAR | STRING | RAW_STRING | ||
19 | | BYTE_STRING | RAW_BYTE_STRING => { | ||
20 | let m = p.start(); | ||
21 | p.bump(); | ||
22 | Some(m.complete(p, LITERAL)) | ||
23 | } | ||
24 | _ => None, | ||
25 | } | ||
26 | } | ||
27 | |||
28 | pub(super) fn expr(p: &mut Parser) { | ||
29 | let mut lhs = match prefix_expr(p) { | ||
30 | Some(lhs) => lhs, | ||
31 | None => return, | ||
32 | }; | ||
33 | |||
34 | loop { | ||
35 | lhs = match p.current() { | ||
36 | L_PAREN => call_expr(p, lhs), | ||
37 | DOT if p.nth(1) == IDENT => if p.nth(2) == L_PAREN { | ||
38 | method_call_expr(p, lhs) | ||
39 | } else { | ||
40 | field_expr(p, lhs) | ||
41 | }, | ||
42 | _ => break, | ||
43 | } | ||
44 | } | ||
45 | } | ||
46 | |||
47 | // test block | ||
48 | // fn a() {} | ||
49 | // fn b() { let _ = 1; } | ||
50 | // fn c() { 1; 2; } | ||
51 | // fn d() { 1; 2 } | ||
52 | pub(super) fn block(p: &mut Parser) { | ||
53 | if !p.at(L_CURLY) { | ||
54 | p.error("expected block"); | ||
55 | } | ||
56 | let m = p.start(); | ||
57 | p.bump(); | ||
58 | while !p.at(EOF) && !p.at(R_CURLY) { | ||
59 | match p.current() { | ||
60 | LET_KW => let_stmt(p), | ||
61 | c => { | ||
62 | // test block_items | ||
63 | // fn a() { fn b() {} } | ||
64 | if items::ITEM_FIRST.contains(c) { | ||
65 | items::item(p) | ||
66 | } else { | ||
67 | let expr_stmt = p.start(); | ||
68 | expressions::expr(p); | ||
69 | if p.eat(SEMI) { | ||
70 | expr_stmt.complete(p, EXPR_STMT); | ||
71 | } else { | ||
72 | expr_stmt.abandon(p); | ||
73 | } | ||
74 | } | ||
75 | } | ||
76 | } | ||
77 | } | ||
78 | p.expect(R_CURLY); | ||
79 | m.complete(p, BLOCK); | ||
80 | } | ||
81 | |||
82 | // test let_stmt; | ||
83 | // fn foo() { | ||
84 | // let a; | ||
85 | // let b: i32; | ||
86 | // let c = 92; | ||
87 | // let d: i32 = 92; | ||
88 | // } | ||
89 | fn let_stmt(p: &mut Parser) { | ||
90 | assert!(p.at(LET_KW)); | ||
91 | let m = p.start(); | ||
92 | p.bump(); | ||
93 | patterns::pattern(p); | ||
94 | if p.at(COLON) { | ||
95 | types::ascription(p); | ||
96 | } | ||
97 | if p.eat(EQ) { | ||
98 | expressions::expr(p); | ||
99 | } | ||
100 | p.expect(SEMI); | ||
101 | m.complete(p, LET_STMT); | ||
102 | } | ||
103 | |||
104 | fn prefix_expr(p: &mut Parser) -> Option<CompletedMarker> { | ||
105 | match p.current() { | ||
106 | AMPERSAND => Some(ref_expr(p)), | ||
107 | STAR => Some(deref_expr(p)), | ||
108 | _ => atom_expr(p), | ||
109 | } | ||
110 | } | ||
111 | |||
112 | // test ref_expr | ||
113 | // fn foo() { | ||
114 | // let _ = &1; | ||
115 | // let _ = &mut &f(); | ||
116 | // } | ||
117 | fn ref_expr(p: &mut Parser) -> CompletedMarker { | ||
118 | assert!(p.at(AMPERSAND)); | ||
119 | let m = p.start(); | ||
120 | p.bump(); | ||
121 | p.eat(MUT_KW); | ||
122 | expr(p); | ||
123 | m.complete(p, REF_EXPR) | ||
124 | } | ||
125 | |||
126 | // test deref_expr | ||
127 | // fn foo() { | ||
128 | // **&1; | ||
129 | // } | ||
130 | fn deref_expr(p: &mut Parser) -> CompletedMarker { | ||
131 | assert!(p.at(STAR)); | ||
132 | let m = p.start(); | ||
133 | p.bump(); | ||
134 | expr(p); | ||
135 | m.complete(p, DEREF_EXPR) | ||
136 | } | ||
137 | |||
138 | fn atom_expr(p: &mut Parser) -> Option<CompletedMarker> { | ||
139 | match literal(p) { | ||
140 | Some(m) => return Some(m), | ||
141 | None => (), | ||
142 | } | ||
143 | if paths::is_path_start(p) { | ||
144 | return Some(path_expr(p)); | ||
145 | } | ||
146 | |||
147 | match p.current() { | ||
148 | L_PAREN => Some(tuple_expr(p)), | ||
149 | PIPE => Some(lambda_expr(p)), | ||
150 | _ => { | ||
151 | p.err_and_bump("expected expression"); | ||
152 | None | ||
153 | } | ||
154 | } | ||
155 | } | ||
156 | |||
157 | fn tuple_expr(p: &mut Parser) -> CompletedMarker { | ||
158 | assert!(p.at(L_PAREN)); | ||
159 | let m = p.start(); | ||
160 | p.expect(L_PAREN); | ||
161 | p.expect(R_PAREN); | ||
162 | m.complete(p, TUPLE_EXPR) | ||
163 | } | ||
164 | |||
165 | // test lambda_expr | ||
166 | // fn foo() { | ||
167 | // || (); | ||
168 | // || -> i32 { 92 }; | ||
169 | // |x| x; | ||
170 | // |x: i32,| x; | ||
171 | // } | ||
172 | fn lambda_expr(p: &mut Parser) -> CompletedMarker { | ||
173 | assert!(p.at(PIPE)); | ||
174 | let m = p.start(); | ||
175 | params::param_list_opt_types(p); | ||
176 | if fn_ret_type(p) { | ||
177 | block(p); | ||
178 | } else { | ||
179 | expr(p) | ||
180 | } | ||
181 | m.complete(p, LAMBDA_EXPR) | ||
182 | } | ||
183 | |||
184 | // test call_expr | ||
185 | // fn foo() { | ||
186 | // let _ = f(); | ||
187 | // let _ = f()(1)(1, 2,); | ||
188 | // } | ||
189 | fn call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | ||
190 | assert!(p.at(L_PAREN)); | ||
191 | let m = lhs.precede(p); | ||
192 | arg_list(p); | ||
193 | m.complete(p, CALL_EXPR) | ||
194 | } | ||
195 | |||
196 | // test method_call_expr | ||
197 | // fn foo() { | ||
198 | // x.foo(); | ||
199 | // y.bar(1, 2,); | ||
200 | // } | ||
201 | fn method_call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | ||
202 | assert!(p.at(DOT) && p.nth(1) == IDENT && p.nth(2) == L_PAREN); | ||
203 | let m = lhs.precede(p); | ||
204 | p.bump(); | ||
205 | p.bump(); | ||
206 | arg_list(p); | ||
207 | m.complete(p, METHOD_CALL_EXPR) | ||
208 | } | ||
209 | |||
210 | // test field_expr | ||
211 | // fn foo() { | ||
212 | // x.foo.bar; | ||
213 | // } | ||
214 | fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | ||
215 | assert!(p.at(DOT) && p.nth(1) == IDENT); | ||
216 | let m = lhs.precede(p); | ||
217 | p.bump(); | ||
218 | p.bump(); | ||
219 | m.complete(p, FIELD_EXPR) | ||
220 | } | ||
221 | |||
222 | fn arg_list(p: &mut Parser) { | ||
223 | assert!(p.at(L_PAREN)); | ||
224 | let m = p.start(); | ||
225 | p.bump(); | ||
226 | while !p.at(R_PAREN) && !p.at(EOF) { | ||
227 | expr(p); | ||
228 | if !p.at(R_PAREN) && !p.expect(COMMA) { | ||
229 | break; | ||
230 | } | ||
231 | } | ||
232 | p.eat(R_PAREN); | ||
233 | m.complete(p, ARG_LIST); | ||
234 | } | ||
235 | |||
236 | // test path_expr | ||
237 | // fn foo() { | ||
238 | // let _ = a; | ||
239 | // let _ = a::b; | ||
240 | // let _ = ::a::<b>; | ||
241 | // } | ||
242 | fn path_expr(p: &mut Parser) -> CompletedMarker { | ||
243 | assert!(paths::is_path_start(p)); | ||
244 | let m = p.start(); | ||
245 | paths::expr_path(p); | ||
246 | if p.at(L_CURLY) { | ||
247 | struct_lit(p); | ||
248 | m.complete(p, STRUCT_LIT) | ||
249 | } else { | ||
250 | m.complete(p, PATH_EXPR) | ||
251 | } | ||
252 | } | ||
253 | |||
254 | // test struct_lit | ||
255 | // fn foo() { | ||
256 | // S {}; | ||
257 | // S { x, y: 32, }; | ||
258 | // S { x, y: 32, ..Default::default() }; | ||
259 | // } | ||
260 | fn struct_lit(p: &mut Parser) { | ||
261 | assert!(p.at(L_CURLY)); | ||
262 | p.bump(); | ||
263 | while !p.at(EOF) && !p.at(R_CURLY) { | ||
264 | match p.current() { | ||
265 | IDENT => { | ||
266 | let m = p.start(); | ||
267 | name_ref(p); | ||
268 | if p.eat(COLON) { | ||
269 | expr(p); | ||
270 | } | ||
271 | m.complete(p, STRUCT_LIT_FIELD); | ||
272 | } | ||
273 | DOTDOT => { | ||
274 | p.bump(); | ||
275 | expr(p); | ||
276 | } | ||
277 | _ => p.err_and_bump("expected identifier"), | ||
278 | } | ||
279 | if !p.at(R_CURLY) { | ||
280 | p.expect(COMMA); | ||
281 | } | ||
282 | } | ||
283 | p.expect(R_CURLY); | ||
284 | } | ||