aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-08-01 09:27:31 +0100
committerAleksey Kladov <[email protected]>2018-08-01 09:27:31 +0100
commit37e1625f0139da07c2690b6ee6ca7eae5ebb061a (patch)
tree368d3329e120fc5d76a0595110f7519bb084d70f /src
parent53485030dc49aa7cd66e36c8a1e1abf1bf08020c (diff)
return expr
Diffstat (limited to 'src')
-rw-r--r--src/grammar.ron4
-rw-r--r--src/grammar/expressions.rs44
-rw-r--r--src/parser_api.rs23
-rw-r--r--src/syntax_kinds/generated.rs11
4 files changed, 65 insertions, 17 deletions
diff --git a/src/grammar.ron b/src/grammar.ron
index 109556561..8e8a71010 100644
--- a/src/grammar.ron
+++ b/src/grammar.ron
@@ -70,6 +70,7 @@ Grammar(
70 "ref", 70 "ref",
71 "let", 71 "let",
72 "move", 72 "move",
73 "return",
73 ], 74 ],
74 contextual_keywords: [ 75 contextual_keywords: [
75 "auto", 76 "auto",
@@ -138,6 +139,8 @@ Grammar(
138 "STRUCT_LIT", 139 "STRUCT_LIT",
139 "STRUCT_LIT_FIELD", 140 "STRUCT_LIT_FIELD",
140 "IF_EXPR", 141 "IF_EXPR",
142 "BLOCK_EXPR",
143 "RETURN_EXPR",
141 144
142 "EXTERN_BLOCK_EXPR", 145 "EXTERN_BLOCK_EXPR",
143 "ENUM_VARIANT", 146 "ENUM_VARIANT",
@@ -155,7 +158,6 @@ Grammar(
155 "ABI", 158 "ABI",
156 "NAME", 159 "NAME",
157 "NAME_REF", 160 "NAME_REF",
158 "BLOCK_EXPR",
159 161
160 "LET_STMT", 162 "LET_STMT",
161 "EXPR_STMT", 163 "EXPR_STMT",
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();
diff --git a/src/parser_api.rs b/src/parser_api.rs
index 5a0da32c9..d12f773b2 100644
--- a/src/parser_api.rs
+++ b/src/parser_api.rs
@@ -3,22 +3,22 @@ use {
3 SyntaxKind::{self, ERROR}, 3 SyntaxKind::{self, ERROR},
4}; 4};
5 5
6pub(crate) struct TokenSet { 6#[derive(Clone, Copy)]
7 pub tokens: &'static [SyntaxKind], 7pub(crate) struct TokenSet(pub(crate) u128);
8fn mask(kind: SyntaxKind) -> u128 {
9 1u128 << (kind as usize)
8} 10}
9 11
10impl TokenSet { 12impl TokenSet {
11 pub fn contains(&self, kind: SyntaxKind) -> bool { 13 pub fn contains(&self, kind: SyntaxKind) -> bool {
12 self.tokens.contains(&kind) 14 self.0 & mask(kind) != 0
13 } 15 }
14} 16}
15 17
16#[macro_export] 18#[macro_export]
17macro_rules! token_set { 19macro_rules! token_set {
18 ($($t:ident),*) => { 20 ($($t:ident),*) => {
19 TokenSet { 21 TokenSet($(1u128 << ($t as usize))|*)
20 tokens: &[$($t),*],
21 }
22 }; 22 };
23 23
24 ($($t:ident),* ,) => { 24 ($($t:ident),* ,) => {
@@ -26,6 +26,17 @@ macro_rules! token_set {
26 }; 26 };
27} 27}
28 28
29#[macro_export]
30macro_rules! token_set_union {
31 ($($ts:expr),*) => {
32 TokenSet($($ts.0)|*)
33 };
34
35 ($($ts:expr),* ,) => {
36 token_set_union!($($ts),*)
37 };
38}
39
29/// `Parser` struct provides the low-level API for 40/// `Parser` struct provides the low-level API for
30/// navigating through the stream of tokens and 41/// navigating through the stream of tokens and
31/// constructing the parse tree. The actual parsing 42/// constructing the parse tree. The actual parsing
diff --git a/src/syntax_kinds/generated.rs b/src/syntax_kinds/generated.rs
index 5f26cbf0a..50aa2b580 100644
--- a/src/syntax_kinds/generated.rs
+++ b/src/syntax_kinds/generated.rs
@@ -71,6 +71,7 @@ pub enum SyntaxKind {
71 REF_KW, 71 REF_KW,
72 LET_KW, 72 LET_KW,
73 MOVE_KW, 73 MOVE_KW,
74 RETURN_KW,
74 AUTO_KW, 75 AUTO_KW,
75 DEFAULT_KW, 76 DEFAULT_KW,
76 UNION_KW, 77 UNION_KW,
@@ -129,6 +130,8 @@ pub enum SyntaxKind {
129 STRUCT_LIT, 130 STRUCT_LIT,
130 STRUCT_LIT_FIELD, 131 STRUCT_LIT_FIELD,
131 IF_EXPR, 132 IF_EXPR,
133 BLOCK_EXPR,
134 RETURN_EXPR,
132 EXTERN_BLOCK_EXPR, 135 EXTERN_BLOCK_EXPR,
133 ENUM_VARIANT, 136 ENUM_VARIANT,
134 NAMED_FIELD, 137 NAMED_FIELD,
@@ -145,7 +148,6 @@ pub enum SyntaxKind {
145 ABI, 148 ABI,
146 NAME, 149 NAME,
147 NAME_REF, 150 NAME_REF,
148 BLOCK_EXPR,
149 LET_STMT, 151 LET_STMT,
150 EXPR_STMT, 152 EXPR_STMT,
151 TYPE_PARAM_LIST, 153 TYPE_PARAM_LIST,
@@ -202,6 +204,7 @@ impl SyntaxKind {
202 | REF_KW 204 | REF_KW
203 | LET_KW 205 | LET_KW
204 | MOVE_KW 206 | MOVE_KW
207 | RETURN_KW
205 | AUTO_KW 208 | AUTO_KW
206 | DEFAULT_KW 209 | DEFAULT_KW
207 | UNION_KW 210 | UNION_KW
@@ -278,6 +281,7 @@ impl SyntaxKind {
278 REF_KW => &SyntaxInfo { name: "REF_KW" }, 281 REF_KW => &SyntaxInfo { name: "REF_KW" },
279 LET_KW => &SyntaxInfo { name: "LET_KW" }, 282 LET_KW => &SyntaxInfo { name: "LET_KW" },
280 MOVE_KW => &SyntaxInfo { name: "MOVE_KW" }, 283 MOVE_KW => &SyntaxInfo { name: "MOVE_KW" },
284 RETURN_KW => &SyntaxInfo { name: "RETURN_KW" },
281 AUTO_KW => &SyntaxInfo { name: "AUTO_KW" }, 285 AUTO_KW => &SyntaxInfo { name: "AUTO_KW" },
282 DEFAULT_KW => &SyntaxInfo { name: "DEFAULT_KW" }, 286 DEFAULT_KW => &SyntaxInfo { name: "DEFAULT_KW" },
283 UNION_KW => &SyntaxInfo { name: "UNION_KW" }, 287 UNION_KW => &SyntaxInfo { name: "UNION_KW" },
@@ -336,6 +340,8 @@ impl SyntaxKind {
336 STRUCT_LIT => &SyntaxInfo { name: "STRUCT_LIT" }, 340 STRUCT_LIT => &SyntaxInfo { name: "STRUCT_LIT" },
337 STRUCT_LIT_FIELD => &SyntaxInfo { name: "STRUCT_LIT_FIELD" }, 341 STRUCT_LIT_FIELD => &SyntaxInfo { name: "STRUCT_LIT_FIELD" },
338 IF_EXPR => &SyntaxInfo { name: "IF_EXPR" }, 342 IF_EXPR => &SyntaxInfo { name: "IF_EXPR" },
343 BLOCK_EXPR => &SyntaxInfo { name: "BLOCK_EXPR" },
344 RETURN_EXPR => &SyntaxInfo { name: "RETURN_EXPR" },
339 EXTERN_BLOCK_EXPR => &SyntaxInfo { name: "EXTERN_BLOCK_EXPR" }, 345 EXTERN_BLOCK_EXPR => &SyntaxInfo { name: "EXTERN_BLOCK_EXPR" },
340 ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" }, 346 ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" },
341 NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" }, 347 NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" },
@@ -352,7 +358,6 @@ impl SyntaxKind {
352 ABI => &SyntaxInfo { name: "ABI" }, 358 ABI => &SyntaxInfo { name: "ABI" },
353 NAME => &SyntaxInfo { name: "NAME" }, 359 NAME => &SyntaxInfo { name: "NAME" },
354 NAME_REF => &SyntaxInfo { name: "NAME_REF" }, 360 NAME_REF => &SyntaxInfo { name: "NAME_REF" },
355 BLOCK_EXPR => &SyntaxInfo { name: "BLOCK_EXPR" },
356 LET_STMT => &SyntaxInfo { name: "LET_STMT" }, 361 LET_STMT => &SyntaxInfo { name: "LET_STMT" },
357 EXPR_STMT => &SyntaxInfo { name: "EXPR_STMT" }, 362 EXPR_STMT => &SyntaxInfo { name: "EXPR_STMT" },
358 TYPE_PARAM_LIST => &SyntaxInfo { name: "TYPE_PARAM_LIST" }, 363 TYPE_PARAM_LIST => &SyntaxInfo { name: "TYPE_PARAM_LIST" },
@@ -403,6 +408,7 @@ impl SyntaxKind {
403 "ref" => REF_KW, 408 "ref" => REF_KW,
404 "let" => LET_KW, 409 "let" => LET_KW,
405 "move" => MOVE_KW, 410 "move" => MOVE_KW,
411 "return" => RETURN_KW,
406 _ => return None, 412 _ => return None,
407 }; 413 };
408 Some(kw) 414 Some(kw)
@@ -506,6 +512,7 @@ impl SyntaxKind {
506 REF_KW => "ref", 512 REF_KW => "ref",
507 LET_KW => "let", 513 LET_KW => "let",
508 MOVE_KW => "move", 514 MOVE_KW => "move",
515 RETURN_KW => "return",
509 AUTO_KW => "auto", 516 AUTO_KW => "auto",
510 DEFAULT_KW => "default", 517 DEFAULT_KW => "default",
511 UNION_KW => "union", 518 UNION_KW => "union",