diff options
Diffstat (limited to 'src/grammar/expressions.rs')
-rw-r--r-- | src/grammar/expressions.rs | 44 |
1 files changed, 36 insertions, 8 deletions
diff --git a/src/grammar/expressions.rs b/src/grammar/expressions.rs index 5c59843a4..423e1a95a 100644 --- a/src/grammar/expressions.rs +++ b/src/grammar/expressions.rs | |||
@@ -13,18 +13,20 @@ use super::*; | |||
13 | // let _ = b"e"; | 13 | // let _ = b"e"; |
14 | // let _ = br"f"; | 14 | // let _ = br"f"; |
15 | // } | 15 | // } |
16 | const 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 | |||
16 | pub(super) fn literal(p: &mut Parser) -> Option<CompletedMarker> { | 20 | pub(super) fn literal(p: &mut Parser) -> Option<CompletedMarker> { |
17 | match p.current() { | 21 | if !LITERAL_FIRST.contains(p.current()) { |
18 | TRUE_KW | FALSE_KW | INT_NUMBER | FLOAT_NUMBER | BYTE | CHAR | STRING | RAW_STRING | 22 | return None; |
19 | | BYTE_STRING | RAW_BYTE_STRING => { | ||
20 | let m = p.start(); | ||
21 | p.bump(); | ||
22 | Some(m.complete(p, LITERAL)) | ||
23 | } | ||
24 | _ => None, | ||
25 | } | 23 | } |
24 | let m = p.start(); | ||
25 | p.bump(); | ||
26 | Some(m.complete(p, LITERAL)) | ||
26 | } | 27 | } |
27 | 28 | ||
29 | const EXPR_FIRST: TokenSet = PREFIX_EXPR_FIRST; | ||
28 | pub(super) fn expr(p: &mut Parser) { | 30 | pub(super) fn expr(p: &mut Parser) { |
29 | let mut lhs = match prefix_expr(p) { | 31 | let mut lhs = match prefix_expr(p) { |
30 | Some(lhs) => lhs, | 32 | Some(lhs) => lhs, |
@@ -80,6 +82,11 @@ fn let_stmt(p: &mut Parser) { | |||
80 | m.complete(p, LET_STMT); | 82 | m.complete(p, LET_STMT); |
81 | } | 83 | } |
82 | 84 | ||
85 | const PREFIX_EXPR_FIRST: TokenSet = | ||
86 | token_set_union![ | ||
87 | token_set![AMPERSAND, STAR, EXCL], | ||
88 | ATOM_EXPR_FIRST, | ||
89 | ]; | ||
83 | fn prefix_expr(p: &mut Parser) -> Option<CompletedMarker> { | 90 | fn prefix_expr(p: &mut Parser) -> Option<CompletedMarker> { |
84 | let done = match p.current() { | 91 | let done = match p.current() { |
85 | AMPERSAND => ref_expr(p), | 92 | AMPERSAND => ref_expr(p), |
@@ -128,6 +135,11 @@ fn not_expr(p: &mut Parser) -> CompletedMarker { | |||
128 | m.complete(p, NOT_EXPR) | 135 | m.complete(p, NOT_EXPR) |
129 | } | 136 | } |
130 | 137 | ||
138 | const ATOM_EXPR_FIRST: TokenSet = | ||
139 | token_set_union![ | ||
140 | LITERAL_FIRST, | ||
141 | token_set![L_PAREN, PIPE, MOVE_KW, IF_KW, UNSAFE_KW, L_CURLY, RETURN_KW], | ||
142 | ]; | ||
131 | fn atom_expr(p: &mut Parser) -> Option<CompletedMarker> { | 143 | fn atom_expr(p: &mut Parser) -> Option<CompletedMarker> { |
132 | match literal(p) { | 144 | match literal(p) { |
133 | Some(m) => return Some(m), | 145 | Some(m) => return Some(m), |
@@ -144,6 +156,7 @@ fn atom_expr(p: &mut Parser) -> Option<CompletedMarker> { | |||
144 | IF_KW => if_expr(p), | 156 | IF_KW => if_expr(p), |
145 | UNSAFE_KW if la == L_CURLY => block_expr(p), | 157 | UNSAFE_KW if la == L_CURLY => block_expr(p), |
146 | L_CURLY => block_expr(p), | 158 | L_CURLY => block_expr(p), |
159 | RETURN_KW => return_expr(p), | ||
147 | _ => { | 160 | _ => { |
148 | p.err_and_bump("expected expression"); | 161 | p.err_and_bump("expected expression"); |
149 | return None; | 162 | return None; |
@@ -237,6 +250,21 @@ fn block_expr(p: &mut Parser) -> CompletedMarker { | |||
237 | m.complete(p, BLOCK_EXPR) | 250 | m.complete(p, BLOCK_EXPR) |
238 | } | 251 | } |
239 | 252 | ||
253 | // test return_expr | ||
254 | // fn foo() { | ||
255 | // return; | ||
256 | // return 92; | ||
257 | // } | ||
258 | fn return_expr(p: &mut Parser) -> CompletedMarker { | ||
259 | assert!(p.at(RETURN_KW)); | ||
260 | let m = p.start(); | ||
261 | p.bump(); | ||
262 | if EXPR_FIRST.contains(p.current()) { | ||
263 | expr(p); | ||
264 | } | ||
265 | m.complete(p, RETURN_EXPR) | ||
266 | } | ||
267 | |||
240 | // test call_expr | 268 | // test call_expr |
241 | // fn foo() { | 269 | // fn foo() { |
242 | // let _ = f(); | 270 | // let _ = f(); |