From 9da641bd8c186412813dca899cc8a0eb509122d9 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Sat, 9 Feb 2013 13:22:21 -0800 Subject: [PATCH] libsyntax: convert interner into a modern struct --- src/libsyntax/parse/token.rs | 4 +- src/libsyntax/util/interner.rs | 80 ++++++++++++++++------------------ 2 files changed, 39 insertions(+), 45 deletions(-) diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index bdd26fc00a7d..f145e433fa7c 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -429,7 +429,7 @@ pub fn mk_ident_interner() -> @ident_interner { ]; let rv = @ident_interner { - interner: interner::mk_prefill(init_vec) + interner: interner::Interner::prefill(init_vec) }; task::local_data::local_data_set(interner_key!(), @rv); @@ -443,7 +443,7 @@ pub fn mk_ident_interner() -> @ident_interner { /* for when we don't care about the contents; doesn't interact with TLD or serialization */ pub fn mk_fake_ident_interner() -> @ident_interner { - @ident_interner { interner: interner::mk::<@~str>() } + @ident_interner { interner: interner::Interner::new() } } /** diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs index 657e6ee59fa4..dcb3261169be 100644 --- a/src/libsyntax/util/interner.rs +++ b/src/libsyntax/util/interner.rs @@ -14,72 +14,66 @@ use core::prelude::*; -use core::dvec::DVec; -use std::oldmap::HashMap; -use std::oldmap; +use hashmap::linear::LinearMap; +use dvec::DVec; -pub type hash_interner = {map: HashMap, vect: DVec}; - -pub fn mk() -> Interner { - let m = oldmap::HashMap::(); - let hi: hash_interner = - {map: m, vect: DVec()}; - ((hi) as Interner::) +pub struct Interner { + priv mut map: LinearMap, + priv vect: DVec, } -pub fn mk_prefill(init: &[T]) -> Interner { - let rv = mk(); - for init.each() |v| { rv.intern(*v); } - return rv; -} - - -/* when traits can extend traits, we should extend index to get [] */ -pub trait Interner { - fn intern(T) -> uint; - fn gensym(T) -> uint; - pure fn get(uint) -> T; - fn len() -> uint; -} - -pub impl Interner for hash_interner { - fn intern(val: T) -> uint { - match self.map.find(&val) { - Some(idx) => return idx, - None => { - let new_idx = self.vect.len(); - self.map.insert(val, new_idx); - self.vect.push(val); - return new_idx; - } +// when traits can extend traits, we should extend index to get [] +pub impl Interner { + static fn new() -> Interner { + Interner { + map: LinearMap::new(), + vect: DVec(), } } - fn gensym(val: T) -> uint { + + static fn prefill(init: &[T]) -> Interner { + let rv = Interner::new(); + for init.each() |v| { rv.intern(*v); } + rv + } + + fn intern(&self, val: T) -> uint { + match self.map.find(&val) { + Some(&idx) => return idx, + None => (), + } + + let new_idx = self.vect.len(); + self.map.insert(val, new_idx); + self.vect.push(val); + new_idx + } + + fn gensym(&self, val: T) -> uint { let new_idx = self.vect.len(); // leave out of .map to avoid colliding self.vect.push(val); - return new_idx; + new_idx } // this isn't "pure" in the traditional sense, because it can go from // failing to returning a value as items are interned. But for typestate, // where we first check a pred and then rely on it, ceasing to fail is ok. - pure fn get(idx: uint) -> T { self.vect.get_elt(idx) } + pure fn get(&self, idx: uint) -> T { self.vect.get_elt(idx) } - fn len() -> uint { return self.vect.len(); } + fn len(&self) -> uint { self.vect.len() } } - #[test] #[should_fail] pub fn i1 () { - let i : Interner<@~str> = mk(); + let i : Interner<@~str> = Interner::new(); i.get(13); } #[test] pub fn i2 () { - let i : Interner<@~str> = mk(); + let i : Interner<@~str> = Interner::new(); // first one is zero: assert i.intern (@~"dog") == 0; // re-use gets the same entry: @@ -104,7 +98,7 @@ pub fn i2 () { #[test] pub fn i3 () { - let i : Interner<@~str> = mk_prefill([@~"Alan",@~"Bob",@~"Carol"]); + let i : Interner<@~str> = Interner::prefill([@~"Alan",@~"Bob",@~"Carol"]); assert i.get(0) == @~"Alan"; assert i.get(1) == @~"Bob"; assert i.get(2) == @~"Carol";