aboutsummaryrefslogtreecommitdiff
path: root/src/parser/grammar
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser/grammar')
-rw-r--r--src/parser/grammar/expressions.rs17
-rw-r--r--src/parser/grammar/items/mod.rs28
-rw-r--r--src/parser/grammar/mod.rs20
-rw-r--r--src/parser/grammar/patterns.rs52
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
16pub(super) fn expr(p: &mut Parser) { 16pub(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
27fn 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;
30mod attributes; 30mod attributes;
31mod expressions; 31mod expressions;
32mod types; 32mod types;
33mod patterns;
33mod paths; 34mod paths;
34mod type_params; 35mod 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: ()) {}
88fn fn_value_parameters(p: &mut Parser) { 94fn 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
94fn fn_ret_type(p: &mut Parser) { 114fn 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 @@
1use super::*;
2
3pub(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 _ = (); }
14fn 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// }
26fn 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// }
42fn 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}