about summary refs log tree commit diff
path: root/src/comp
diff options
context:
space:
mode:
authorRafael Ávila de Espíndola <respindola@mozilla.com>2011-03-11 17:10:11 -0500
committerRafael Ávila de Espíndola <respindola@mozilla.com>2011-03-11 17:12:25 -0500
commit28d51e3fd2cccdb9fefab71b476fd868a2363ac9 (patch)
tree55cffdf76ee450919e60c24ec74ae12ee0b13dfd /src/comp
parent5c21f039903311a9403b7fe7cfa0d2e455a7c4f0 (diff)
Add support for indexing tags in blocks.
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/front/ast.rs8
-rw-r--r--src/comp/front/parser.rs24
-rw-r--r--src/comp/middle/resolve.rs44
3 files changed, 57 insertions, 19 deletions
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs
index 05daf5eeb1d..c17eddeee78 100644
--- a/src/comp/front/ast.rs
+++ b/src/comp/front/ast.rs
@@ -66,9 +66,15 @@ type meta_item = spanned[meta_item_];
 type meta_item_ = rec(ident name, str value);
 
 type block = spanned[block_];
+type block_index = hashmap[ident, block_index_entry];
+tag block_index_entry {
+    bie_item(@item);
+    bie_local(@local);
+    bie_tag_variant(@item /* tag item */, uint /* variant index */);
+}
 type block_ = rec(vec[@stmt] stmts,
                   option.t[@expr] expr,
-                  hashmap[ident,uint] index);
+                  hashmap[ident,block_index_entry] index);
 
 type variant_def = tup(def_id /* tag */, def_id /* variant */);
 
diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs
index 2836b12054c..58cbac00846 100644
--- a/src/comp/front/parser.rs
+++ b/src/comp/front/parser.rs
@@ -1478,31 +1478,36 @@ impure fn parse_source_stmt(parser p) -> @ast.stmt {
 }
 
 fn index_block(vec[@ast.stmt] stmts, option.t[@ast.expr] expr) -> ast.block_ {
-    auto index = new_str_hash[uint]();
-    auto u = 0u;
+    auto index = new_str_hash[ast.block_index_entry]();
     for (@ast.stmt s in stmts) {
         alt (s.node) {
             case (ast.stmt_decl(?d)) {
                 alt (d.node) {
                     case (ast.decl_local(?loc)) {
-                        index.insert(loc.ident, u);
+                        index.insert(loc.ident, ast.bie_local(loc));
                     }
                     case (ast.decl_item(?it)) {
                         alt (it.node) {
                             case (ast.item_fn(?i, _, _, _, _)) {
-                                index.insert(i, u);
+                                index.insert(i, ast.bie_item(it));
                             }
                             case (ast.item_mod(?i, _, _)) {
-                                index.insert(i, u);
+                                index.insert(i, ast.bie_item(it));
                             }
                             case (ast.item_ty(?i, _, _, _, _)) {
-                                index.insert(i, u);
+                                index.insert(i, ast.bie_item(it));
                             }
-                            case (ast.item_tag(?i, _, _, _)) {
-                                index.insert(i, u);
+                            case (ast.item_tag(?i, ?variants, _, _)) {
+                                index.insert(i, ast.bie_item(it));
+                                let uint vid = 0u;
+                                for (ast.variant v in variants) {
+                                    auto t = ast.bie_tag_variant(it, vid);
+                                    index.insert(v.name, t);
+                                    vid += 1u;
+                                }
                             }
                             case (ast.item_obj(?i, _, _, _, _)) {
-                                index.insert(i, u);
+                                index.insert(i, ast.bie_item(it));
                             }
                         }
                     }
@@ -1510,7 +1515,6 @@ fn index_block(vec[@ast.stmt] stmts, option.t[@ast.expr] expr) -> ast.block_ {
             }
             case (_) { /* fall through */ }
         }
-        u += 1u;
     }
     ret rec(stmts=stmts, expr=expr, index=index);
 }
diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs
index 7102e442fac..1079489e96b 100644
--- a/src/comp/middle/resolve.rs
+++ b/src/comp/middle/resolve.rs
@@ -342,6 +342,40 @@ fn lookup_name_wrapped(&env e, ast.ident i) -> option.t[tup(@env, def_wrap)] {
         ret none[def_wrap];
     }
 
+    fn found_tag(@ast.item item, uint variant_idx) -> def_wrap {
+        alt (item.node) {
+            case (ast.item_tag(_, ?variants, _, ?tid)) {
+                auto vid = variants.(variant_idx).id;
+                auto t = ast.def_variant(tid, vid);
+                ret def_wrap_other(t);
+            }
+            case (_) {
+                log "tag item not actually a tag";
+                fail;
+            }
+        }
+    }
+
+    fn check_block(ast.ident i, &ast.block_ b) -> option.t[def_wrap] {
+        alt (b.index.find(i)) {
+            case (some[ast.block_index_entry](?ix)) {
+                alt(ix) {
+                    case (ast.bie_item(?it)) {
+                        ret some(found_def_item(it));
+                    }
+                    case (ast.bie_local(?l)) {
+                        auto t = ast.def_local(l.id);
+                        ret some(def_wrap_other(t));
+                    }
+                    case (ast.bie_tag_variant(?item, ?variant_idx)) {
+                        ret some(found_tag(item, variant_idx));
+                    }
+                }
+            }
+            case (_) { ret none[def_wrap]; }
+        }
+    }
+
     fn in_scope(ast.ident i, &scope s) -> option.t[def_wrap] {
         alt (s) {
 
@@ -368,7 +402,7 @@ fn lookup_name_wrapped(&env e, ast.ident i) -> option.t[tup(@env, def_wrap)] {
                             }
                         }
                     }
-                    case (ast.item_tag(_, _, ?ty_params, _)) {
+                    case (ast.item_tag(_, ?variants, ?ty_params, ?tag_id)) {
                         for (ast.ty_param tp in ty_params) {
                             if (_str.eq(tp.ident, i)) {
                                 auto t = ast.def_ty_arg(tp.id);
@@ -414,13 +448,7 @@ fn lookup_name_wrapped(&env e, ast.ident i) -> option.t[tup(@env, def_wrap)] {
             }
 
             case (scope_block(?b)) {
-                alt (b.node.index.find(i)) {
-                    case (some[uint](?ix)) {
-                        auto x = found_decl_stmt(b.node.stmts.(ix));
-                        ret some(x);
-                    }
-                    case (_) { /* fall through */  }
-                }
+                ret check_block(i, b.node);
             }
 
             case (scope_arm(?a)) {