diff options
Diffstat (limited to 'src/grammar')
-rw-r--r-- | src/grammar/expressions.rs | 56 |
1 files changed, 54 insertions, 2 deletions
diff --git a/src/grammar/expressions.rs b/src/grammar/expressions.rs index c68419929..6506892e1 100644 --- a/src/grammar/expressions.rs +++ b/src/grammar/expressions.rs | |||
@@ -27,6 +27,7 @@ pub(super) fn literal(p: &mut Parser) -> Option<CompletedMarker> { | |||
27 | } | 27 | } |
28 | 28 | ||
29 | const EXPR_FIRST: TokenSet = PREFIX_EXPR_FIRST; | 29 | const EXPR_FIRST: TokenSet = PREFIX_EXPR_FIRST; |
30 | |||
30 | pub(super) fn expr(p: &mut Parser) { | 31 | pub(super) fn expr(p: &mut Parser) { |
31 | let mut lhs = match prefix_expr(p) { | 32 | let mut lhs = match prefix_expr(p) { |
32 | Some(lhs) => lhs, | 33 | Some(lhs) => lhs, |
@@ -87,6 +88,7 @@ const PREFIX_EXPR_FIRST: TokenSet = | |||
87 | token_set![AMPERSAND, STAR, EXCL], | 88 | token_set![AMPERSAND, STAR, EXCL], |
88 | ATOM_EXPR_FIRST, | 89 | ATOM_EXPR_FIRST, |
89 | ]; | 90 | ]; |
91 | |||
90 | fn prefix_expr(p: &mut Parser) -> Option<CompletedMarker> { | 92 | fn prefix_expr(p: &mut Parser) -> Option<CompletedMarker> { |
91 | let done = match p.current() { | 93 | let done = match p.current() { |
92 | AMPERSAND => ref_expr(p), | 94 | AMPERSAND => ref_expr(p), |
@@ -140,6 +142,7 @@ const ATOM_EXPR_FIRST: TokenSet = | |||
140 | LITERAL_FIRST, | 142 | LITERAL_FIRST, |
141 | token_set![L_PAREN, PIPE, MOVE_KW, IF_KW, UNSAFE_KW, L_CURLY, RETURN_KW], | 143 | token_set![L_PAREN, PIPE, MOVE_KW, IF_KW, UNSAFE_KW, L_CURLY, RETURN_KW], |
142 | ]; | 144 | ]; |
145 | |||
143 | fn atom_expr(p: &mut Parser) -> Option<CompletedMarker> { | 146 | fn atom_expr(p: &mut Parser) -> Option<CompletedMarker> { |
144 | match literal(p) { | 147 | match literal(p) { |
145 | Some(m) => return Some(m), | 148 | Some(m) => return Some(m), |
@@ -154,6 +157,7 @@ fn atom_expr(p: &mut Parser) -> Option<CompletedMarker> { | |||
154 | PIPE => lambda_expr(p), | 157 | PIPE => lambda_expr(p), |
155 | MOVE_KW if la == PIPE => lambda_expr(p), | 158 | MOVE_KW if la == PIPE => lambda_expr(p), |
156 | IF_KW => if_expr(p), | 159 | IF_KW => if_expr(p), |
160 | MATCH_KW => match_expr(p), | ||
157 | UNSAFE_KW if la == L_CURLY => block_expr(p), | 161 | UNSAFE_KW if la == L_CURLY => block_expr(p), |
158 | L_CURLY => block_expr(p), | 162 | L_CURLY => block_expr(p), |
159 | RETURN_KW => return_expr(p), | 163 | RETURN_KW => return_expr(p), |
@@ -202,8 +206,7 @@ fn lambda_expr(p: &mut Parser) -> CompletedMarker { | |||
202 | fn if_expr(p: &mut Parser) -> CompletedMarker { | 206 | fn if_expr(p: &mut Parser) -> CompletedMarker { |
203 | assert!(p.at(IF_KW)); | 207 | assert!(p.at(IF_KW)); |
204 | let m = p.start(); | 208 | let m = p.start(); |
205 | p.bump(); | 209 | if_head(p); |
206 | expr(p); | ||
207 | block(p); | 210 | block(p); |
208 | if p.at(ELSE_KW) { | 211 | if p.at(ELSE_KW) { |
209 | p.bump(); | 212 | p.bump(); |
@@ -216,6 +219,55 @@ fn if_expr(p: &mut Parser) -> CompletedMarker { | |||
216 | m.complete(p, IF_EXPR) | 219 | m.complete(p, IF_EXPR) |
217 | } | 220 | } |
218 | 221 | ||
222 | fn if_head(p: &mut Parser) { | ||
223 | assert!(p.at(IF_KW)); | ||
224 | p.bump(); | ||
225 | expr(p); | ||
226 | } | ||
227 | |||
228 | // test match_expr | ||
229 | // fn foo() { | ||
230 | // match () { }; | ||
231 | // } | ||
232 | fn match_expr(p: &mut Parser) -> CompletedMarker { | ||
233 | assert!(p.at(MATCH_KW)); | ||
234 | let m = p.start(); | ||
235 | p.bump(); | ||
236 | expr(p); | ||
237 | p.eat(L_CURLY); | ||
238 | while !p.at(EOF) && !p.at(R_CURLY) { | ||
239 | match_arm(p); | ||
240 | if !p.at(R_CURLY) { | ||
241 | p.expect(COMMA); | ||
242 | } | ||
243 | } | ||
244 | p.expect(R_CURLY); | ||
245 | m.complete(p, MATCH_EXPR) | ||
246 | } | ||
247 | |||
248 | // test match_arm | ||
249 | // fn foo() { | ||
250 | // match () { | ||
251 | // _ => (), | ||
252 | // X | Y if Z => (), | ||
253 | // }; | ||
254 | // } | ||
255 | fn match_arm(p: &mut Parser) { | ||
256 | let m = p.start(); | ||
257 | loop { | ||
258 | patterns::pattern(p); | ||
259 | if !p.eat(PIPE) { | ||
260 | break; | ||
261 | } | ||
262 | } | ||
263 | if p.at(IF_KW) { | ||
264 | if_head(p) | ||
265 | } | ||
266 | p.expect(FAT_ARROW); | ||
267 | expr(p); | ||
268 | m.complete(p, MATCH_ARM); | ||
269 | } | ||
270 | |||
219 | // test block_expr | 271 | // test block_expr |
220 | // fn foo() { | 272 | // fn foo() { |
221 | // {}; | 273 | // {}; |