aboutsummaryrefslogtreecommitdiff
path: root/src/grammar/expressions.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/grammar/expressions.rs')
-rw-r--r--src/grammar/expressions.rs44
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// }
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
16pub(super) fn literal(p: &mut Parser) -> Option<CompletedMarker> { 20pub(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
29const EXPR_FIRST: TokenSet = PREFIX_EXPR_FIRST;
28pub(super) fn expr(p: &mut Parser) { 30pub(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
85const PREFIX_EXPR_FIRST: TokenSet =
86 token_set_union![
87 token_set![AMPERSAND, STAR, EXCL],
88 ATOM_EXPR_FIRST,
89 ];
83fn prefix_expr(p: &mut Parser) -> Option<CompletedMarker> { 90fn 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
138const 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 ];
131fn atom_expr(p: &mut Parser) -> Option<CompletedMarker> { 143fn 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// }
258fn 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();