about summary refs log tree commit diff
path: root/src/comp/syntax
diff options
context:
space:
mode:
authorMarijn Haverbeke <marijnh@gmail.com>2011-08-15 13:15:19 +0200
committerMarijn Haverbeke <marijnh@gmail.com>2011-08-15 13:20:16 +0200
commit3f127e397fdba5b982603aaab034f6e9aa0992bb (patch)
tree07fc3b6fb6fc599b2ce38fa481c507ea612f9471 /src/comp/syntax
parent1ee24d31e139683a93c6afa93689f5a4122341be (diff)
downloadrust-3f127e397fdba5b982603aaab034f6e9aa0992bb.tar.gz
rust-3f127e397fdba5b982603aaab034f6e9aa0992bb.zip
Add tuple patterns
Diffstat (limited to 'src/comp/syntax')
-rw-r--r--src/comp/syntax/ast.rs20
-rw-r--r--src/comp/syntax/fold.rs3
-rw-r--r--src/comp/syntax/parse/parser.rs18
-rw-r--r--src/comp/syntax/print/pprust.rs5
-rw-r--r--src/comp/syntax/visit.rs3
5 files changed, 38 insertions, 11 deletions
diff --git a/src/comp/syntax/ast.rs b/src/comp/syntax/ast.rs
index bedb2cad64d..d2ad2cd0f08 100644
--- a/src/comp/syntax/ast.rs
+++ b/src/comp/syntax/ast.rs
@@ -126,6 +126,7 @@ tag pat_ {
     pat_lit(@lit);
     pat_tag(path, [@pat]);
     pat_rec([field_pat], bool);
+    pat_tup([@pat]);
     pat_box(@pat);
 }
 
@@ -135,18 +136,10 @@ type pat_id_map = std::map::hashmap[str, ast::node_id];
 // use the node_id of their namesake in the first pattern.
 fn pat_id_map(pat: &@pat) -> pat_id_map {
     let map = std::map::new_str_hash[node_id]();
-    fn walk(map: &pat_id_map, pat: &@pat) {
-        alt pat.node {
-          pat_bind(name) { map.insert(name, pat.id); }
-          pat_tag(_, sub) { for p: @pat in sub { walk(map, p); } }
-          pat_rec(fields, _) {
-            for f: field_pat  in fields { walk(map, f.pat); }
-          }
-          pat_box(inner) { walk(map, inner); }
-          _ { }
-        }
+    for each bound in pat_bindings(pat) {
+        let name = alt bound.node { pat_bind(n) { n } };
+        map.insert(name, bound.id);
     }
-    walk(map, pat);
     ret map;
 }
 
@@ -163,6 +156,11 @@ iter pat_bindings(pat: &@pat) -> @pat {
             for each b in pat_bindings(f.pat) { put b; }
         }
       }
+      pat_tup(elts) {
+        for elt in elts {
+            for each b in pat_bindings(elt) { put b; }
+        }
+      }
       pat_box(sub) {
         for each b in pat_bindings(sub) { put b; }
       }
diff --git a/src/comp/syntax/fold.rs b/src/comp/syntax/fold.rs
index 177e05fa091..77ec93c809b 100644
--- a/src/comp/syntax/fold.rs
+++ b/src/comp/syntax/fold.rs
@@ -283,6 +283,9 @@ fn noop_fold_pat(p: &pat_, fld: ast_fold) -> pat_ {
             }
             pat_rec(fs, etc)
           }
+          pat_tup(elts) {
+            pat_tup(ivec::map(fld.fold_pat, elts))
+          }
           pat_box(inner) { pat_box(fld.fold_pat(inner)) }
         };
 }
diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs
index 8f7dbd184c3..f28ea683cf9 100644
--- a/src/comp/syntax/parse/parser.rs
+++ b/src/comp/syntax/parse/parser.rs
@@ -1454,6 +1454,24 @@ fn parse_pat(p: &parser) -> @ast::pat {
         p.bump();
         pat = ast::pat_rec(fields, etc);
       }
+      token::LPAREN. {
+        p.bump();
+        if p.peek() == token::RPAREN {
+            hi = p.get_hi_pos();
+            p.bump();
+            pat = ast::pat_lit(@{node: ast::lit_nil, span: {lo: lo, hi: hi}});
+        } else {
+            let fields = ~[parse_pat(p)];
+            while p.peek() == token::COMMA {
+                p.bump();
+                fields += ~[parse_pat(p)];
+            }
+            if ivec::len(fields) == 1u { expect(p, token::COMMA); }
+            hi = p.get_hi_pos();
+            expect(p, token::RPAREN);
+            pat = ast::pat_tup(fields);
+        }
+      }
       tok {
         if !is_ident(tok) || is_word(p, "true") || is_word(p, "false") {
             let lit = parse_lit(p);
diff --git a/src/comp/syntax/print/pprust.rs b/src/comp/syntax/print/pprust.rs
index 569a5ad136a..fa2df63e280 100644
--- a/src/comp/syntax/print/pprust.rs
+++ b/src/comp/syntax/print/pprust.rs
@@ -1146,6 +1146,11 @@ fn print_pat(s: &ps, pat: &@ast::pat) {
         }
         word(s.s, "}");
       }
+      ast::pat_tup(elts) {
+        popen(s);
+        commasep(s, inconsistent, elts, print_pat);
+        pclose(s);
+      }
       ast::pat_box(inner) { word(s.s, "@"); print_pat(s, inner); }
     }
     s.ann.post(ann_node);
diff --git a/src/comp/syntax/visit.rs b/src/comp/syntax/visit.rs
index 3fbca6238ee..5f160d88e6f 100644
--- a/src/comp/syntax/visit.rs
+++ b/src/comp/syntax/visit.rs
@@ -175,6 +175,9 @@ fn visit_pat[E](p: &@pat, e: &E, v: &vt[E]) {
       pat_rec(fields, _) {
         for f: field_pat  in fields { v.visit_pat(f.pat, e, v); }
       }
+      pat_tup(elts) {
+        for elt in elts { v.visit_pat(elt, e, v); }
+      }
       pat_box(inner) { v.visit_pat(inner, e, v); }
       _ { }
     }