1515use ast:: Name ;
1616
1717use std:: borrow:: Borrow ;
18- use std:: cell:: RefCell ;
1918use std:: collections:: HashMap ;
2019use std:: rc:: Rc ;
2120
@@ -28,85 +27,60 @@ impl Borrow<str> for RcStr {
2827 }
2928}
3029
30+ #[ derive( Default ) ]
3131pub struct Interner {
32- map : RefCell < HashMap < RcStr , Name > > ,
33- vect : RefCell < Vec < Rc < String > > > ,
32+ names : HashMap < RcStr , Name > ,
33+ strings : Vec < Rc < String > > ,
3434}
3535
3636/// When traits can extend traits, we should extend index<Name,T> to get []
3737impl Interner {
3838 pub fn new ( ) -> Self {
39- Interner {
40- map : RefCell :: new ( HashMap :: new ( ) ) ,
41- vect : RefCell :: new ( Vec :: new ( ) ) ,
42- }
39+ Interner :: default ( )
4340 }
4441
4542 pub fn prefill ( init : & [ & str ] ) -> Self {
46- let rv = Interner :: new ( ) ;
47- for & v in init { rv. intern ( v) ; }
48- rv
49- }
50-
51- pub fn intern < T : Borrow < str > + Into < String > > ( & self , val : T ) -> Name {
52- let mut map = self . map . borrow_mut ( ) ;
53- if let Some ( & idx) = map. get ( val. borrow ( ) ) {
54- return idx;
43+ let mut this = Interner :: new ( ) ;
44+ for & string in init {
45+ this. intern ( string) ;
5546 }
56-
57- let new_idx = Name ( self . len ( ) as u32 ) ;
58- let val = Rc :: new ( val. into ( ) ) ;
59- map. insert ( RcStr ( val. clone ( ) ) , new_idx) ;
60- self . vect . borrow_mut ( ) . push ( val) ;
61- new_idx
47+ this
6248 }
6349
64- pub fn gensym ( & self , val : & str ) -> Name {
65- let new_idx = Name ( self . len ( ) as u32 ) ;
66- // leave out of .map to avoid colliding
67- self . vect . borrow_mut ( ) . push ( Rc :: new ( val. to_owned ( ) ) ) ;
68- new_idx
69- }
70-
71- // I want these gensyms to share name pointers
72- // with existing entries. This would be automatic,
73- // except that the existing gensym creates its
74- // own managed ptr using to_managed. I think that
75- // adding this utility function is the most
76- // lightweight way to get what I want, though not
77- // necessarily the cleanest.
78-
79- /// Create a gensym with the same name as an existing
80- /// entry.
81- pub fn gensym_copy ( & self , idx : Name ) -> Name {
82- let new_idx = Name ( self . len ( ) as u32 ) ;
83- // leave out of map to avoid colliding
84- let mut vect = self . vect . borrow_mut ( ) ;
85- let existing = ( * vect) [ idx. 0 as usize ] . clone ( ) ;
86- vect. push ( existing) ;
87- new_idx
88- }
50+ pub fn intern < T : Borrow < str > + Into < String > > ( & mut self , string : T ) -> Name {
51+ if let Some ( & name) = self . names . get ( string. borrow ( ) ) {
52+ return name;
53+ }
8954
90- pub fn get ( & self , idx : Name ) -> Rc < String > {
91- ( * self . vect . borrow ( ) ) [ idx. 0 as usize ] . clone ( )
55+ let name = Name ( self . strings . len ( ) as u32 ) ;
56+ let string = Rc :: new ( string. into ( ) ) ;
57+ self . strings . push ( string. clone ( ) ) ;
58+ self . names . insert ( RcStr ( string) , name) ;
59+ name
9260 }
9361
94- pub fn len ( & self ) -> usize {
95- self . vect . borrow ( ) . len ( )
62+ pub fn gensym ( & mut self , string : & str ) -> Name {
63+ let gensym = Name ( self . strings . len ( ) as u32 ) ;
64+ // leave out of `names` to avoid colliding
65+ self . strings . push ( Rc :: new ( string. to_owned ( ) ) ) ;
66+ gensym
9667 }
9768
98- pub fn find ( & self , val : & str ) -> Option < Name > {
99- self . map . borrow ( ) . get ( val) . cloned ( )
69+ /// Create a gensym with the same name as an existing entry.
70+ pub fn gensym_copy ( & mut self , name : Name ) -> Name {
71+ let gensym = Name ( self . strings . len ( ) as u32 ) ;
72+ // leave out of `names` to avoid colliding
73+ let string = self . strings [ name. 0 as usize ] . clone ( ) ;
74+ self . strings . push ( string) ;
75+ gensym
10076 }
10177
102- pub fn clear ( & self ) {
103- * self . map . borrow_mut ( ) = HashMap :: new ( ) ;
104- * self . vect . borrow_mut ( ) = Vec :: new ( ) ;
78+ pub fn get ( & self , name : Name ) -> Rc < String > {
79+ self . strings [ name. 0 as usize ] . clone ( )
10580 }
10681
107- pub fn reset ( & self , other : Interner ) {
108- * self . map . borrow_mut ( ) = other. map . into_inner ( ) ;
109- * self . vect . borrow_mut ( ) = other. vect . into_inner ( ) ;
82+ pub fn find ( & self , string : & str ) -> Option < Name > {
83+ self . names . get ( string) . cloned ( )
11084 }
11185}
11286
@@ -117,7 +91,7 @@ mod tests {
11791
11892 #[ test]
11993 fn interner_tests ( ) {
120- let i : Interner = Interner :: new ( ) ;
94+ let mut i : Interner = Interner :: new ( ) ;
12195 // first one is zero:
12296 assert_eq ! ( i. intern( "dog" ) , Name ( 0 ) ) ;
12397 // re-use gets the same entry:
0 commit comments