1 // An "interner" is a data structure that associates values with uint tags and
2 // allows bidirectional lookup; i.e. given a value, one can easily find the
3 // type, and vice versa.
4 import std::{vec, map, option};
5 import std::map::{hashmap, hashfn, eqfn};
6 import std::option::{none, some};
9 {map: hashmap<T, uint>,
14 fn mk<@T>(hasher: hashfn<T>, eqer: eqfn<T>) -> interner<T> {
15 let m = map::mk_hashmap::<T, uint>(hasher, eqer);
16 ret {map: m, mutable vect: [], hasher: hasher, eqer: eqer};
19 fn intern<@T>(itr: interner<T>, val: T) -> uint {
20 alt itr.map.find(val) {
21 some(idx) { ret idx; }
23 let new_idx = vec::len::<T>(itr.vect);
24 itr.map.insert(val, new_idx);
31 pure fn get<@T>(itr: interner<T>, idx: uint) -> T { ret itr.vect[idx]; }
33 pure fn len<T>(itr: interner<T>) -> uint { ret vec::len(itr.vect); }