@@ -17,122 +17,45 @@ use ast::Name;
1717use std:: borrow:: Borrow ;
1818use std:: cell:: RefCell ;
1919use std:: collections:: HashMap ;
20- use std:: hash:: Hash ;
2120use std:: rc:: Rc ;
2221
23- pub struct Interner < T > {
24- map : RefCell < HashMap < T , Name > > ,
25- vect : RefCell < Vec < T > > ,
26- }
27-
28- // when traits can extend traits, we should extend index<Name,T> to get []
29- impl < T : Eq + Hash + Clone + ' static > Interner < T > {
30- pub fn new ( ) -> Interner < T > {
31- Interner {
32- map : RefCell :: new ( HashMap :: new ( ) ) ,
33- vect : RefCell :: new ( Vec :: new ( ) ) ,
34- }
35- }
36-
37- pub fn prefill ( init : & [ T ] ) -> Interner < T > {
38- let rv = Interner :: new ( ) ;
39- for v in init {
40- rv. intern ( ( * v) . clone ( ) ) ;
41- }
42- rv
43- }
44-
45- pub fn intern ( & self , val : T ) -> Name {
46- let mut map = self . map . borrow_mut ( ) ;
47- if let Some ( & idx) = ( * map) . get ( & val) {
48- return idx;
49- }
50-
51- let mut vect = self . vect . borrow_mut ( ) ;
52- let new_idx = Name ( ( * vect) . len ( ) as u32 ) ;
53- ( * map) . insert ( val. clone ( ) , new_idx) ;
54- ( * vect) . push ( val) ;
55- new_idx
56- }
57-
58- pub fn gensym ( & self , val : T ) -> Name {
59- let mut vect = self . vect . borrow_mut ( ) ;
60- let new_idx = Name ( ( * vect) . len ( ) as u32 ) ;
61- // leave out of .map to avoid colliding
62- ( * vect) . push ( val) ;
63- new_idx
64- }
65-
66- pub fn get ( & self , idx : Name ) -> T {
67- let vect = self . vect . borrow ( ) ;
68- ( * vect) [ idx. 0 as usize ] . clone ( )
69- }
70-
71- pub fn len ( & self ) -> usize {
72- let vect = self . vect . borrow ( ) ;
73- ( * vect) . len ( )
74- }
75-
76- pub fn find < Q : ?Sized > ( & self , val : & Q ) -> Option < Name >
77- where T : Borrow < Q > , Q : Eq + Hash {
78- let map = self . map . borrow ( ) ;
79- match ( * map) . get ( val) {
80- Some ( v) => Some ( * v) ,
81- None => None ,
82- }
83- }
84-
85- pub fn clear ( & self ) {
86- * self . map . borrow_mut ( ) = HashMap :: new ( ) ;
87- * self . vect . borrow_mut ( ) = Vec :: new ( ) ;
88- }
89- }
90-
91- #[ derive( Clone , PartialEq , Eq , Hash , Debug ) ]
22+ #[ derive( PartialEq , Eq , Hash ) ]
9223struct RcStr ( Rc < String > ) ;
9324
94- impl RcStr {
95- fn new ( string : & str ) -> Self {
96- RcStr ( Rc :: new ( string. to_owned ( ) ) )
97- }
98- }
99-
10025impl Borrow < str > for RcStr {
10126 fn borrow ( & self ) -> & str {
10227 & self . 0
10328 }
10429}
10530
106- /// A StrInterner differs from Interner<String> in that it accepts
107- /// &str rather than RcStr, resulting in less allocation.
108- pub struct StrInterner {
31+ pub struct Interner {
10932 map : RefCell < HashMap < RcStr , Name > > ,
11033 vect : RefCell < Vec < Rc < String > > > ,
11134}
11235
11336/// When traits can extend traits, we should extend index<Name,T> to get []
114- impl StrInterner {
115- pub fn new ( ) -> StrInterner {
116- StrInterner {
37+ impl Interner {
38+ pub fn new ( ) -> Self {
39+ Interner {
11740 map : RefCell :: new ( HashMap :: new ( ) ) ,
11841 vect : RefCell :: new ( Vec :: new ( ) ) ,
11942 }
12043 }
12144
122- pub fn prefill ( init : & [ & str ] ) -> StrInterner {
123- let rv = StrInterner :: new ( ) ;
45+ pub fn prefill ( init : & [ & str ] ) -> Self {
46+ let rv = Interner :: new ( ) ;
12447 for & v in init { rv. intern ( v) ; }
12548 rv
12649 }
12750
128- pub fn intern ( & self , val : & str ) -> Name {
51+ pub fn intern < T : Borrow < str > + Into < String > > ( & self , val : T ) -> Name {
12952 let mut map = self . map . borrow_mut ( ) ;
130- if let Some ( & idx) = map. get ( val) {
53+ if let Some ( & idx) = map. get ( val. borrow ( ) ) {
13154 return idx;
13255 }
13356
13457 let new_idx = Name ( self . len ( ) as u32 ) ;
135- let val = Rc :: new ( val. to_owned ( ) ) ;
58+ let val = Rc :: new ( val. into ( ) ) ;
13659 map. insert ( RcStr ( val. clone ( ) ) , new_idx) ;
13760 self . vect . borrow_mut ( ) . push ( val) ;
13861 new_idx
@@ -181,7 +104,7 @@ impl StrInterner {
181104 * self . vect . borrow_mut ( ) = Vec :: new ( ) ;
182105 }
183106
184- pub fn reset ( & self , other : StrInterner ) {
107+ pub fn reset ( & self , other : Interner ) {
185108 * self . map . borrow_mut ( ) = other. map . into_inner ( ) ;
186109 * self . vect . borrow_mut ( ) = other. vect . into_inner ( ) ;
187110 }
@@ -190,57 +113,11 @@ impl StrInterner {
190113#[ cfg( test) ]
191114mod tests {
192115 use super :: * ;
193- use super :: RcStr ;
194116 use ast:: Name ;
195117
196118 #[ test]
197- #[ should_panic]
198- fn i1 ( ) {
199- let i : Interner < RcStr > = Interner :: new ( ) ;
200- i. get ( Name ( 13 ) ) ;
201- }
202-
203- #[ test]
204- fn interner_tests ( ) {
205- let i : Interner < RcStr > = Interner :: new ( ) ;
206- // first one is zero:
207- assert_eq ! ( i. intern( RcStr :: new( "dog" ) ) , Name ( 0 ) ) ;
208- // re-use gets the same entry:
209- assert_eq ! ( i. intern( RcStr :: new( "dog" ) ) , Name ( 0 ) ) ;
210- // different string gets a different #:
211- assert_eq ! ( i. intern( RcStr :: new( "cat" ) ) , Name ( 1 ) ) ;
212- assert_eq ! ( i. intern( RcStr :: new( "cat" ) ) , Name ( 1 ) ) ;
213- // dog is still at zero
214- assert_eq ! ( i. intern( RcStr :: new( "dog" ) ) , Name ( 0 ) ) ;
215- // gensym gets 3
216- assert_eq ! ( i. gensym( RcStr :: new( "zebra" ) ) , Name ( 2 ) ) ;
217- // gensym of same string gets new number :
218- assert_eq ! ( i. gensym ( RcStr :: new( "zebra" ) ) , Name ( 3 ) ) ;
219- // gensym of *existing* string gets new number:
220- assert_eq ! ( i. gensym( RcStr :: new( "dog" ) ) , Name ( 4 ) ) ;
221- assert_eq ! ( i. get( Name ( 0 ) ) , RcStr :: new( "dog" ) ) ;
222- assert_eq ! ( i. get( Name ( 1 ) ) , RcStr :: new( "cat" ) ) ;
223- assert_eq ! ( i. get( Name ( 2 ) ) , RcStr :: new( "zebra" ) ) ;
224- assert_eq ! ( i. get( Name ( 3 ) ) , RcStr :: new( "zebra" ) ) ;
225- assert_eq ! ( i. get( Name ( 4 ) ) , RcStr :: new( "dog" ) ) ;
226- }
227-
228- #[ test]
229- fn i3 ( ) {
230- let i : Interner < RcStr > = Interner :: prefill ( & [
231- RcStr :: new ( "Alan" ) ,
232- RcStr :: new ( "Bob" ) ,
233- RcStr :: new ( "Carol" )
234- ] ) ;
235- assert_eq ! ( i. get( Name ( 0 ) ) , RcStr :: new( "Alan" ) ) ;
236- assert_eq ! ( i. get( Name ( 1 ) ) , RcStr :: new( "Bob" ) ) ;
237- assert_eq ! ( i. get( Name ( 2 ) ) , RcStr :: new( "Carol" ) ) ;
238- assert_eq ! ( i. intern( RcStr :: new( "Bob" ) ) , Name ( 1 ) ) ;
239- }
240-
241- #[ test]
242- fn string_interner_tests ( ) {
243- let i : StrInterner = StrInterner :: new ( ) ;
119+ fn interner_tests ( ) {
120+ let i : Interner = Interner :: new ( ) ;
244121 // first one is zero:
245122 assert_eq ! ( i. intern( "dog" ) , Name ( 0 ) ) ;
246123 // re-use gets the same entry:
0 commit comments