aboutsummaryrefslogtreecommitdiff
path: root/src/comp
diff options
context:
space:
mode:
authorRafael Ávila de Espíndola <[email protected]>2011-01-07 17:38:13 -0500
committerGraydon Hoare <[email protected]>2011-01-07 15:17:18 -0800
commit2fb09eb58569f5a0e5544c6256173d4b6b8ffcf2 (patch)
treeae9a24f0e04bf84f69cc61acbb15d1d7b72ceb86 /src/comp
parentSynthesize closure thunks, and pass closure pointer into fn calls. (diff)
downloadrust-2fb09eb58569f5a0e5544c6256173d4b6b8ffcf2.tar.xz
rust-2fb09eb58569f5a0e5544c6256173d4b6b8ffcf2.zip
Add sufficient import support to compile some simple single-crate programs.
This is likely not the final solution. It does repetitive work and doesn't produce errors for invalid but unused imports. In any case, I think it is a useful step.
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/front/ast.rs1
-rw-r--r--src/comp/middle/fold.rs8
-rw-r--r--src/comp/middle/resolve.rs143
3 files changed, 115 insertions, 37 deletions
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs
index fff7b24c..5dc0c4d2 100644
--- a/src/comp/front/ast.rs
+++ b/src/comp/front/ast.rs
@@ -36,7 +36,6 @@ tag def {
def_ty_arg(def_id);
def_binding(def_id);
def_use(def_id);
- def_import(def_id);
}
type crate = spanned[crate_];
diff --git a/src/comp/middle/fold.rs b/src/comp/middle/fold.rs
index 70f6e470..6679fc5f 100644
--- a/src/comp/middle/fold.rs
+++ b/src/comp/middle/fold.rs
@@ -781,14 +781,14 @@ fn fold_mod[ENV](&ENV e, ast_fold[ENV] fld, &ast._mod m) -> ast._mod {
let vec[@item] items = vec();
auto index = m.index;
- for (@item i in m.items) {
- append[@item](items, fold_item[ENV](e, fld, i));
- }
-
for (@view_item vi in m.view_items) {
append[@view_item](view_items, fold_view_item[ENV](e, fld, vi));
}
+ for (@item i in m.items) {
+ append[@item](items, fold_item[ENV](e, fld, i));
+ }
+
ret fld.fold_mod(e, rec(view_items=view_items, items=items, index=index));
}
diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs
index e1f58b5d..808637e7 100644
--- a/src/comp/middle/resolve.rs
+++ b/src/comp/middle/resolve.rs
@@ -24,39 +24,106 @@ tag scope {
type env = rec(list[scope] scopes,
session.session sess);
-fn lookup_name(&env e, ast.ident i) -> option.t[def] {
+// A simple wrapper over defs that stores a bit more information about modules
+// and uses so that we can use the regular lookup_name when resolving imports.
+tag def_wrap {
+ def_wrap_use(@ast.view_item);
+ def_wrap_mod(@ast.item);
+ def_wrap_other(def);
+}
+
+fn unwrap_def(option.t[def_wrap] d_) -> option.t[def] {
+ alt (d_) {
+ case (none[def_wrap]) {
+ ret none[def];
+ }
+ case (some[def_wrap](?d)) {
+ alt (d) {
+ case (def_wrap_use(?it)) {
+ alt (it.node) {
+ case (ast.view_item_use(_, _, ?id)) {
+ ret some[def](ast.def_use(id));
+ }
+ }
+ fail;
+ }
+ case (def_wrap_mod(?i)) {
+ alt (i.node) {
+ case (ast.item_mod(_, _, ?id)) {
+ ret some[def](ast.def_mod(id));
+ }
+ }
+ fail;
+ }
+ case (def_wrap_other(?d)) {
+ ret some[def](d);
+ }
+ }
+ }
+ }
+ fail;
+}
+
+// Follow the path of an import and return what it ultimately points to.
+
+fn find_final_def(&env e, vec[ident] idents) -> option.t[def_wrap] {
+ auto len = _vec.len[ident](idents);
+ auto first = idents.(0);
+ if (len == 1u) {
+ ret lookup_name(e, first);
+ }
+ auto d_ = lookup_name(e, first);
+ alt (d_) {
+ case (none[def_wrap]) {
+ ret d_;
+ }
+ case (some[def_wrap](?d)) {
+ alt(d) {
+ case (def_wrap_mod(?i)) {
+ auto new_env = update_env_for_item(e, i);
+ auto new_idents = _vec.slice[ident](idents, 1u, len);
+ ret find_final_def(new_env, new_idents);
+ }
+ }
+ }
+ }
+ fail;
+}
+
+fn lookup_name(&env e, ast.ident i) -> option.t[def_wrap] {
// log "resolving name " + i;
- fn found_def_item(@ast.item i) -> option.t[def] {
+ fn found_def_item(@ast.item i) -> option.t[def_wrap] {
alt (i.node) {
case (ast.item_const(_, _, _, ?id, _)) {
- ret some[def](ast.def_const(id));
+ ret some[def_wrap](def_wrap_other(ast.def_const(id)));
}
case (ast.item_fn(_, _, _, ?id, _)) {
- ret some[def](ast.def_fn(id));
+ ret some[def_wrap](def_wrap_other(ast.def_fn(id)));
}
case (ast.item_mod(_, _, ?id)) {
- ret some[def](ast.def_mod(id));
+ ret some[def_wrap](def_wrap_mod(i));
}
case (ast.item_ty(_, _, _, ?id, _)) {
- ret some[def](ast.def_ty(id));
+ ret some[def_wrap](def_wrap_other(ast.def_ty(id)));
}
case (ast.item_tag(_, _, _, ?id)) {
- ret some[def](ast.def_ty(id));
+ ret some[def_wrap](def_wrap_other(ast.def_ty(id)));
}
case (ast.item_obj(_, _, _, ?id, _)) {
- ret some[def](ast.def_obj(id));
+ ret some[def_wrap](def_wrap_other(ast.def_obj(id)));
}
}
}
- fn found_decl_stmt(@ast.stmt s) -> option.t[def] {
+ fn found_decl_stmt(@ast.stmt s) -> option.t[def_wrap] {
alt (s.node) {
case (ast.stmt_decl(?d)) {
alt (d.node) {
case (ast.decl_local(?loc)) {
- ret some[def](ast.def_local(loc.id));
+ auto t = ast.def_local(loc.id);
+ ret some[def_wrap](def_wrap_other(t));
}
case (ast.decl_item(?it)) {
ret found_def_item(it);
@@ -64,26 +131,32 @@ fn lookup_name(&env e, ast.ident i) -> option.t[def] {
}
}
}
- ret none[def];
+ ret none[def_wrap];
}
- fn found_def_view(@ast.view_item i) -> option.t[def] {
+ fn found_def_view(&env e, @ast.view_item i) -> option.t[def_wrap] {
alt (i.node) {
case (ast.view_item_use(_, _, ?id)) {
- ret some[def](ast.def_use(id));
+ ret some[def_wrap](def_wrap_use(i));
}
- case (ast.view_item_import(_,?id)) {
- ret some[def](ast.def_import(id));
+ case (ast.view_item_import(?idents,_)) {
+ auto d = find_final_def(e, idents);
+ alt (d) {
+ case (some[def_wrap](_)) {
+ ret d;
+ }
+ }
}
}
+ fail;
}
- fn check_mod(ast.ident i, ast._mod m) -> option.t[def] {
+ fn check_mod(&env e, ast.ident i, ast._mod m) -> option.t[def_wrap] {
alt (m.index.find(i)) {
case (some[ast.mod_index_entry](?ent)) {
alt (ent) {
case (ast.mie_view_item(?ix)) {
- ret found_def_view(m.view_items.(ix));
+ ret found_def_view(e, m.view_items.(ix));
}
case (ast.mie_item(?ix)) {
ret found_def_item(m.items.(ix));
@@ -92,7 +165,8 @@ fn lookup_name(&env e, ast.ident i) -> option.t[def] {
alt (m.items.(item_idx).node) {
case (ast.item_tag(_, ?variants, _, ?tid)) {
auto vid = variants.(variant_idx).id;
- ret some[def](ast.def_variant(tid, vid));
+ auto t = ast.def_variant(tid, vid);
+ ret some[def_wrap](def_wrap_other(t));
}
case (_) {
log "tag item not actually a tag";
@@ -104,15 +178,15 @@ fn lookup_name(&env e, ast.ident i) -> option.t[def] {
}
case (none[ast.mod_index_entry]) { /* fall through */ }
}
- ret none[def];
+ ret none[def_wrap];
}
- fn in_scope(ast.ident i, &scope s) -> option.t[def] {
+ fn in_scope(ast.ident i, env e, &scope s) -> option.t[def_wrap] {
alt (s) {
case (scope_crate(?c)) {
- ret check_mod(i, c.node.module);
+ ret check_mod(e, i, c.node.module);
}
case (scope_item(?it)) {
@@ -120,29 +194,33 @@ fn lookup_name(&env e, ast.ident i) -> option.t[def] {
case (ast.item_fn(_, ?f, ?ty_params, _, _)) {
for (ast.arg a in f.inputs) {
if (_str.eq(a.ident, i)) {
- ret some[def](ast.def_arg(a.id));
+ auto t = ast.def_arg(a.id);
+ ret some[def_wrap](def_wrap_other(t));
}
}
for (ast.ty_param tp in ty_params) {
if (_str.eq(tp.ident, i)) {
- ret some[def](ast.def_ty_arg(tp.id));
+ auto t = ast.def_ty_arg(tp.id);
+ ret some[def_wrap](def_wrap_other(t));
}
}
}
case (ast.item_obj(_, ?ob, ?ty_params, _, _)) {
for (ast.obj_field f in ob.fields) {
if (_str.eq(f.ident, i)) {
- ret some[def](ast.def_obj_field(f.id));
+ auto t = ast.def_obj_field(f.id);
+ ret some[def_wrap](def_wrap_other(t));
}
}
for (ast.ty_param tp in ty_params) {
if (_str.eq(tp.ident, i)) {
- ret some[def](ast.def_ty_arg(tp.id));
+ auto t = ast.def_ty_arg(tp.id);
+ ret some[def_wrap](def_wrap_other(t));
}
}
}
case (ast.item_mod(_, ?m, _)) {
- ret check_mod(i, m);
+ ret check_mod(e, i, m);
}
case (_) { /* fall through */ }
}
@@ -160,22 +238,23 @@ fn lookup_name(&env e, ast.ident i) -> option.t[def] {
case (scope_arm(?a)) {
alt (a.index.find(i)) {
case (some[ast.def_id](?did)) {
- ret some[def](ast.def_binding(did));
+ auto t = ast.def_binding(did);
+ ret some[def_wrap](def_wrap_other(t));
}
case (_) { /* fall through */ }
}
}
}
- ret none[def];
+ ret none[def_wrap];
}
- ret std.list.find[scope,def](e.scopes, bind in_scope(i, _));
+ ret std.list.find[scope,def_wrap](e.scopes, bind in_scope(i, e, _));
}
fn fold_pat_tag(&env e, &span sp, ident i, vec[@ast.pat] args,
option.t[ast.variant_def] old_def, ann a) -> @ast.pat {
auto new_def;
- alt (lookup_name(e, i)) {
+ alt (unwrap_def(lookup_name(e, i))) {
case (some[def](?d)) {
alt (d) {
case (ast.def_variant(?did, ?vid)) {
@@ -203,7 +282,7 @@ fn fold_expr_name(&env e, &span sp, &ast.name n,
e.sess.unimpl("resolving name expr with ty params");
}
- auto d_ = lookup_name(e, n.node.ident);
+ auto d_ = unwrap_def(lookup_name(e, n.node.ident));
alt (d_) {
case (some[def](_)) {
@@ -232,7 +311,7 @@ fn fold_ty_path(&env e, &span sp, ast.path p,
e.sess.unimpl("resolving path ty with ty params");
}
- auto d_ = lookup_name(e, n.node.ident);
+ auto d_ = unwrap_def(lookup_name(e, n.node.ident));
alt (d_) {
case (some[def](_)) {