2011-06-28 21:31:27 -05:00
|
|
|
import std::smallintmap;
|
|
|
|
import std::option;
|
2011-07-05 04:48:19 -05:00
|
|
|
import syntax::ast::*;
|
|
|
|
import syntax::visit;
|
2011-06-19 15:41:21 -05:00
|
|
|
import visit::vt;
|
|
|
|
|
|
|
|
tag ast_node {
|
|
|
|
node_item(@item);
|
|
|
|
node_obj_ctor(@item);
|
|
|
|
node_native_item(@native_item);
|
|
|
|
node_expr(@expr);
|
|
|
|
}
|
|
|
|
|
|
|
|
type map = std::map::hashmap[node_id, ast_node];
|
|
|
|
|
2011-07-27 07:19:39 -05:00
|
|
|
fn map_crate(c: &crate) -> map {
|
2011-06-28 21:31:27 -05:00
|
|
|
// FIXME: This is using an adapter to convert the smallintmap
|
|
|
|
// interface to the hashmap interface. It would be better to just
|
|
|
|
// convert everything to use the smallintmap.
|
2011-07-27 07:19:39 -05:00
|
|
|
let map = new_smallintmap_int_adapter[ast_node]();
|
2011-06-19 15:41:21 -05:00
|
|
|
|
2011-07-27 07:19:39 -05:00
|
|
|
let v_map =
|
|
|
|
@{visit_item: bind map_item(map, _, _, _),
|
|
|
|
visit_native_item: bind map_native_item(map, _, _, _),
|
|
|
|
visit_expr: bind map_expr(map, _, _, _)
|
|
|
|
with *visit::default_visitor[()]()};
|
2011-07-01 07:05:54 -05:00
|
|
|
visit::visit_crate(c, (), visit::mk_vt(v_map));
|
2011-06-19 15:41:21 -05:00
|
|
|
ret map;
|
|
|
|
}
|
|
|
|
|
2011-07-27 07:19:39 -05:00
|
|
|
fn map_item(map: &map, i: &@item, e: &(), v: &vt[()]) {
|
2011-06-19 15:41:21 -05:00
|
|
|
map.insert(i.id, node_item(i));
|
2011-07-27 07:19:39 -05:00
|
|
|
alt i.node {
|
|
|
|
item_obj(_, _, ctor_id) { map.insert(ctor_id, node_obj_ctor(i)); }
|
|
|
|
_ { }
|
2011-06-19 15:41:21 -05:00
|
|
|
}
|
|
|
|
visit::visit_item(i, e, v);
|
|
|
|
}
|
|
|
|
|
2011-07-27 07:19:39 -05:00
|
|
|
fn map_native_item(map: &map, i: &@native_item, e: &(), v: &vt[()]) {
|
2011-06-21 16:01:08 -05:00
|
|
|
map.insert(i.id, node_native_item(i));
|
2011-06-19 15:41:21 -05:00
|
|
|
visit::visit_native_item(i, e, v);
|
|
|
|
}
|
|
|
|
|
2011-07-27 07:19:39 -05:00
|
|
|
fn map_expr(map: &map, ex: &@expr, e: &(), v: &vt[()]) {
|
2011-06-21 15:16:40 -05:00
|
|
|
map.insert(ex.id, node_expr(ex));
|
2011-06-19 15:41:21 -05:00
|
|
|
visit::visit_expr(ex, e, v);
|
|
|
|
}
|
|
|
|
|
2011-07-29 20:38:22 -05:00
|
|
|
fn new_smallintmap_int_adapter[@V]() -> std::map::hashmap[int, V] {
|
2011-07-27 07:19:39 -05:00
|
|
|
let key_idx = fn (key: &int) -> uint { key as uint };
|
|
|
|
let idx_key = fn (idx: &uint) -> int { idx as int };
|
2011-06-28 21:31:27 -05:00
|
|
|
ret new_smallintmap_adapter(key_idx, idx_key);
|
|
|
|
}
|
|
|
|
|
|
|
|
// This creates an object with the hashmap interface backed
|
|
|
|
// by the smallintmap type, because I don't want to go through
|
|
|
|
// the entire codebase adapting all the callsites to the different
|
|
|
|
// interface.
|
|
|
|
// FIXME: hashmap and smallintmap should support the same interface.
|
2011-07-29 20:38:22 -05:00
|
|
|
fn new_smallintmap_adapter[@K,
|
|
|
|
@V](key_idx: fn(&K) -> uint ,
|
|
|
|
idx_key: fn(&uint) -> K ) ->
|
2011-07-27 07:19:39 -05:00
|
|
|
std::map::hashmap[K, V] {
|
2011-06-28 21:31:27 -05:00
|
|
|
|
2011-07-29 20:38:22 -05:00
|
|
|
obj adapter[@K,
|
|
|
|
@V](map: smallintmap::smallintmap[V],
|
|
|
|
key_idx: fn(&K) -> uint ,
|
|
|
|
idx_key: fn(&uint) -> K ) {
|
2011-06-28 21:31:27 -05:00
|
|
|
|
|
|
|
fn size() -> uint { fail }
|
|
|
|
|
2011-07-27 07:19:39 -05:00
|
|
|
fn insert(key: &K, value: &V) -> bool {
|
|
|
|
let exists = smallintmap::contains_key(map, key_idx(key));
|
2011-06-28 21:31:27 -05:00
|
|
|
smallintmap::insert(map, key_idx(key), value);
|
|
|
|
ret !exists;
|
|
|
|
}
|
|
|
|
|
2011-07-27 07:19:39 -05:00
|
|
|
fn contains_key(key: &K) -> bool {
|
2011-06-28 21:31:27 -05:00
|
|
|
ret smallintmap::contains_key(map, key_idx(key));
|
|
|
|
}
|
|
|
|
|
2011-07-27 07:19:39 -05:00
|
|
|
fn get(key: &K) -> V { ret smallintmap::get(map, key_idx(key)); }
|
2011-06-28 21:31:27 -05:00
|
|
|
|
2011-07-27 07:19:39 -05:00
|
|
|
fn find(key: &K) -> option::t[V] {
|
2011-06-28 21:31:27 -05:00
|
|
|
ret smallintmap::find(map, key_idx(key));
|
|
|
|
}
|
|
|
|
|
2011-07-27 07:19:39 -05:00
|
|
|
fn remove(key: &K) -> option::t[V] { fail }
|
2011-06-28 21:31:27 -05:00
|
|
|
|
|
|
|
fn rehash() { fail }
|
|
|
|
|
2011-07-27 07:19:39 -05:00
|
|
|
iter items() -> @{key: K, val: V} {
|
|
|
|
let idx = 0u;
|
|
|
|
for item: option::t[V] in map.v {
|
|
|
|
alt item {
|
|
|
|
option::some(elt) {
|
|
|
|
let value = elt;
|
|
|
|
let key = idx_key(idx);
|
|
|
|
put @{key: key, val: value};
|
|
|
|
}
|
|
|
|
option::none. { }
|
2011-06-28 21:31:27 -05:00
|
|
|
}
|
|
|
|
idx += 1u;
|
|
|
|
}
|
|
|
|
}
|
2011-07-21 20:14:39 -05:00
|
|
|
iter keys() -> K {
|
2011-07-27 07:19:39 -05:00
|
|
|
for each p: @{key: K, val: V} in self.items() { put p.key; }
|
2011-07-21 20:14:39 -05:00
|
|
|
}
|
2011-06-28 21:31:27 -05:00
|
|
|
}
|
|
|
|
|
2011-07-27 07:19:39 -05:00
|
|
|
let map = smallintmap::mk[V]();
|
2011-06-28 21:31:27 -05:00
|
|
|
ret adapter(map, key_idx, idx_key);
|
|
|
|
}
|
|
|
|
|
2011-06-19 15:41:21 -05:00
|
|
|
// 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:
|