about summary refs log tree commit diff
path: root/src/comp/syntax/parse
diff options
context:
space:
mode:
authorMarijn Haverbeke <marijnh@gmail.com>2011-07-08 16:27:55 +0200
committerMarijn Haverbeke <marijnh@gmail.com>2011-07-11 11:01:54 +0200
commit86ee3454a1e49b0b913f37c2c52e79d68cae5410 (patch)
treefbb448de5295ab46b6894117597fdb51d2f28001 /src/comp/syntax/parse
parent4d325b1a15126c6aa9f97d510a11d93d4ac2ad53 (diff)
downloadrust-86ee3454a1e49b0b913f37c2c52e79d68cae5410.tar.gz
rust-86ee3454a1e49b0b913f37c2c52e79d68cae5410.zip
Implement or-patterns in case clauses
You can now say

    expr_move(?dst, ?src) | expr_assign(?dst, ?src) { ... }

to match both expr_move and expr_assign. The names, types, and number
of bound names have to match in all the patterns.

Closes #449.
Diffstat (limited to 'src/comp/syntax/parse')
-rw-r--r--src/comp/syntax/parse/parser.rs34
1 files changed, 23 insertions, 11 deletions
diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs
index 75235bfb809..567aa995fd6 100644
--- a/src/comp/syntax/parse/parser.rs
+++ b/src/comp/syntax/parse/parser.rs
@@ -1359,10 +1359,10 @@ fn parse_alt_expr(&parser p) -> @ast::expr {
         eat_word(p, "case");
         auto parens = false;
         if (p.peek() == token::LPAREN) { parens = true; p.bump(); }
-        auto pat = parse_pat(p);
+        auto pats = parse_pats(p);
         if (parens) { expect(p, token::RPAREN); }
         auto block = parse_block(p);
-        arms += ~[rec(pat=pat, block=block)];
+        arms += ~[rec(pats=pats, block=block)];
     }
     auto hi = p.get_hi_pos();
     p.bump();
@@ -1405,20 +1405,32 @@ fn parse_initializer(&parser p) -> option::t[ast::initializer] {
             p.bump();
             ret some(rec(op=ast::init_move, expr=parse_expr(p)));
         }
-        case (
-             // Now that the the channel is the first argument to receive,
-             // combining it with an initializer doesn't really make sense.
-             // case (token::RECV) {
-             //     p.bump();
-             //     ret some(rec(op = ast::init_recv,
-             //                  expr = parse_expr(p)));
-             // }
-             _) {
+        // Now that the the channel is the first argument to receive,
+        // combining it with an initializer doesn't really make sense.
+        // case (token::RECV) {
+        //     p.bump();
+        //     ret some(rec(op = ast::init_recv,
+        //                  expr = parse_expr(p)));
+        // }
+        case (_) {
             ret none;
         }
     }
 }
 
+fn parse_pats(&parser p) -> (@ast::pat)[] {
+    auto pats = ~[];
+    while (true) {
+        pats += ~[parse_pat(p)];
+        if (p.peek() == token::BINOP(token::OR)) {
+            p.bump();
+        } else {
+            break;
+        }
+    }
+    ret pats;
+}
+
 fn parse_pat(&parser p) -> @ast::pat {
     auto lo = p.get_lo_pos();
     auto hi = p.get_hi_pos();