diff options
Diffstat (limited to 'src/grammar/params.rs')
-rw-r--r-- | src/grammar/params.rs | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/src/grammar/params.rs b/src/grammar/params.rs new file mode 100644 index 000000000..be985c80f --- /dev/null +++ b/src/grammar/params.rs | |||
@@ -0,0 +1,70 @@ | |||
1 | use super::*; | ||
2 | |||
3 | // test param_list | ||
4 | // fn a() {} | ||
5 | // fn b(x: i32) {} | ||
6 | // fn c(x: i32, ) {} | ||
7 | // fn d(x: i32, y: ()) {} | ||
8 | pub(super) fn param_list(p: &mut Parser) { | ||
9 | list_(p, true) | ||
10 | } | ||
11 | |||
12 | pub(super) fn param_list_opt_types(p: &mut Parser) { | ||
13 | list_(p, false) | ||
14 | } | ||
15 | |||
16 | fn list_(p: &mut Parser, require_types: bool) { | ||
17 | assert!(p.at(if require_types { L_PAREN } else { PIPE })); | ||
18 | let m = p.start(); | ||
19 | p.bump(); | ||
20 | if require_types { | ||
21 | self_param(p); | ||
22 | } | ||
23 | let terminator = if require_types { R_PAREN } else { PIPE }; | ||
24 | while !p.at(EOF) && !p.at(terminator) { | ||
25 | value_parameter(p, require_types); | ||
26 | if !p.at(terminator) { | ||
27 | p.expect(COMMA); | ||
28 | } | ||
29 | } | ||
30 | p.expect(terminator); | ||
31 | m.complete(p, PARAM_LIST); | ||
32 | } | ||
33 | |||
34 | fn value_parameter(p: &mut Parser, require_type: bool) { | ||
35 | let m = p.start(); | ||
36 | patterns::pattern(p); | ||
37 | if p.at(COLON) || require_type { | ||
38 | types::ascription(p) | ||
39 | } | ||
40 | m.complete(p, PARAM); | ||
41 | } | ||
42 | |||
43 | // test self_param | ||
44 | // impl S { | ||
45 | // fn a(self) {} | ||
46 | // fn b(&self,) {} | ||
47 | // fn c(&'a self,) {} | ||
48 | // fn d(&'a mut self, x: i32) {} | ||
49 | // } | ||
50 | fn self_param(p: &mut Parser) { | ||
51 | let la1 = p.nth(1); | ||
52 | let la2 = p.nth(2); | ||
53 | let la3 = p.nth(3); | ||
54 | let n_toks = match (p.current(), la1, la2, la3) { | ||
55 | (SELF_KW, _, _, _) => 1, | ||
56 | (AMPERSAND, SELF_KW, _, _) => 2, | ||
57 | (AMPERSAND, MUT_KW, SELF_KW, _) => 3, | ||
58 | (AMPERSAND, LIFETIME, SELF_KW, _) => 3, | ||
59 | (AMPERSAND, LIFETIME, MUT_KW, SELF_KW) => 4, | ||
60 | _ => return, | ||
61 | }; | ||
62 | let m = p.start(); | ||
63 | for _ in 0..n_toks { | ||
64 | p.bump(); | ||
65 | } | ||
66 | m.complete(p, SELF_PARAM); | ||
67 | if !p.at(R_PAREN) { | ||
68 | p.expect(COMMA); | ||
69 | } | ||
70 | } | ||