about summary refs log tree commit diff
path: root/src/libsyntax/util
diff options
context:
space:
mode:
authorErick Tryzelaar <erick.tryzelaar@gmail.com>2013-02-09 13:22:21 -0800
committerErick Tryzelaar <erick.tryzelaar@gmail.com>2013-02-19 10:02:50 -0800
commit9da641bd8c186412813dca899cc8a0eb509122d9 (patch)
tree60c312dd358e4fd048afd3a80ae8d60f6a641162 /src/libsyntax/util
parent2ec958db5ae37f193d4d632635818241b134a617 (diff)
downloadrust-9da641bd8c186412813dca899cc8a0eb509122d9.tar.gz
rust-9da641bd8c186412813dca899cc8a0eb509122d9.zip
libsyntax: convert interner into a modern struct
Diffstat (limited to 'src/libsyntax/util')
-rw-r--r--src/libsyntax/util/interner.rs74
1 files changed, 34 insertions, 40 deletions
diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs
index 657e6ee59fa..dcb3261169b 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<T> = {map: HashMap<T, uint>, vect: DVec<T>};
-
-pub fn mk<T:Eq IterBytes Hash Const Copy>() -> Interner<T> {
-    let m = oldmap::HashMap::<T, uint>();
-    let hi: hash_interner<T> =
-        {map: m, vect: DVec()};
-    ((hi) as Interner::<T>)
-}
-
-pub fn mk_prefill<T:Eq IterBytes Hash Const Copy>(init: &[T]) -> Interner<T> {
-    let rv = mk();
-    for init.each() |v| { rv.intern(*v); }
-    return rv;
+pub struct Interner<T> {
+    priv mut map: LinearMap<T, uint>,
+    priv vect: DVec<T>,
 }
 
+// when traits can extend traits, we should extend index<uint,T> to get []
+pub impl<T: Eq IterBytes Hash Const Copy> Interner<T> {
+    static fn new() -> Interner<T> {
+        Interner {
+            map: LinearMap::new(),
+            vect: DVec(),
+        }
+    }
 
-/* when traits can extend traits, we should extend index<uint,T> to get [] */
-pub trait Interner<T:Eq IterBytes Hash Const Copy> {
-    fn intern(T) -> uint;
-    fn gensym(T) -> uint;
-    pure fn get(uint) -> T;
-    fn len() -> uint;
-}
+    static fn prefill(init: &[T]) -> Interner<T> {
+        let rv = Interner::new();
+        for init.each() |v| { rv.intern(*v); }
+        rv
+    }
 
-pub impl<T:Eq IterBytes Hash Const Copy> Interner<T> for hash_interner<T> {
-    fn intern(val: T) -> uint {
+    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);
-            return new_idx;
-          }
+            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(val: T) -> uint {
+
+    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";