diff options
| author | Rafael Ávila de Espíndola <[email protected]> | 2011-01-07 17:38:13 -0500 |
|---|---|---|
| committer | Graydon Hoare <[email protected]> | 2011-01-07 15:17:18 -0800 |
| commit | 2fb09eb58569f5a0e5544c6256173d4b6b8ffcf2 (patch) | |
| tree | ae9a24f0e04bf84f69cc61acbb15d1d7b72ceb86 /src/comp | |
| parent | Synthesize closure thunks, and pass closure pointer into fn calls. (diff) | |
| download | rust-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.rs | 1 | ||||
| -rw-r--r-- | src/comp/middle/fold.rs | 8 | ||||
| -rw-r--r-- | src/comp/middle/resolve.rs | 143 |
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](_)) { |