aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-08-04 11:39:03 +0100
committerAleksey Kladov <[email protected]>2018-08-04 11:39:03 +0100
commit8f1c64505574f60c805c5b4a32e55e818b9e0eee (patch)
tree01f97f1eac44cde01a203ccb14b003c42924115b /src
parente919db3731968ae7a6877530d2cb645b0495d5fd (diff)
Match expr
Diffstat (limited to 'src')
-rw-r--r--src/grammar.ron3
-rw-r--r--src/grammar/expressions.rs56
-rw-r--r--src/syntax_kinds/generated.rs6
3 files changed, 63 insertions, 2 deletions
diff --git a/src/grammar.ron b/src/grammar.ron
index 8e8a71010..0239a3c1d 100644
--- a/src/grammar.ron
+++ b/src/grammar.ron
@@ -141,6 +141,9 @@ Grammar(
141 "IF_EXPR", 141 "IF_EXPR",
142 "BLOCK_EXPR", 142 "BLOCK_EXPR",
143 "RETURN_EXPR", 143 "RETURN_EXPR",
144 "MATCH_EXPR",
145 "MATCH_ARM",
146 "MATCH_GUARD",
144 147
145 "EXTERN_BLOCK_EXPR", 148 "EXTERN_BLOCK_EXPR",
146 "ENUM_VARIANT", 149 "ENUM_VARIANT",
diff --git a/src/grammar/expressions.rs b/src/grammar/expressions.rs
index c68419929..6506892e1 100644
--- a/src/grammar/expressions.rs
+++ b/src/grammar/expressions.rs
@@ -27,6 +27,7 @@ pub(super) fn literal(p: &mut Parser) -> Option<CompletedMarker> {
27} 27}
28 28
29const EXPR_FIRST: TokenSet = PREFIX_EXPR_FIRST; 29const EXPR_FIRST: TokenSet = PREFIX_EXPR_FIRST;
30
30pub(super) fn expr(p: &mut Parser) { 31pub(super) fn expr(p: &mut Parser) {
31 let mut lhs = match prefix_expr(p) { 32 let mut lhs = match prefix_expr(p) {
32 Some(lhs) => lhs, 33 Some(lhs) => lhs,
@@ -87,6 +88,7 @@ const PREFIX_EXPR_FIRST: TokenSet =
87 token_set![AMPERSAND, STAR, EXCL], 88 token_set![AMPERSAND, STAR, EXCL],
88 ATOM_EXPR_FIRST, 89 ATOM_EXPR_FIRST,
89 ]; 90 ];
91
90fn prefix_expr(p: &mut Parser) -> Option<CompletedMarker> { 92fn prefix_expr(p: &mut Parser) -> Option<CompletedMarker> {
91 let done = match p.current() { 93 let done = match p.current() {
92 AMPERSAND => ref_expr(p), 94 AMPERSAND => ref_expr(p),
@@ -140,6 +142,7 @@ const ATOM_EXPR_FIRST: TokenSet =
140 LITERAL_FIRST, 142 LITERAL_FIRST,
141 token_set![L_PAREN, PIPE, MOVE_KW, IF_KW, UNSAFE_KW, L_CURLY, RETURN_KW], 143 token_set![L_PAREN, PIPE, MOVE_KW, IF_KW, UNSAFE_KW, L_CURLY, RETURN_KW],
142 ]; 144 ];
145
143fn atom_expr(p: &mut Parser) -> Option<CompletedMarker> { 146fn atom_expr(p: &mut Parser) -> Option<CompletedMarker> {
144 match literal(p) { 147 match literal(p) {
145 Some(m) => return Some(m), 148 Some(m) => return Some(m),
@@ -154,6 +157,7 @@ fn atom_expr(p: &mut Parser) -> Option<CompletedMarker> {
154 PIPE => lambda_expr(p), 157 PIPE => lambda_expr(p),
155 MOVE_KW if la == PIPE => lambda_expr(p), 158 MOVE_KW if la == PIPE => lambda_expr(p),
156 IF_KW => if_expr(p), 159 IF_KW => if_expr(p),
160 MATCH_KW => match_expr(p),
157 UNSAFE_KW if la == L_CURLY => block_expr(p), 161 UNSAFE_KW if la == L_CURLY => block_expr(p),
158 L_CURLY => block_expr(p), 162 L_CURLY => block_expr(p),
159 RETURN_KW => return_expr(p), 163 RETURN_KW => return_expr(p),
@@ -202,8 +206,7 @@ fn lambda_expr(p: &mut Parser) -> CompletedMarker {
202fn if_expr(p: &mut Parser) -> CompletedMarker { 206fn if_expr(p: &mut Parser) -> CompletedMarker {
203 assert!(p.at(IF_KW)); 207 assert!(p.at(IF_KW));
204 let m = p.start(); 208 let m = p.start();
205 p.bump(); 209 if_head(p);
206 expr(p);
207 block(p); 210 block(p);
208 if p.at(ELSE_KW) { 211 if p.at(ELSE_KW) {
209 p.bump(); 212 p.bump();
@@ -216,6 +219,55 @@ fn if_expr(p: &mut Parser) -> CompletedMarker {
216 m.complete(p, IF_EXPR) 219 m.complete(p, IF_EXPR)
217} 220}
218 221
222fn if_head(p: &mut Parser) {
223 assert!(p.at(IF_KW));
224 p.bump();
225 expr(p);
226}
227
228// test match_expr
229// fn foo() {
230// match () { };
231// }
232fn match_expr(p: &mut Parser) -> CompletedMarker {
233 assert!(p.at(MATCH_KW));
234 let m = p.start();
235 p.bump();
236 expr(p);
237 p.eat(L_CURLY);
238 while !p.at(EOF) && !p.at(R_CURLY) {
239 match_arm(p);
240 if !p.at(R_CURLY) {
241 p.expect(COMMA);
242 }
243 }
244 p.expect(R_CURLY);
245 m.complete(p, MATCH_EXPR)
246}
247
248// test match_arm
249// fn foo() {
250// match () {
251// _ => (),
252// X | Y if Z => (),
253// };
254// }
255fn match_arm(p: &mut Parser) {
256 let m = p.start();
257 loop {
258 patterns::pattern(p);
259 if !p.eat(PIPE) {
260 break;
261 }
262 }
263 if p.at(IF_KW) {
264 if_head(p)
265 }
266 p.expect(FAT_ARROW);
267 expr(p);
268 m.complete(p, MATCH_ARM);
269}
270
219// test block_expr 271// test block_expr
220// fn foo() { 272// fn foo() {
221// {}; 273// {};
diff --git a/src/syntax_kinds/generated.rs b/src/syntax_kinds/generated.rs
index 50aa2b580..73b26b274 100644
--- a/src/syntax_kinds/generated.rs
+++ b/src/syntax_kinds/generated.rs
@@ -132,6 +132,9 @@ pub enum SyntaxKind {
132 IF_EXPR, 132 IF_EXPR,
133 BLOCK_EXPR, 133 BLOCK_EXPR,
134 RETURN_EXPR, 134 RETURN_EXPR,
135 MATCH_EXPR,
136 MATCH_ARM,
137 MATCH_GUARD,
135 EXTERN_BLOCK_EXPR, 138 EXTERN_BLOCK_EXPR,
136 ENUM_VARIANT, 139 ENUM_VARIANT,
137 NAMED_FIELD, 140 NAMED_FIELD,
@@ -342,6 +345,9 @@ impl SyntaxKind {
342 IF_EXPR => &SyntaxInfo { name: "IF_EXPR" }, 345 IF_EXPR => &SyntaxInfo { name: "IF_EXPR" },
343 BLOCK_EXPR => &SyntaxInfo { name: "BLOCK_EXPR" }, 346 BLOCK_EXPR => &SyntaxInfo { name: "BLOCK_EXPR" },
344 RETURN_EXPR => &SyntaxInfo { name: "RETURN_EXPR" }, 347 RETURN_EXPR => &SyntaxInfo { name: "RETURN_EXPR" },
348 MATCH_EXPR => &SyntaxInfo { name: "MATCH_EXPR" },
349 MATCH_ARM => &SyntaxInfo { name: "MATCH_ARM" },
350 MATCH_GUARD => &SyntaxInfo { name: "MATCH_GUARD" },
345 EXTERN_BLOCK_EXPR => &SyntaxInfo { name: "EXTERN_BLOCK_EXPR" }, 351 EXTERN_BLOCK_EXPR => &SyntaxInfo { name: "EXTERN_BLOCK_EXPR" },
346 ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" }, 352 ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" },
347 NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" }, 353 NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" },