rustc: Factor out the code that interns types into an "interner" data structure
This commit is contained in:
parent
3760bfab87
commit
32b8dcb97c
3 changed files with 61 additions and 36 deletions
|
|
@ -33,6 +33,8 @@ import util::common::new_def_hash;
|
|||
import util::common::span;
|
||||
import util::typestate_ann::ts_ann;
|
||||
|
||||
import util::interner;
|
||||
|
||||
// Data types
|
||||
|
||||
tag mode {
|
||||
|
|
@ -159,19 +161,14 @@ const uint idx_native = 18u;
|
|||
const uint idx_type = 19u;
|
||||
const uint idx_first_others = 20u;
|
||||
|
||||
type type_store = rec(mutable vec[raw_t] others,
|
||||
hashmap[raw_t,uint] other_structural);
|
||||
type type_store = interner::interner[raw_t];
|
||||
|
||||
type ty_param_substs_opt_and_ty = tup(option::t[vec[ty::t]], ty::t);
|
||||
type node_type_table =
|
||||
@mutable vec[mutable option::t[ty::ty_param_substs_opt_and_ty]];
|
||||
|
||||
fn mk_type_store() -> @type_store {
|
||||
let vec[raw_t] others = vec();
|
||||
let hashmap[raw_t,uint] ost =
|
||||
map::mk_hashmap[raw_t,uint](hash_raw_ty, eq_raw_ty);
|
||||
|
||||
auto ts = @rec(mutable others=others, other_structural=ost);
|
||||
auto ts = @interner::mk_interner[raw_t](hash_raw_ty, eq_raw_ty);
|
||||
|
||||
intern(ts, ty_nil, none[str]);
|
||||
intern(ts, ty_bool, none[str]);
|
||||
|
|
@ -194,7 +191,7 @@ fn mk_type_store() -> @type_store {
|
|||
intern(ts, ty_native, none[str]);
|
||||
intern(ts, ty_type, none[str]);
|
||||
|
||||
assert _vec::len(ts.others) == idx_first_others;
|
||||
assert _vec::len(ts.vect) == idx_first_others;
|
||||
|
||||
ret ts;
|
||||
}
|
||||
|
|
@ -240,7 +237,7 @@ fn mk_raw_ty(&@type_store ts, &sty st, &option::t[str] cname) -> raw_t {
|
|||
&mutable bool has_vars,
|
||||
&mutable bool has_locals,
|
||||
&t tt) {
|
||||
auto rt = ts.others.(tt);
|
||||
auto rt = interner::get[raw_t](*ts, tt);
|
||||
has_params = has_params || rt.has_params;
|
||||
has_bound_params = has_bound_params || rt.has_bound_params;
|
||||
has_vars = has_vars || rt.has_vars;
|
||||
|
|
@ -355,32 +352,13 @@ fn mk_raw_ty(&@type_store ts, &sty st, &option::t[str] cname) -> raw_t {
|
|||
has_locals = has_locals);
|
||||
}
|
||||
|
||||
fn intern_raw_ty(&@type_store ts, &raw_t rt) {
|
||||
auto type_num = _vec::len[raw_t](ts.others);
|
||||
ts.others += vec(rt);
|
||||
ts.other_structural.insert(rt, type_num);
|
||||
}
|
||||
|
||||
fn intern(&@type_store ts, &sty st, &option::t[str] cname) {
|
||||
intern_raw_ty(ts, mk_raw_ty(ts, st, cname));
|
||||
interner::intern[raw_t](*ts, mk_raw_ty(ts, st, cname));
|
||||
}
|
||||
|
||||
fn gen_ty_full(&ctxt cx, &sty st, &option::t[str] cname) -> t {
|
||||
auto raw_type = mk_raw_ty(cx.ts, st, cname);
|
||||
|
||||
// Is it interned?
|
||||
alt (cx.ts.other_structural.find(raw_type)) {
|
||||
case (some[t](?typ)) {
|
||||
ret typ;
|
||||
}
|
||||
case (none[t]) {
|
||||
// Nope: Insert it and return.
|
||||
auto type_num = _vec::len[raw_t](cx.ts.others);
|
||||
intern_raw_ty(cx.ts, raw_type);
|
||||
// log_err "added: " + ty_to_str(tystore, raw_type);
|
||||
ret type_num;
|
||||
}
|
||||
}
|
||||
ret interner::intern[raw_t](*cx.ts, raw_type);
|
||||
}
|
||||
|
||||
// These are private constructors to this module. External users should always
|
||||
|
|
@ -484,10 +462,14 @@ fn mk_native(&ctxt cx) -> t { ret idx_native; }
|
|||
|
||||
|
||||
// Returns the one-level-deep type structure of the given type.
|
||||
fn struct(&ctxt cx, &t typ) -> sty { ret cx.ts.others.(typ).struct; }
|
||||
fn struct(&ctxt cx, &t typ) -> sty {
|
||||
ret interner::get[raw_t](*cx.ts, typ).struct;
|
||||
}
|
||||
|
||||
// Returns the canonical name of the given type.
|
||||
fn cname(&ctxt cx, &t typ) -> option::t[str] { ret cx.ts.others.(typ).cname; }
|
||||
fn cname(&ctxt cx, &t typ) -> option::t[str] {
|
||||
ret interner::get[raw_t](*cx.ts, typ).cname;
|
||||
}
|
||||
|
||||
|
||||
// Stringification
|
||||
|
|
@ -1525,19 +1507,19 @@ fn count_ty_params(ctxt cx, t ty) -> uint {
|
|||
}
|
||||
|
||||
fn type_contains_vars(&ctxt cx, &t typ) -> bool {
|
||||
ret cx.ts.others.(typ).has_vars;
|
||||
ret interner::get[raw_t](*cx.ts, typ).has_vars;
|
||||
}
|
||||
|
||||
fn type_contains_locals(&ctxt cx, &t typ) -> bool {
|
||||
ret cx.ts.others.(typ).has_locals;
|
||||
ret interner::get[raw_t](*cx.ts, typ).has_locals;
|
||||
}
|
||||
|
||||
fn type_contains_params(&ctxt cx, &t typ) -> bool {
|
||||
ret cx.ts.others.(typ).has_params;
|
||||
ret interner::get[raw_t](*cx.ts, typ).has_params;
|
||||
}
|
||||
|
||||
fn type_contains_bound_params(&ctxt cx, &t typ) -> bool {
|
||||
ret cx.ts.others.(typ).has_bound_params;
|
||||
ret interner::get[raw_t](*cx.ts, typ).has_bound_params;
|
||||
}
|
||||
|
||||
// Type accessors for substructures of types
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ mod driver {
|
|||
|
||||
mod util {
|
||||
mod common;
|
||||
mod interner;
|
||||
mod typestate_ann;
|
||||
}
|
||||
|
||||
|
|
|
|||
42
src/comp/util/interner.rs
Normal file
42
src/comp/util/interner.rs
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
// An "interner" is a data structure that associates values with uint tags and
|
||||
// allows bidirectional lookup; i.e. given a value, one can easily find the
|
||||
// type, and vice versa.
|
||||
|
||||
import std::_vec;
|
||||
import std::map;
|
||||
import std::map::hashmap;
|
||||
import std::map::hashfn;
|
||||
import std::map::eqfn;
|
||||
import std::option;
|
||||
import std::option::none;
|
||||
import std::option::some;
|
||||
|
||||
type interner[T] = rec(
|
||||
hashmap[T,uint] map,
|
||||
mutable vec[T] vect,
|
||||
hashfn[T] hasher,
|
||||
eqfn[T] eqer
|
||||
);
|
||||
|
||||
fn mk_interner[T](hashfn[T] hasher, eqfn[T] eqer) -> interner[T] {
|
||||
auto m = map::mk_hashmap[T,uint](hasher, eqer);
|
||||
let vec[T] vect = vec();
|
||||
ret rec(map=m, mutable vect=vect, hasher=hasher, eqer=eqer);
|
||||
}
|
||||
|
||||
fn intern[T](&interner[T] itr, &T val) -> uint {
|
||||
alt (itr.map.find(val)) {
|
||||
case (some[uint](?idx)) { ret idx; }
|
||||
case (none[uint]) {
|
||||
auto new_idx = _vec::len[T](itr.vect);
|
||||
itr.map.insert(val, new_idx);
|
||||
itr.vect += vec(val);
|
||||
ret new_idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get[T](&interner[T] itr, uint idx) -> T {
|
||||
ret itr.vect.(idx);
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue