]> git.lizzy.rs Git - rust.git/blob - src/comp/syntax/util/interner.rs
ce1124d68aa95e47220d68248316e7ded40a994c
[rust.git] / src / comp / syntax / util / interner.rs
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};
7
8 type interner<T> =
9     {map: hashmap<T, uint>,
10      mutable vect: [T],
11      hasher: hashfn<T>,
12      eqer: eqfn<T>};
13
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};
17 }
18
19 fn intern<@T>(itr: interner<T>, val: T) -> uint {
20     alt itr.map.find(val) {
21       some(idx) { ret idx; }
22       none. {
23         let new_idx = vec::len::<T>(itr.vect);
24         itr.map.insert(val, new_idx);
25         itr.vect += [val];
26         ret new_idx;
27       }
28     }
29 }
30
31 fn get<@T>(itr: interner<T>, idx: uint) -> T { ret itr.vect[idx]; }
32
33 fn len<T>(itr: interner<T>) -> uint { ret vec::len(itr.vect); }
34