aboutsummaryrefslogtreecommitdiff
path: root/src/parser
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-07-31 21:13:08 +0100
committerAleksey Kladov <[email protected]>2018-07-31 21:13:08 +0100
commitd82a21ab202b2f5e8c96847802d806735ec74ad3 (patch)
treeaea23d0bb9760a6104f5994a73b37c869cbaf4bb /src/parser
parent1af8eb9c08f974a1b3beecfebadeb03144ef337d (diff)
lambda expressions
Diffstat (limited to 'src/parser')
-rw-r--r--src/parser/grammar/expressions.rs77
-rw-r--r--src/parser/grammar/items/mod.rs63
-rw-r--r--src/parser/grammar/mod.rs65
-rw-r--r--src/parser/grammar/params.rs71
-rw-r--r--src/parser/grammar/types.rs2
5 files changed, 158 insertions, 120 deletions
diff --git a/src/parser/grammar/expressions.rs b/src/parser/grammar/expressions.rs
index ef3a0f76c..09b351f31 100644
--- a/src/parser/grammar/expressions.rs
+++ b/src/parser/grammar/expressions.rs
@@ -44,6 +44,63 @@ pub(super) fn expr(p: &mut Parser) {
44 } 44 }
45} 45}
46 46
47// test block
48// fn a() {}
49// fn b() { let _ = 1; }
50// fn c() { 1; 2; }
51// fn d() { 1; 2 }
52pub(super) fn block(p: &mut Parser) {
53 if !p.at(L_CURLY) {
54 p.error("expected block");
55 }
56 let m = p.start();
57 p.bump();
58 while !p.at(EOF) && !p.at(R_CURLY) {
59 match p.current() {
60 LET_KW => let_stmt(p),
61 c => {
62 // test block_items
63 // fn a() { fn b() {} }
64 if items::ITEM_FIRST.contains(c) {
65 items::item(p)
66 } else {
67 let expr_stmt = p.start();
68 expressions::expr(p);
69 if p.eat(SEMI) {
70 expr_stmt.complete(p, EXPR_STMT);
71 } else {
72 expr_stmt.abandon(p);
73 }
74 }
75 }
76 }
77 }
78 p.expect(R_CURLY);
79 m.complete(p, BLOCK);
80}
81
82// test let_stmt;
83// fn foo() {
84// let a;
85// let b: i32;
86// let c = 92;
87// let d: i32 = 92;
88// }
89fn let_stmt(p: &mut Parser) {
90 assert!(p.at(LET_KW));
91 let m = p.start();
92 p.bump();
93 patterns::pattern(p);
94 if p.at(COLON) {
95 types::ascription(p);
96 }
97 if p.eat(EQ) {
98 expressions::expr(p);
99 }
100 p.expect(SEMI);
101 m.complete(p, LET_STMT);
102}
103
47fn prefix_expr(p: &mut Parser) -> Option<CompletedMarker> { 104fn prefix_expr(p: &mut Parser) -> Option<CompletedMarker> {
48 match p.current() { 105 match p.current() {
49 AMPERSAND => Some(ref_expr(p)), 106 AMPERSAND => Some(ref_expr(p)),
@@ -89,6 +146,7 @@ fn atom_expr(p: &mut Parser) -> Option<CompletedMarker> {
89 146
90 match p.current() { 147 match p.current() {
91 L_PAREN => Some(tuple_expr(p)), 148 L_PAREN => Some(tuple_expr(p)),
149 PIPE => Some(lambda_expr(p)),
92 _ => { 150 _ => {
93 p.err_and_bump("expected expression"); 151 p.err_and_bump("expected expression");
94 None 152 None
@@ -104,6 +162,25 @@ fn tuple_expr(p: &mut Parser) -> CompletedMarker {
104 m.complete(p, TUPLE_EXPR) 162 m.complete(p, TUPLE_EXPR)
105} 163}
106 164
165// test lambda_expr
166// fn foo() {
167// || ();
168// || -> i32 { 92 };
169// |x| x;
170// |x: i32,| x;
171// }
172fn lambda_expr(p: &mut Parser) -> CompletedMarker {
173 assert!(p.at(PIPE));
174 let m = p.start();
175 params::list_opt_types(p);
176 if fn_ret_type(p) {
177 block(p);
178 } else {
179 expr(p)
180 }
181 m.complete(p, LAMBDA_EXPR)
182}
183
107// test call_expr 184// test call_expr
108// fn foo() { 185// fn foo() {
109// let _ = f(); 186// let _ = f();
diff --git a/src/parser/grammar/items/mod.rs b/src/parser/grammar/items/mod.rs
index d1da1ecb4..8c2704be5 100644
--- a/src/parser/grammar/items/mod.rs
+++ b/src/parser/grammar/items/mod.rs
@@ -15,7 +15,7 @@ pub(super) fn mod_contents(p: &mut Parser, stop_on_r_curly: bool) {
15pub(super) const ITEM_FIRST: TokenSet = 15pub(super) const ITEM_FIRST: TokenSet =
16 token_set![EXTERN_KW, MOD_KW, USE_KW, STRUCT_KW, ENUM_KW, FN_KW, PUB_KW, POUND]; 16 token_set![EXTERN_KW, MOD_KW, USE_KW, STRUCT_KW, ENUM_KW, FN_KW, PUB_KW, POUND];
17 17
18fn item(p: &mut Parser) { 18pub(super) fn item(p: &mut Parser) {
19 let item = p.start(); 19 let item = p.start();
20 attributes::outer_attributes(p); 20 attributes::outer_attributes(p);
21 visibility(p); 21 visibility(p);
@@ -239,7 +239,7 @@ fn fn_item(p: &mut Parser) {
239 type_params::list(p); 239 type_params::list(p);
240 240
241 if p.at(L_PAREN) { 241 if p.at(L_PAREN) {
242 fn_value_parameters(p); 242 params::list(p);
243 } else { 243 } else {
244 p.error("expected function arguments"); 244 p.error("expected function arguments");
245 } 245 }
@@ -252,64 +252,7 @@ fn fn_item(p: &mut Parser) {
252 // fn foo<T>() where T: Copy {} 252 // fn foo<T>() where T: Copy {}
253 type_params::where_clause(p); 253 type_params::where_clause(p);
254 254
255 block(p); 255 expressions::block(p);
256
257 // test block
258 // fn a() {}
259 // fn b() { let _ = 1; }
260 // fn c() { 1; 2; }
261 // fn d() { 1; 2 }
262 fn block(p: &mut Parser) {
263 if !p.at(L_CURLY) {
264 p.error("expected block");
265 }
266 let m = p.start();
267 p.bump();
268 while !p.at(EOF) && !p.at(R_CURLY) {
269 match p.current() {
270 LET_KW => let_stmt(p),
271 c => {
272 // test block_items
273 // fn a() { fn b() {} }
274 if ITEM_FIRST.contains(c) {
275 item(p)
276 } else {
277 let expr_stmt = p.start();
278 expressions::expr(p);
279 if p.eat(SEMI) {
280 expr_stmt.complete(p, EXPR_STMT);
281 } else {
282 expr_stmt.abandon(p);
283 }
284 }
285 }
286 }
287 }
288 p.expect(R_CURLY);
289 m.complete(p, BLOCK);
290 }
291
292 // test let_stmt;
293 // fn foo() {
294 // let a;
295 // let b: i32;
296 // let c = 92;
297 // let d: i32 = 92;
298 // }
299 fn let_stmt(p: &mut Parser) {
300 assert!(p.at(LET_KW));
301 let m = p.start();
302 p.bump();
303 patterns::pattern(p);
304 if p.at(COLON) {
305 types::ascription(p);
306 }
307 if p.eat(EQ) {
308 expressions::expr(p);
309 }
310 p.expect(SEMI);
311 m.complete(p, LET_STMT);
312 }
313} 256}
314 257
315// test type_item 258// test type_item
diff --git a/src/parser/grammar/mod.rs b/src/parser/grammar/mod.rs
index 69942e7f1..d4f9b80cf 100644
--- a/src/parser/grammar/mod.rs
+++ b/src/parser/grammar/mod.rs
@@ -26,8 +26,9 @@ mod expressions;
26mod items; 26mod items;
27mod paths; 27mod paths;
28mod patterns; 28mod patterns;
29mod type_args; 29mod params;
30mod type_params; 30mod type_params;
31mod type_args;
31mod types; 32mod types;
32 33
33use { 34use {
@@ -95,67 +96,13 @@ fn abi(p: &mut Parser) {
95 abi.complete(p, ABI); 96 abi.complete(p, ABI);
96} 97}
97 98
98// test fn_value_parameters 99fn fn_ret_type(p: &mut Parser) -> bool {
99// fn a() {}
100// fn b(x: i32) {}
101// fn c(x: i32, ) {}
102// fn d(x: i32, y: ()) {}
103fn fn_value_parameters(p: &mut Parser) {
104 assert!(p.at(L_PAREN));
105 let m = p.start();
106 p.bump();
107 self_param(p);
108 while !p.at(EOF) && !p.at(R_PAREN) {
109 value_parameter(p);
110 if !p.at(R_PAREN) {
111 p.expect(COMMA);
112 }
113 }
114 p.expect(R_PAREN);
115 m.complete(p, PARAM_LIST);
116
117 fn value_parameter(p: &mut Parser) {
118 let m = p.start();
119 patterns::pattern(p);
120 p.expect(COLON);
121 types::type_(p);
122 m.complete(p, VALUE_PARAMETER);
123 }
124
125 // test self_param
126 // impl S {
127 // fn a(self) {}
128 // fn b(&self,) {}
129 // fn c(&'a self,) {}
130 // fn d(&'a mut self, x: i32) {}
131 // }
132 fn self_param(p: &mut Parser) {
133 let la1 = p.nth(1);
134 let la2 = p.nth(2);
135 let la3 = p.nth(3);
136 let n_toks = match (p.current(), la1, la2, la3) {
137 (SELF_KW, _, _, _) => 1,
138 (AMPERSAND, SELF_KW, _, _) => 2,
139 (AMPERSAND, MUT_KW, SELF_KW, _) => 3,
140 (AMPERSAND, LIFETIME, SELF_KW, _) => 3,
141 (AMPERSAND, LIFETIME, MUT_KW, SELF_KW) => 4,
142 _ => return,
143 };
144 let m = p.start();
145 for _ in 0..n_toks {
146 p.bump();
147 }
148 m.complete(p, SELF_PARAM);
149 if !p.at(R_PAREN) {
150 p.expect(COMMA);
151 }
152 }
153}
154
155fn fn_ret_type(p: &mut Parser) {
156 if p.at(THIN_ARROW) { 100 if p.at(THIN_ARROW) {
157 p.bump(); 101 p.bump();
158 types::type_(p); 102 types::type_(p);
103 true
104 } else {
105 false
159 } 106 }
160} 107}
161 108
diff --git a/src/parser/grammar/params.rs b/src/parser/grammar/params.rs
new file mode 100644
index 000000000..1ef2cea88
--- /dev/null
+++ b/src/parser/grammar/params.rs
@@ -0,0 +1,71 @@
1use 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: ()) {}
8pub(super) fn list(p: &mut Parser) {
9 list_(p, true)
10}
11
12pub(super) fn list_opt_types(p: &mut Parser) {
13 list_(p, false)
14}
15
16fn 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
34fn 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, VALUE_PARAMETER);
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// }
50fn 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}
71
diff --git a/src/parser/grammar/types.rs b/src/parser/grammar/types.rs
index 31871ceec..6535f6872 100644
--- a/src/parser/grammar/types.rs
+++ b/src/parser/grammar/types.rs
@@ -166,7 +166,7 @@ fn fn_pointer_type(p: &mut Parser) {
166 return; 166 return;
167 } 167 }
168 168
169 fn_value_parameters(p); 169 params::list(p);
170 // test fn_pointer_type_with_ret 170 // test fn_pointer_type_with_ret
171 // type F = fn() -> (); 171 // type F = fn() -> ();
172 fn_ret_type(p); 172 fn_ret_type(p);