diff options
Diffstat (limited to 'src/parser/grammar')
-rw-r--r-- | src/parser/grammar/expressions.rs | 17 | ||||
-rw-r--r-- | src/parser/grammar/items/mod.rs | 28 | ||||
-rw-r--r-- | src/parser/grammar/mod.rs | 20 | ||||
-rw-r--r-- | src/parser/grammar/patterns.rs | 52 |
4 files changed, 113 insertions, 4 deletions
diff --git a/src/parser/grammar/expressions.rs b/src/parser/grammar/expressions.rs index 3704cb16f..2145b8d8b 100644 --- a/src/parser/grammar/expressions.rs +++ b/src/parser/grammar/expressions.rs | |||
@@ -14,7 +14,20 @@ pub(super) fn literal(p: &mut Parser) -> bool { | |||
14 | } | 14 | } |
15 | 15 | ||
16 | pub(super) fn expr(p: &mut Parser) { | 16 | pub(super) fn expr(p: &mut Parser) { |
17 | if !literal(p) { | 17 | if literal(p) { |
18 | p.error("expected expression"); | 18 | return; |
19 | } | 19 | } |
20 | |||
21 | match p.current() { | ||
22 | L_PAREN => tuple_expr(p), | ||
23 | _ => p.error("expected expression"), | ||
24 | } | ||
25 | } | ||
26 | |||
27 | fn tuple_expr(p: &mut Parser) { | ||
28 | assert!(p.at(L_PAREN)); | ||
29 | let m = p.start(); | ||
30 | p.expect(L_PAREN); | ||
31 | p.expect(R_PAREN); | ||
32 | m.complete(p, TUPLE_EXPR); | ||
20 | } | 33 | } |
diff --git a/src/parser/grammar/items/mod.rs b/src/parser/grammar/items/mod.rs index 3af6d13a1..1fe646652 100644 --- a/src/parser/grammar/items/mod.rs +++ b/src/parser/grammar/items/mod.rs | |||
@@ -218,9 +218,33 @@ fn fn_item(p: &mut Parser) { | |||
218 | p.error("expected function arguments"); | 218 | p.error("expected function arguments"); |
219 | } | 219 | } |
220 | 220 | ||
221 | if p.at(L_CURLY) { | 221 | block(p); |
222 | p.expect(L_CURLY); | 222 | |
223 | fn block(p: &mut Parser) { | ||
224 | if !p.at(L_CURLY) { | ||
225 | p.error("expected block"); | ||
226 | } | ||
227 | let m = p.start(); | ||
228 | p.bump(); | ||
229 | while !p.at(EOF) && !p.at(R_CURLY) { | ||
230 | match p.current() { | ||
231 | LET_KW => let_stmt(p), | ||
232 | _ => p.err_and_bump("expected statement"), | ||
233 | } | ||
234 | } | ||
223 | p.expect(R_CURLY); | 235 | p.expect(R_CURLY); |
236 | m.complete(p, BLOCK); | ||
237 | } | ||
238 | |||
239 | fn let_stmt(p: &mut Parser) { | ||
240 | assert!(p.at(LET_KW)); | ||
241 | let m = p.start(); | ||
242 | p.bump(); | ||
243 | patterns::pattern(p); | ||
244 | p.expect(EQ); | ||
245 | expressions::expr(p); | ||
246 | p.expect(SEMI); | ||
247 | m.complete(p, LET_STMT); | ||
224 | } | 248 | } |
225 | } | 249 | } |
226 | 250 | ||
diff --git a/src/parser/grammar/mod.rs b/src/parser/grammar/mod.rs index ee0263203..54a63a547 100644 --- a/src/parser/grammar/mod.rs +++ b/src/parser/grammar/mod.rs | |||
@@ -30,6 +30,7 @@ mod items; | |||
30 | mod attributes; | 30 | mod attributes; |
31 | mod expressions; | 31 | mod expressions; |
32 | mod types; | 32 | mod types; |
33 | mod patterns; | ||
33 | mod paths; | 34 | mod paths; |
34 | mod type_params; | 35 | mod type_params; |
35 | 36 | ||
@@ -85,10 +86,29 @@ fn abi(p: &mut Parser) { | |||
85 | abi.complete(p, ABI); | 86 | abi.complete(p, ABI); |
86 | } | 87 | } |
87 | 88 | ||
89 | // test fn_value_parameters | ||
90 | // fn a() {} | ||
91 | // fn b(x: i32) {} | ||
92 | // fn c(x: i32, ) {} | ||
93 | // fn d(x: i32, y: ()) {} | ||
88 | fn fn_value_parameters(p: &mut Parser) { | 94 | fn fn_value_parameters(p: &mut Parser) { |
89 | assert!(p.at(L_PAREN)); | 95 | assert!(p.at(L_PAREN)); |
90 | p.bump(); | 96 | p.bump(); |
97 | while !p.at(EOF) && !p.at(R_PAREN) { | ||
98 | value_parameter(p); | ||
99 | if !p.at(R_PAREN) { | ||
100 | p.expect(COMMA); | ||
101 | } | ||
102 | } | ||
91 | p.expect(R_PAREN); | 103 | p.expect(R_PAREN); |
104 | |||
105 | fn value_parameter(p: &mut Parser) { | ||
106 | let m = p.start(); | ||
107 | patterns::pattern(p); | ||
108 | p.expect(COLON); | ||
109 | types::type_(p); | ||
110 | m.complete(p, VALUE_PARAMETER); | ||
111 | } | ||
92 | } | 112 | } |
93 | 113 | ||
94 | fn fn_ret_type(p: &mut Parser) { | 114 | fn fn_ret_type(p: &mut Parser) { |
diff --git a/src/parser/grammar/patterns.rs b/src/parser/grammar/patterns.rs new file mode 100644 index 000000000..6e4f2236b --- /dev/null +++ b/src/parser/grammar/patterns.rs | |||
@@ -0,0 +1,52 @@ | |||
1 | use super::*; | ||
2 | |||
3 | pub(super) fn pattern(p: &mut Parser) { | ||
4 | match p.current() { | ||
5 | UNDERSCORE => placeholder_pat(p), | ||
6 | AMPERSAND => ref_pat(p), | ||
7 | IDENT | REF_KW => bind_pat(p), | ||
8 | _ => p.err_and_bump("expected pattern"), | ||
9 | } | ||
10 | } | ||
11 | |||
12 | // test placeholder_pat | ||
13 | // fn main() { let _ = (); } | ||
14 | fn placeholder_pat(p: &mut Parser) { | ||
15 | assert!(p.at(UNDERSCORE)); | ||
16 | let m = p.start(); | ||
17 | p.bump(); | ||
18 | m.complete(p, PLACEHOLDER_PAT); | ||
19 | } | ||
20 | |||
21 | // test ref_pat | ||
22 | // fn main() { | ||
23 | // let &a = (); | ||
24 | // let &mut b = (); | ||
25 | // } | ||
26 | fn ref_pat(p: &mut Parser) { | ||
27 | assert!(p.at(AMPERSAND)); | ||
28 | let m = p.start(); | ||
29 | p.bump(); | ||
30 | p.eat(MUT_KW); | ||
31 | pattern(p); | ||
32 | m.complete(p, REF_PAT); | ||
33 | } | ||
34 | |||
35 | // test bind_pat | ||
36 | // fn main() { | ||
37 | // let a = (); | ||
38 | // let ref b = (); | ||
39 | // let ref mut c = (); | ||
40 | // let d @ _ = (); | ||
41 | // } | ||
42 | fn bind_pat(p: &mut Parser) { | ||
43 | let m = p.start(); | ||
44 | if p.eat(REF_KW) { | ||
45 | p.eat(MUT_KW); | ||
46 | } | ||
47 | name(p); | ||
48 | if p.eat(AT) { | ||
49 | pattern(p); | ||
50 | } | ||
51 | m.complete(p, BIND_PAT); | ||
52 | } | ||