about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMarijn Haverbeke <marijnh@gmail.com>2011-07-13 11:33:46 +0200
committerMarijn Haverbeke <marijnh@gmail.com>2011-07-13 11:33:46 +0200
commit8d68b0462aef5799af4cd1054d747f578c34a4cd (patch)
tree33f4d51a1a99c824fda59e0a7cebae3b36c70ae9 /src
parentbe4f7354b475ff8e80a81b495640d7e46d7094cc (diff)
downloadrust-8d68b0462aef5799af4cd1054d747f578c34a4cd.tar.gz
rust-8d68b0462aef5799af4cd1054d747f578c34a4cd.zip
Refactor out some repetetive code in trans_alt
Diffstat (limited to 'src')
-rw-r--r--src/comp/middle/trans_alt.rs105
1 files changed, 46 insertions, 59 deletions
diff --git a/src/comp/middle/trans_alt.rs b/src/comp/middle/trans_alt.rs
index ddd7bcec5d5..d61a72564f6 100644
--- a/src/comp/middle/trans_alt.rs
+++ b/src/comp/middle/trans_alt.rs
@@ -84,63 +84,61 @@ fn bind_for_pat(&@ast::pat p, &match_branch br, ValueRef val) {
     }
 }
 
-fn enter_default(&match m, uint col, ValueRef val) -> match {
+type enter_pat = fn(&@ast::pat) -> option::t[(@ast::pat)[]];
+
+fn enter_match(&match m, uint col, ValueRef val, &enter_pat e) -> match {
     auto result = ~[];
     for (match_branch br in m) {
-        if (matches_always(br.pats.(col))) {
-            auto pats = ivec::slice(br.pats, 0u, col) +
-                ivec::slice(br.pats, col + 1u, ivec::len(br.pats));
-            auto new_br = @rec(pats=pats with *br);
-            result += ~[new_br];
-            bind_for_pat(br.pats.(col), new_br, val);
+        alt (e(br.pats.(col))) {
+            some(?sub) {
+                auto pats = ivec::slice(br.pats, 0u, col) +
+                    sub + ivec::slice(br.pats, col + 1u, ivec::len(br.pats));
+                auto new_br = @rec(pats=pats with *br);
+                result += ~[new_br];
+                bind_for_pat(br.pats.(col), new_br, val);
+            }
+            none {}
         }
     }
     ret result;
 }
 
+fn enter_default(&match m, uint col, ValueRef val) -> match {
+    fn e(&@ast::pat p) -> option::t[(@ast::pat)[]] {
+        ret if (matches_always(p)) { some(~[]) }
+            else { none };
+    }
+    ret enter_match(m, col, val, e);
+}
+
 fn enter_opt(&@crate_ctxt ccx, &match m, &opt opt,
              uint col, uint tag_size, ValueRef val) -> match {
-    auto result = ~[];
     auto dummy = @rec(id=0, node=ast::pat_wild, span=rec(lo=0u, hi=0u));
-    for (match_branch br in m) {
-        auto pats = ivec::slice(br.pats, 0u, col);
-        auto include = true;
-        alt (br.pats.(col).node) {
-            ast::pat_tag(?ctor, _) {
-                include = opt_eq(variant_opt(ccx, br.pats.(col).id), opt);
+    fn e(&@crate_ctxt ccx, &@ast::pat dummy, &opt opt, uint size,
+         &@ast::pat p) -> option::t[(@ast::pat)[]] {
+        alt (p.node) {
+            ast::pat_tag(?ctor, ?subpats) {
+                ret if (opt_eq(variant_opt(ccx, p.id), opt)) { some(subpats) }
+                    else { none };
             }
             ast::pat_lit(?l) {
-                include = opt_eq(lit(l), opt);
+                ret if (opt_eq(lit(l), opt)) { some(~[]) }
+                    else { none };
             }
-            _ {}
-        }
-        if (include) {
-            alt (br.pats.(col).node) {
-                ast::pat_tag(_, ?subpats) {
-                    assert ivec::len(subpats) == tag_size;
-                    pats += subpats;
-                }
-                _ {
-                    pats += ivec::init_elt(dummy, tag_size);
-                }
-            }
-            pats += ivec::slice(br.pats, col + 1u, ivec::len(br.pats));
-            auto new_br = @rec(pats=pats with *br);
-            result += ~[new_br];
-            bind_for_pat(br.pats.(col), new_br, val);
+            _ { ret some(ivec::init_elt(dummy, size)); }
         }
     }
-    ret result;
+    ret enter_match(m, col, val, bind e(ccx, dummy, opt, tag_size, _));
 }
 
-fn enter_rec(&@crate_ctxt ccx, &match m, uint col, &ast::ident[] fields,
+fn enter_rec(&match m, uint col, &ast::ident[] fields,
              ValueRef val) -> match {
-    auto result = ~[];
     auto dummy = @rec(id=0, node=ast::pat_wild, span=rec(lo=0u, hi=0u));
-    for (match_branch br in m) {
-        auto pats = ivec::slice(br.pats, 0u, col);
-        alt (br.pats.(col).node) {
+    fn e(&@ast::pat dummy, &ast::ident[] fields, &@ast::pat p)
+        -> option::t[(@ast::pat)[]] {
+        alt (p.node) {
             ast::pat_rec(?fpats, _) {
+                auto pats = ~[];
                 for (ast::ident fname in fields) {
                     auto pat = dummy;
                     for (ast::field_pat fpat in fpats) {
@@ -151,34 +149,23 @@ fn enter_rec(&@crate_ctxt ccx, &match m, uint col, &ast::ident[] fields,
                     }
                     pats += ~[pat];
                 }
+                ret some(pats);
             }
-            _ {
-                pats += ivec::init_elt(dummy, ivec::len(fields));
-            }
+            _ { ret some(ivec::init_elt(dummy, ivec::len(fields))); }
         }
-        pats += ivec::slice(br.pats, col + 1u, ivec::len(br.pats));
-        auto new_br = @rec(pats=pats with *br);
-        result += ~[new_br];
-        bind_for_pat(br.pats.(col), new_br, val);
     }
-    ret result;
+    ret enter_match(m, col, val, bind e(dummy, fields, _));
 }
 
-fn enter_box(&@crate_ctxt ccx, &match m, uint col, ValueRef val) -> match {
-    auto result = ~[];
+fn enter_box(&match m, uint col, ValueRef val) -> match {
     auto dummy = @rec(id=0, node=ast::pat_wild, span=rec(lo=0u, hi=0u));
-    for (match_branch br in m) {
-        auto pats = ivec::slice(br.pats, 0u, col);
-        alt (br.pats.(col).node) {
-            ast::pat_box(?sub) { pats += ~[sub]; }
-            _ { pats += ~[dummy]; }
+    fn e(&@ast::pat dummy, &@ast::pat p) -> option::t[(@ast::pat)[]] {
+        alt (p.node) {
+            ast::pat_box(?sub) { ret some(~[sub]); }
+            _ { ret some(~[dummy]); }
         }
-        pats += ivec::slice(br.pats, col + 1u, ivec::len(br.pats));
-        auto new_br = @rec(pats=pats with *br);
-        result += ~[new_br];
-        bind_for_pat(br.pats.(col), new_br, val);
     }
-    ret result;
+    ret enter_match(m, col, val, bind e(dummy, _));
 }
 
 fn get_options(&@crate_ctxt ccx, &match m, uint col) -> opt[] {
@@ -301,7 +288,7 @@ fn compile_submatch(@block_ctxt bcx, &match m, ValueRef[] vals, &mk_fail f,
             rec_vals += ~[r.val];
             bcx = r.bcx;
         }
-        compile_submatch(bcx, enter_rec(ccx, m, col, rec_fields, val),
+        compile_submatch(bcx, enter_rec(m, col, rec_fields, val),
                          rec_vals + vals_left, f, exits);
         ret;
     }
@@ -311,7 +298,7 @@ fn compile_submatch(@block_ctxt bcx, &match m, ValueRef[] vals, &mk_fail f,
         auto box = bcx.build.Load(val);
         auto unboxed = bcx.build.InBoundsGEP
             (box, ~[C_int(0), C_int(back::abi::box_rc_field_body)]);
-        compile_submatch(bcx, enter_box(ccx, m, col, val),
+        compile_submatch(bcx, enter_box(m, col, val),
                          ~[unboxed] + vals_left, f, exits);
         ret;
     }