diff options
author | Aleksey Kladov <[email protected]> | 2018-07-31 21:13:08 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-07-31 21:13:08 +0100 |
commit | d82a21ab202b2f5e8c96847802d806735ec74ad3 (patch) | |
tree | aea23d0bb9760a6104f5994a73b37c869cbaf4bb /src/parser/grammar/expressions.rs | |
parent | 1af8eb9c08f974a1b3beecfebadeb03144ef337d (diff) |
lambda expressions
Diffstat (limited to 'src/parser/grammar/expressions.rs')
-rw-r--r-- | src/parser/grammar/expressions.rs | 77 |
1 files changed, 77 insertions, 0 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 } | ||
52 | pub(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 | // } | ||
89 | fn 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 | |||
47 | fn prefix_expr(p: &mut Parser) -> Option<CompletedMarker> { | 104 | fn 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 | // } | ||
172 | fn 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(); |