Encapsulate RcStr
in syntax::util::interner
.
This commit is contained in:
parent
6d5f85996e
commit
f8a934e971
2 changed files with 25 additions and 62 deletions
|
@ -17,8 +17,7 @@ pub use self::Token::*;
|
||||||
use ast::{self, BinOpKind};
|
use ast::{self, BinOpKind};
|
||||||
use ext::mtwt;
|
use ext::mtwt;
|
||||||
use ptr::P;
|
use ptr::P;
|
||||||
use util::interner::{RcStr, StrInterner};
|
use util::interner::StrInterner;
|
||||||
use util::interner;
|
|
||||||
use tokenstream;
|
use tokenstream;
|
||||||
|
|
||||||
use serialize::{Decodable, Decoder, Encodable, Encoder};
|
use serialize::{Decodable, Decoder, Encodable, Encoder};
|
||||||
|
@ -397,7 +396,7 @@ macro_rules! declare_keywords {(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mk_fresh_ident_interner() -> IdentInterner {
|
fn mk_fresh_ident_interner() -> IdentInterner {
|
||||||
interner::StrInterner::prefill(&[$($string,)*])
|
StrInterner::prefill(&[$($string,)*])
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
@ -502,19 +501,19 @@ pub fn reset_ident_interner() {
|
||||||
/// somehow.
|
/// somehow.
|
||||||
#[derive(Clone, PartialEq, Hash, PartialOrd, Eq, Ord)]
|
#[derive(Clone, PartialEq, Hash, PartialOrd, Eq, Ord)]
|
||||||
pub struct InternedString {
|
pub struct InternedString {
|
||||||
string: RcStr,
|
string: Rc<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InternedString {
|
impl InternedString {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(string: &'static str) -> InternedString {
|
pub fn new(string: &'static str) -> InternedString {
|
||||||
InternedString {
|
InternedString {
|
||||||
string: RcStr::new(string),
|
string: Rc::new(string.to_owned()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn new_from_rc_str(string: RcStr) -> InternedString {
|
fn new_from_rc_str(string: Rc<String>) -> InternedString {
|
||||||
InternedString {
|
InternedString {
|
||||||
string: string,
|
string: string,
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,11 +16,8 @@ use ast::Name;
|
||||||
|
|
||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::cmp::Ordering;
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt;
|
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
use std::ops::Deref;
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub struct Interner<T> {
|
pub struct Interner<T> {
|
||||||
|
@ -91,56 +88,26 @@ impl<T: Eq + Hash + Clone + 'static> Interner<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Hash, PartialOrd)]
|
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
||||||
pub struct RcStr {
|
struct RcStr(Rc<String>);
|
||||||
string: Rc<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RcStr {
|
impl RcStr {
|
||||||
pub fn new(string: &str) -> RcStr {
|
fn new(string: &str) -> Self {
|
||||||
RcStr {
|
RcStr(Rc::new(string.to_owned()))
|
||||||
string: Rc::new(string.to_string()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Eq for RcStr {}
|
|
||||||
|
|
||||||
impl Ord for RcStr {
|
|
||||||
fn cmp(&self, other: &RcStr) -> Ordering {
|
|
||||||
self[..].cmp(&other[..])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Debug for RcStr {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
self[..].fmt(f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for RcStr {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
self[..].fmt(f)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Borrow<str> for RcStr {
|
impl Borrow<str> for RcStr {
|
||||||
fn borrow(&self) -> &str {
|
fn borrow(&self) -> &str {
|
||||||
&self.string[..]
|
&self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deref for RcStr {
|
|
||||||
type Target = str;
|
|
||||||
|
|
||||||
fn deref(&self) -> &str { &self.string[..] }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A StrInterner differs from Interner<String> in that it accepts
|
/// A StrInterner differs from Interner<String> in that it accepts
|
||||||
/// &str rather than RcStr, resulting in less allocation.
|
/// &str rather than RcStr, resulting in less allocation.
|
||||||
pub struct StrInterner {
|
pub struct StrInterner {
|
||||||
map: RefCell<HashMap<RcStr, Name>>,
|
map: RefCell<HashMap<RcStr, Name>>,
|
||||||
vect: RefCell<Vec<RcStr> >,
|
vect: RefCell<Vec<Rc<String>> >,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// When traits can extend traits, we should extend index<Name,T> to get []
|
/// When traits can extend traits, we should extend index<Name,T> to get []
|
||||||
|
@ -165,8 +132,8 @@ impl StrInterner {
|
||||||
}
|
}
|
||||||
|
|
||||||
let new_idx = Name(self.len() as u32);
|
let new_idx = Name(self.len() as u32);
|
||||||
let val = RcStr::new(val);
|
let val = Rc::new(val.to_owned());
|
||||||
map.insert(val.clone(), new_idx);
|
map.insert(RcStr(val.clone()), new_idx);
|
||||||
self.vect.borrow_mut().push(val);
|
self.vect.borrow_mut().push(val);
|
||||||
new_idx
|
new_idx
|
||||||
}
|
}
|
||||||
|
@ -174,7 +141,7 @@ impl StrInterner {
|
||||||
pub fn gensym(&self, val: &str) -> Name {
|
pub fn gensym(&self, val: &str) -> Name {
|
||||||
let new_idx = Name(self.len() as u32);
|
let new_idx = Name(self.len() as u32);
|
||||||
// leave out of .map to avoid colliding
|
// leave out of .map to avoid colliding
|
||||||
self.vect.borrow_mut().push(RcStr::new(val));
|
self.vect.borrow_mut().push(Rc::new(val.to_owned()));
|
||||||
new_idx
|
new_idx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,7 +164,7 @@ impl StrInterner {
|
||||||
new_idx
|
new_idx
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self, idx: Name) -> RcStr {
|
pub fn get(&self, idx: Name) -> Rc<String> {
|
||||||
(*self.vect.borrow())[idx.0 as usize].clone()
|
(*self.vect.borrow())[idx.0 as usize].clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,12 +172,8 @@ impl StrInterner {
|
||||||
self.vect.borrow().len()
|
self.vect.borrow().len()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find<Q: ?Sized>(&self, val: &Q) -> Option<Name>
|
pub fn find(&self, val: &str) -> Option<Name> {
|
||||||
where RcStr: Borrow<Q>, Q: Eq + Hash {
|
self.map.borrow().get(val).cloned()
|
||||||
match (*self.map.borrow()).get(val) {
|
|
||||||
Some(v) => Some(*v),
|
|
||||||
None => None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear(&self) {
|
pub fn clear(&self) {
|
||||||
|
@ -227,6 +190,7 @@ impl StrInterner {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use super::RcStr;
|
||||||
use ast::Name;
|
use ast::Name;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -294,13 +258,13 @@ mod tests {
|
||||||
assert_eq!(i.gensym("dog"), Name(4));
|
assert_eq!(i.gensym("dog"), Name(4));
|
||||||
// gensym tests again with gensym_copy:
|
// gensym tests again with gensym_copy:
|
||||||
assert_eq!(i.gensym_copy(Name(2)), Name(5));
|
assert_eq!(i.gensym_copy(Name(2)), Name(5));
|
||||||
assert_eq!(i.get(Name(5)), RcStr::new("zebra"));
|
assert_eq!(*i.get(Name(5)), "zebra");
|
||||||
assert_eq!(i.gensym_copy(Name(2)), Name(6));
|
assert_eq!(i.gensym_copy(Name(2)), Name(6));
|
||||||
assert_eq!(i.get(Name(6)), RcStr::new("zebra"));
|
assert_eq!(*i.get(Name(6)), "zebra");
|
||||||
assert_eq!(i.get(Name(0)), RcStr::new("dog"));
|
assert_eq!(*i.get(Name(0)), "dog");
|
||||||
assert_eq!(i.get(Name(1)), RcStr::new("cat"));
|
assert_eq!(*i.get(Name(1)), "cat");
|
||||||
assert_eq!(i.get(Name(2)), RcStr::new("zebra"));
|
assert_eq!(*i.get(Name(2)), "zebra");
|
||||||
assert_eq!(i.get(Name(3)), RcStr::new("zebra"));
|
assert_eq!(*i.get(Name(3)), "zebra");
|
||||||
assert_eq!(i.get(Name(4)), RcStr::new("dog"));
|
assert_eq!(*i.get(Name(4)), "dog");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue