about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMichael Sullivan <sully@msully.net>2011-07-18 17:26:37 -0700
committerBrian Anderson <banderson@mozilla.com>2011-07-19 12:01:13 -0700
commitc4bcd0a44d64d43a5c1dfde73d4e3f94e2419da7 (patch)
treec5aadad104a507ad50ff8a4744ec21bd0db7560c /src
parent2e6197aa959126ac882bc8db2f44d32a4af34f0f (diff)
downloadrust-c4bcd0a44d64d43a5c1dfde73d4e3f94e2419da7.tar.gz
rust-c4bcd0a44d64d43a5c1dfde73d4e3f94e2419da7.zip
Move collect_upvars into its own file.
Diffstat (limited to 'src')
-rw-r--r--src/comp/middle/freevars.rs91
-rw-r--r--src/comp/middle/trans.rs76
-rw-r--r--src/comp/rustc.rc1
3 files changed, 96 insertions, 72 deletions
diff --git a/src/comp/middle/freevars.rs b/src/comp/middle/freevars.rs
new file mode 100644
index 00000000000..bf2a8f7e2c9
--- /dev/null
+++ b/src/comp/middle/freevars.rs
@@ -0,0 +1,91 @@
+// A pass that annotates for each loops with the free variables that
+// they contain.
+
+import std::map;
+import std::map::*;
+import syntax::ast;
+import syntax::walk;
+import driver::session;
+import middle::ty;
+import syntax::codemap::span;
+
+
+
+// Searches through part of the AST for all references to locals or
+// upvars in this frame and returns the list of definition IDs thus found.
+// Since we want to be able to collect upvars in some arbitrary piece
+// of the AST, we take a walker function that we invoke with a visitor
+// in order to start the search.
+fn collect_upvars(&ty::ctxt tcx, &fn (&walk::ast_visitor) walker,
+                  ast::node_id[] initial_decls) -> ast::node_id[] {
+    type env =
+        @rec(mutable ast::node_id[] refs,
+             hashmap[ast::node_id, ()] decls,
+             resolve::def_map def_map,
+             session::session sess);
+
+    fn walk_fn(env e, &ast::_fn f, &ast::ty_param[] tps, &span sp,
+               &ast::fn_ident i, ast::node_id nid) {
+        for (ast::arg a in f.decl.inputs) { e.decls.insert(a.id, ()); }
+    }
+    fn walk_expr(env e, &@ast::expr expr) {
+        alt (expr.node) {
+            case (ast::expr_path(?path)) {
+                if (! e.def_map.contains_key(expr.id)) {
+                    e.sess.span_fatal(expr.span,
+                       "internal error in collect_upvars");
+                }
+                alt (e.def_map.get(expr.id)) {
+                    case (ast::def_arg(?did)) { e.refs += ~[did._1]; }
+                    case (ast::def_local(?did)) { e.refs += ~[did._1]; }
+                    case (ast::def_binding(?did)) { e.refs += ~[did._1]; }
+                    case (_) { /* no-op */ }
+                }
+            }
+            case (_) { }
+        }
+    }
+    fn walk_local(env e, &@ast::local local) {
+        e.decls.insert(local.node.id, ());
+    }
+    fn walk_pat(env e, &@ast::pat p) {
+        alt (p.node) {
+            case (ast::pat_bind(_)) {
+                e.decls.insert(p.id, ());
+            }
+            case (_) {}
+        }
+    }
+    let hashmap[ast::node_id, ()] decls = new_int_hash[()]();
+    for (ast::node_id decl in initial_decls) { decls.insert(decl, ()); }
+
+    let env e =
+        @rec(mutable refs=~[],
+             decls=decls,
+             def_map=tcx.def_map,
+             sess=tcx.sess);
+    auto visitor =
+        @rec(visit_fn_pre=bind walk_fn(e, _, _, _, _, _),
+             visit_local_pre=bind walk_local(e, _),
+             visit_expr_pre=bind walk_expr(e, _),
+             visit_pat_pre=bind walk_pat(e, _)
+             with walk::default_visitor());
+    walker(*visitor);
+    // Calculate (refs - decls). This is the set of captured upvars.
+
+    let ast::node_id[] result = ~[];
+    for (ast::node_id ref_id_ in e.refs) {
+        auto ref_id = ref_id_;
+        if (!decls.contains_key(ref_id)) { result += ~[ref_id]; }
+    }
+    ret result;
+}
+
+// Local Variables:
+// mode: rust
+// fill-column: 78;
+// indent-tabs-mode: nil
+// c-basic-offset: 4
+// buffer-file-coding-system: utf-8-unix
+// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
+// End:
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 0fba8ccd2b1..710b91a18a9 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -27,6 +27,7 @@ import syntax::ast;
 import syntax::walk;
 import driver::session;
 import middle::ty;
+import middle::freevars;
 import back::link;
 import back::x86;
 import back::abi;
@@ -4107,76 +4108,6 @@ fn trans_for(&@block_ctxt cx, &@ast::local local, &@ast::expr seq,
 
 // Iterator translation
 
-// Searches through part of the AST for all references to locals or
-// upvars in this frame and returns the list of definition IDs thus found.
-// Since we want to be able to collect upvars in some arbitrary piece
-// of the AST, we take a walker function that we invoke with a visitor
-// in order to start the search.
-fn collect_upvars(&@block_ctxt cx, &fn (&walk::ast_visitor) walker,
-                  ast::node_id[] initial_decls) -> ast::node_id[] {
-    type env =
-        @rec(mutable ast::node_id[] refs,
-             hashmap[ast::node_id, ()] decls,
-             resolve::def_map def_map,
-             session::session sess);
-
-    fn walk_fn(env e, &ast::_fn f, &ast::ty_param[] tps, &span sp,
-               &ast::fn_ident i, ast::node_id nid) {
-        for (ast::arg a in f.decl.inputs) { e.decls.insert(a.id, ()); }
-    }
-    fn walk_expr(env e, &@ast::expr expr) {
-        alt (expr.node) {
-            case (ast::expr_path(?path)) {
-                if (! e.def_map.contains_key(expr.id)) {
-                    e.sess.span_fatal(expr.span,
-                       "internal error in collect_upvars");
-                }
-                alt (e.def_map.get(expr.id)) {
-                    case (ast::def_arg(?did)) { e.refs += ~[did._1]; }
-                    case (ast::def_local(?did)) { e.refs += ~[did._1]; }
-                    case (ast::def_binding(?did)) { e.refs += ~[did._1]; }
-                    case (_) { /* no-op */ }
-                }
-            }
-            case (_) { }
-        }
-    }
-    fn walk_local(env e, &@ast::local local) {
-        e.decls.insert(local.node.id, ());
-    }
-    fn walk_pat(env e, &@ast::pat p) {
-        alt (p.node) {
-            case (ast::pat_bind(_)) {
-                e.decls.insert(p.id, ());
-            }
-            case (_) {}
-        }
-    }
-    let hashmap[ast::node_id, ()] decls = new_int_hash[()]();
-    for (ast::node_id decl in initial_decls) { decls.insert(decl, ()); }
-
-    let env e =
-        @rec(mutable refs=~[],
-             decls=decls,
-             def_map=cx.fcx.lcx.ccx.tcx.def_map,
-             sess=cx.fcx.lcx.ccx.tcx.sess);
-    auto visitor =
-        @rec(visit_fn_pre=bind walk_fn(e, _, _, _, _, _),
-             visit_local_pre=bind walk_local(e, _),
-             visit_expr_pre=bind walk_expr(e, _),
-             visit_pat_pre=bind walk_pat(e, _)
-             with walk::default_visitor());
-    walker(*visitor);
-    // Calculate (refs - decls). This is the set of captured upvars.
-
-    let ast::node_id[] result = ~[];
-    for (ast::node_id ref_id_ in e.refs) {
-        auto ref_id = ref_id_;
-        if (!decls.contains_key(ref_id)) { result += ~[ref_id]; }
-    }
-    ret result;
-}
-
 // Finds the ValueRef associated with a variable in a function
 // context. It checks locals, upvars, and args.
 fn find_variable(&@fn_ctxt fcx, ast::node_id nid) -> ValueRef {
@@ -4353,8 +4284,9 @@ fn trans_for_each(&@block_ctxt cx, &@ast::local local, &@ast::expr seq,
     // FIXME: possibly support alias-mode here?
     auto decl_ty = node_id_type(lcx.ccx, local.node.id);
     auto decl_id = local.node.id;
-    auto upvars = collect_upvars(cx, bind walk::walk_block(_, body),
-                                 ~[decl_id]);
+    auto upvars = freevars::collect_upvars(cx.fcx.lcx.ccx.tcx,
+                                           bind walk::walk_block(_, body),
+                                           ~[decl_id]);
 
     auto environment_data = build_environment(cx, upvars);
     auto llenvptr = environment_data._0;
diff --git a/src/comp/rustc.rc b/src/comp/rustc.rc
index 10e9cb80193..1970aa66cd2 100644
--- a/src/comp/rustc.rc
+++ b/src/comp/rustc.rc
@@ -26,6 +26,7 @@ mod middle {
     mod resolve;
     mod typeck;
     mod alias;
+    mod freevars;
 
     mod tstate {
         mod ck;