ast: make Name its own type

This commit is contained in:
Corey Richardson 2014-07-06 01:17:59 -07:00
parent f512779554
commit 092c5078be
11 changed files with 149 additions and 106 deletions

View file

@ -1114,7 +1114,7 @@ impl UnusedMut {
match mode { match mode {
ast::BindByValue(ast::MutMutable) => { ast::BindByValue(ast::MutMutable) => {
if !token::get_ident(ident).get().starts_with("_") { if !token::get_ident(ident).get().starts_with("_") {
mutables.insert_or_update_with(ident.name as uint, mutables.insert_or_update_with(ident.name.uint(),
vec!(id), |_, old| { old.push(id); }); vec!(id), |_, old| { old.push(id); });
} }
} }

View file

@ -323,7 +323,7 @@ fn item_name(intr: &IdentInterner, item: ebml::Doc) -> ast::Ident {
let string = name.as_str_slice(); let string = name.as_str_slice();
match intr.find_equiv(&string) { match intr.find_equiv(&string) {
None => token::str_to_ident(string), None => token::str_to_ident(string),
Some(val) => ast::Ident::new(val as ast::Name), Some(val) => ast::Ident::new(val),
} }
} }

View file

@ -52,10 +52,7 @@ impl Ident {
pub fn new(name: Name) -> Ident { Ident {name: name, ctxt: EMPTY_CTXT}} pub fn new(name: Name) -> Ident { Ident {name: name, ctxt: EMPTY_CTXT}}
pub fn as_str<'a>(&'a self) -> &'a str { pub fn as_str<'a>(&'a self) -> &'a str {
unsafe { self.name.as_str()
// FIXME #12938: can't use copy_lifetime since &str isn't a &T
::std::mem::transmute(token::get_ident(*self).get())
}
} }
} }
@ -109,7 +106,26 @@ pub static ILLEGAL_CTXT : SyntaxContext = 1;
/// A name is a part of an identifier, representing a string or gensym. It's /// A name is a part of an identifier, representing a string or gensym. It's
/// the result of interning. /// the result of interning.
pub type Name = u32; #[deriving(Eq, Ord, PartialEq, PartialOrd, Hash, Encodable, Decodable, Clone, Show)]
pub struct Name(pub u32);
impl Name {
pub fn as_str<'a>(&'a self) -> &'a str {
unsafe {
// FIXME #12938: can't use copy_lifetime since &str isn't a &T
::std::mem::transmute(token::get_name(*self).get())
}
}
pub fn uint(&self) -> uint {
let Name(nm) = *self;
nm as uint
}
pub fn ident(&self) -> Ident {
Ident { name: *self, ctxt: 0 }
}
}
/// A mark represents a unique id associated with a macro expansion /// A mark represents a unique id associated with a macro expansion
pub type Mrk = u32; pub type Mrk = u32;

View file

@ -535,6 +535,9 @@ impl<'a> ExtCtxt<'a> {
pub fn ident_of(&self, st: &str) -> ast::Ident { pub fn ident_of(&self, st: &str) -> ast::Ident {
str_to_ident(st) str_to_ident(st)
} }
pub fn name_of(&self, st: &str) -> ast::Name {
token::intern(st)
}
} }
/// Extract a string literal from the macro expanded version of `expr`, /// Extract a string literal from the macro expanded version of `expr`,

View file

@ -82,8 +82,8 @@ fn apply_rename_internal(id: Ident,
to: Name, to: Name,
ctxt: SyntaxContext, ctxt: SyntaxContext,
table: &SCTable) -> SyntaxContext { table: &SCTable) -> SyntaxContext {
let key = (ctxt,id,to); let key = (ctxt, id, to);
let new_ctxt = |_: &(SyntaxContext, Ident, Mrk)| let new_ctxt = |_: &(SyntaxContext, Ident, Name)|
idx_push(&mut *table.table.borrow_mut(), Rename(id, to, ctxt)); idx_push(&mut *table.table.borrow_mut(), Rename(id, to, ctxt));
*table.rename_memo.borrow_mut().find_or_insert_with(key, new_ctxt) *table.rename_memo.borrow_mut().find_or_insert_with(key, new_ctxt)
@ -142,7 +142,7 @@ pub fn clear_tables() {
} }
/// Add a value to the end of a vec, return its index /// Add a value to the end of a vec, return its index
fn idx_push<T>(vec: &mut Vec<T> , val: T) -> u32 { fn idx_push<T>(vec: &mut Vec<T>, val: T) -> u32 {
vec.push(val); vec.push(val);
(vec.len() - 1) as u32 (vec.len() - 1) as u32
} }

View file

@ -363,6 +363,15 @@ fn mk_ident(cx: &ExtCtxt, sp: Span, ident: ast::Ident) -> Gc<ast::Expr> {
vec!(e_str)) vec!(e_str))
} }
// Lift a name to the expr that evaluates to that name
fn mk_name(cx: &ExtCtxt, sp: Span, ident: ast::Ident) -> Gc<ast::Expr> {
let e_str = cx.expr_str(sp, token::get_ident(ident));
cx.expr_method_call(sp,
cx.expr_ident(sp, id_ext("ext_cx")),
id_ext("name_of"),
vec!(e_str))
}
fn mk_ast_path(cx: &ExtCtxt, sp: Span, name: &str) -> Gc<ast::Expr> { fn mk_ast_path(cx: &ExtCtxt, sp: Span, name: &str) -> Gc<ast::Expr> {
let idents = vec!(id_ext("syntax"), id_ext("ast"), id_ext(name)); let idents = vec!(id_ext("syntax"), id_ext("ast"), id_ext(name));
cx.expr_path(cx.path_global(sp, idents)) cx.expr_path(cx.path_global(sp, idents))
@ -401,37 +410,37 @@ fn mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> Gc<ast::Expr> {
} }
LIT_BYTE(i) => { LIT_BYTE(i) => {
let e_byte = mk_ident(cx, sp, i); let e_byte = mk_name(cx, sp, i.ident());
return cx.expr_call(sp, mk_token_path(cx, sp, "LIT_BYTE"), vec!(e_byte)); return cx.expr_call(sp, mk_token_path(cx, sp, "LIT_BYTE"), vec!(e_byte));
} }
LIT_CHAR(i) => { LIT_CHAR(i) => {
let e_char = mk_ident(cx, sp, i); let e_char = mk_name(cx, sp, i.ident());
return cx.expr_call(sp, mk_token_path(cx, sp, "LIT_CHAR"), vec!(e_char)); return cx.expr_call(sp, mk_token_path(cx, sp, "LIT_CHAR"), vec!(e_char));
} }
LIT_INTEGER(i) => { LIT_INTEGER(i) => {
let e_int = mk_ident(cx, sp, i); let e_int = mk_name(cx, sp, i.ident());
return cx.expr_call(sp, mk_token_path(cx, sp, "LIT_INTEGER"), vec!(e_int)); return cx.expr_call(sp, mk_token_path(cx, sp, "LIT_INTEGER"), vec!(e_int));
} }
LIT_FLOAT(fident) => { LIT_FLOAT(fident) => {
let e_fident = mk_ident(cx, sp, fident); let e_fident = mk_name(cx, sp, fident.ident());
return cx.expr_call(sp, mk_token_path(cx, sp, "LIT_FLOAT"), vec!(e_fident)); return cx.expr_call(sp, mk_token_path(cx, sp, "LIT_FLOAT"), vec!(e_fident));
} }
LIT_STR(ident) => { LIT_STR(ident) => {
return cx.expr_call(sp, return cx.expr_call(sp,
mk_token_path(cx, sp, "LIT_STR"), mk_token_path(cx, sp, "LIT_STR"),
vec!(mk_ident(cx, sp, ident))); vec!(mk_name(cx, sp, ident.ident())));
} }
LIT_STR_RAW(ident, n) => { LIT_STR_RAW(ident, n) => {
return cx.expr_call(sp, return cx.expr_call(sp,
mk_token_path(cx, sp, "LIT_STR_RAW"), mk_token_path(cx, sp, "LIT_STR_RAW"),
vec!(mk_ident(cx, sp, ident), cx.expr_uint(sp, n))); vec!(mk_name(cx, sp, ident.ident()), cx.expr_uint(sp, n)));
} }
IDENT(ident, b) => { IDENT(ident, b) => {
@ -449,7 +458,7 @@ fn mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> Gc<ast::Expr> {
DOC_COMMENT(ident) => { DOC_COMMENT(ident) => {
return cx.expr_call(sp, return cx.expr_call(sp,
mk_token_path(cx, sp, "DOC_COMMENT"), mk_token_path(cx, sp, "DOC_COMMENT"),
vec!(mk_ident(cx, sp, ident))); vec!(mk_name(cx, sp, ident.ident())));
} }
INTERPOLATED(_) => fail!("quote! with interpolated token"), INTERPOLATED(_) => fail!("quote! with interpolated token"),

View file

@ -43,7 +43,7 @@ impl<'a> ParserAttr for Parser<'a> {
token::DOC_COMMENT(s) => { token::DOC_COMMENT(s) => {
let attr = ::attr::mk_sugared_doc_attr( let attr = ::attr::mk_sugared_doc_attr(
attr::mk_attr_id(), attr::mk_attr_id(),
self.id_to_interned_str(s), self.id_to_interned_str(s.ident()),
self.span.lo, self.span.lo,
self.span.hi self.span.hi
); );
@ -139,7 +139,7 @@ impl<'a> ParserAttr for Parser<'a> {
let Span { lo, hi, .. } = self.span; let Span { lo, hi, .. } = self.span;
self.bump(); self.bump();
attr::mk_sugared_doc_attr(attr::mk_attr_id(), attr::mk_sugared_doc_attr(attr::mk_attr_id(),
self.id_to_interned_str(s), self.id_to_interned_str(s.ident()),
lo, lo,
hi) hi)
} }

View file

@ -216,18 +216,18 @@ impl<'a> StringReader<'a> {
self.with_str_from_to(start, self.last_pos, f) self.with_str_from_to(start, self.last_pos, f)
} }
/// Create an Ident from a given offset to the current offset, each /// Create a Name from a given offset to the current offset, each
/// adjusted 1 towards each other (assumes that on either side there is a /// adjusted 1 towards each other (assumes that on either side there is a
/// single-byte delimiter). /// single-byte delimiter).
pub fn ident_from(&self, start: BytePos) -> ast::Ident { pub fn name_from(&self, start: BytePos) -> ast::Name {
debug!("taking an ident from {} to {}", start, self.last_pos); debug!("taking an ident from {} to {}", start, self.last_pos);
self.with_str_from(start, str_to_ident) self.with_str_from(start, token::intern)
} }
/// As ident_from, with an explicit endpoint. /// As name_from, with an explicit endpoint.
pub fn ident_from_to(&self, start: BytePos, end: BytePos) -> ast::Ident { pub fn name_from_to(&self, start: BytePos, end: BytePos) -> ast::Name {
debug!("taking an ident from {} to {}", start, end); debug!("taking an ident from {} to {}", start, end);
self.with_str_from_to(start, end, str_to_ident) self.with_str_from_to(start, end, token::intern)
} }
/// Calls `f` with a string slice of the source text spanning from `start` /// Calls `f` with a string slice of the source text spanning from `start`
@ -377,7 +377,7 @@ impl<'a> StringReader<'a> {
return self.with_str_from(start_bpos, |string| { return self.with_str_from(start_bpos, |string| {
// but comments with only more "/"s are not // but comments with only more "/"s are not
let tok = if is_doc_comment(string) { let tok = if is_doc_comment(string) {
token::DOC_COMMENT(str_to_ident(string)) token::DOC_COMMENT(token::intern(string))
} else { } else {
token::COMMENT token::COMMENT
}; };
@ -421,7 +421,7 @@ impl<'a> StringReader<'a> {
let start = self.last_pos; let start = self.last_pos;
while !self.curr_is('\n') && !self.is_eof() { self.bump(); } while !self.curr_is('\n') && !self.is_eof() { self.bump(); }
return Some(TokenAndSpan { return Some(TokenAndSpan {
tok: token::SHEBANG(self.ident_from(start)), tok: token::SHEBANG(self.name_from(start)),
sp: codemap::mk_sp(start, self.last_pos) sp: codemap::mk_sp(start, self.last_pos)
}); });
} }
@ -500,7 +500,7 @@ impl<'a> StringReader<'a> {
self.translate_crlf(start_bpos, string, self.translate_crlf(start_bpos, string,
"bare CR not allowed in block doc-comment") "bare CR not allowed in block doc-comment")
} else { string.into_maybe_owned() }; } else { string.into_maybe_owned() };
token::DOC_COMMENT(str_to_ident(string.as_slice())) token::DOC_COMMENT(token::intern(string.as_slice()))
} else { } else {
token::COMMENT token::COMMENT
}; };
@ -548,17 +548,17 @@ impl<'a> StringReader<'a> {
} }
'u' | 'i' => { 'u' | 'i' => {
self.scan_int_suffix(); self.scan_int_suffix();
return token::LIT_INTEGER(self.ident_from(start_bpos)); return token::LIT_INTEGER(self.name_from(start_bpos));
}, },
'f' => { 'f' => {
let last_pos = self.last_pos; let last_pos = self.last_pos;
self.scan_float_suffix(); self.scan_float_suffix();
self.check_float_base(start_bpos, last_pos, base); self.check_float_base(start_bpos, last_pos, base);
return token::LIT_FLOAT(self.ident_from(start_bpos)); return token::LIT_FLOAT(self.name_from(start_bpos));
} }
_ => { _ => {
// just a 0 // just a 0
return token::LIT_INTEGER(self.ident_from(start_bpos)); return token::LIT_INTEGER(self.name_from(start_bpos));
} }
} }
} else if c.is_digit_radix(10) { } else if c.is_digit_radix(10) {
@ -571,7 +571,7 @@ impl<'a> StringReader<'a> {
self.err_span_(start_bpos, self.last_pos, "no valid digits found for number"); self.err_span_(start_bpos, self.last_pos, "no valid digits found for number");
// eat any suffix // eat any suffix
self.scan_int_suffix(); self.scan_int_suffix();
return token::LIT_INTEGER(str_to_ident("0")); return token::LIT_INTEGER(token::intern("0"));
} }
// might be a float, but don't be greedy if this is actually an // might be a float, but don't be greedy if this is actually an
@ -589,13 +589,13 @@ impl<'a> StringReader<'a> {
} }
let last_pos = self.last_pos; let last_pos = self.last_pos;
self.check_float_base(start_bpos, last_pos, base); self.check_float_base(start_bpos, last_pos, base);
return token::LIT_FLOAT(self.ident_from(start_bpos)); return token::LIT_FLOAT(self.name_from(start_bpos));
} else if self.curr_is('f') { } else if self.curr_is('f') {
// or it might be an integer literal suffixed as a float // or it might be an integer literal suffixed as a float
self.scan_float_suffix(); self.scan_float_suffix();
let last_pos = self.last_pos; let last_pos = self.last_pos;
self.check_float_base(start_bpos, last_pos, base); self.check_float_base(start_bpos, last_pos, base);
return token::LIT_FLOAT(self.ident_from(start_bpos)); return token::LIT_FLOAT(self.name_from(start_bpos));
} else { } else {
// it might be a float if it has an exponent // it might be a float if it has an exponent
if self.curr_is('e') || self.curr_is('E') { if self.curr_is('e') || self.curr_is('E') {
@ -603,11 +603,11 @@ impl<'a> StringReader<'a> {
self.scan_float_suffix(); self.scan_float_suffix();
let last_pos = self.last_pos; let last_pos = self.last_pos;
self.check_float_base(start_bpos, last_pos, base); self.check_float_base(start_bpos, last_pos, base);
return token::LIT_FLOAT(self.ident_from(start_bpos)); return token::LIT_FLOAT(self.name_from(start_bpos));
} }
// but we certainly have an integer! // but we certainly have an integer!
self.scan_int_suffix(); self.scan_int_suffix();
return token::LIT_INTEGER(self.ident_from(start_bpos)); return token::LIT_INTEGER(self.name_from(start_bpos));
} }
} }
@ -980,7 +980,7 @@ impl<'a> StringReader<'a> {
start - BytePos(1), last_bpos, start - BytePos(1), last_bpos,
"unterminated character constant".to_string()); "unterminated character constant".to_string());
} }
let id = if valid { self.ident_from(start) } else { str_to_ident("0") }; let id = if valid { self.name_from(start) } else { token::intern("0") };
self.bump(); // advance curr past token self.bump(); // advance curr past token
return token::LIT_CHAR(id); return token::LIT_CHAR(id);
} }
@ -1010,8 +1010,8 @@ impl<'a> StringReader<'a> {
valid &= self.scan_char_or_byte(ch_start, ch, /* ascii_only = */ false, '"'); valid &= self.scan_char_or_byte(ch_start, ch, /* ascii_only = */ false, '"');
} }
// adjust for the ACSII " at the start of the literal // adjust for the ACSII " at the start of the literal
let id = if valid { self.ident_from(start_bpos + BytePos(1)) } let id = if valid { self.name_from(start_bpos + BytePos(1)) }
else { str_to_ident("??") }; else { token::intern("??") };
self.bump(); self.bump();
return token::LIT_STR(id); return token::LIT_STR(id);
} }
@ -1076,9 +1076,9 @@ impl<'a> StringReader<'a> {
} }
self.bump(); self.bump();
let id = if valid { let id = if valid {
self.ident_from_to(content_start_bpos, content_end_bpos) self.name_from_to(content_start_bpos, content_end_bpos)
} else { } else {
str_to_ident("??") token::intern("??")
}; };
return token::LIT_STR_RAW(id, hash_count); return token::LIT_STR_RAW(id, hash_count);
} }
@ -1168,7 +1168,7 @@ impl<'a> StringReader<'a> {
"unterminated byte constant".to_string()); "unterminated byte constant".to_string());
} }
let id = if valid { self.ident_from(start) } else { str_to_ident("??") }; let id = if valid { self.name_from(start) } else { token::intern("??") };
self.bump(); // advance curr past token self.bump(); // advance curr past token
return token::LIT_BYTE(id); return token::LIT_BYTE(id);
} }
@ -1190,7 +1190,7 @@ impl<'a> StringReader<'a> {
self.bump(); self.bump();
valid &= self.scan_char_or_byte(ch_start, ch, /* ascii_only = */ true, '"'); valid &= self.scan_char_or_byte(ch_start, ch, /* ascii_only = */ true, '"');
} }
let id = if valid { self.ident_from(start) } else { str_to_ident("??") }; let id = if valid { self.name_from(start) } else { token::intern("??") };
self.bump(); self.bump();
return token::LIT_BINARY(id); return token::LIT_BINARY(id);
} }
@ -1243,7 +1243,7 @@ impl<'a> StringReader<'a> {
self.bump(); self.bump();
} }
self.bump(); self.bump();
return token::LIT_BINARY_RAW(self.ident_from_to(content_start_bpos, content_end_bpos), return token::LIT_BINARY_RAW(self.name_from_to(content_start_bpos, content_end_bpos),
hash_count); hash_count);
} }
} }

View file

@ -1560,7 +1560,7 @@ impl<'a> Parser<'a> {
match *tok { match *tok {
token::LIT_BYTE(i) => LitByte(parse::byte_lit(i.as_str()).val0()), token::LIT_BYTE(i) => LitByte(parse::byte_lit(i.as_str()).val0()),
token::LIT_CHAR(i) => LitChar(parse::char_lit(i.as_str()).val0()), token::LIT_CHAR(i) => LitChar(parse::char_lit(i.as_str()).val0()),
token::LIT_INTEGER(s) => parse::integer_lit(self.id_to_interned_str(s).get(), token::LIT_INTEGER(s) => parse::integer_lit(s.as_str(),
&self.sess.span_diagnostic, self.span), &self.sess.span_diagnostic, self.span),
token::LIT_FLOAT(s) => parse::float_lit(s.as_str()), token::LIT_FLOAT(s) => parse::float_lit(s.as_str()),
token::LIT_STR(s) => { token::LIT_STR(s) => {
@ -1572,7 +1572,7 @@ impl<'a> Parser<'a> {
ast::RawStr(n)) ast::RawStr(n))
} }
token::LIT_BINARY(i) => token::LIT_BINARY(i) =>
LitBinary(parse::binary_lit(self.id_to_interned_str(i).get())), LitBinary(parse::binary_lit(i.as_str())),
token::LIT_BINARY_RAW(i, _) => token::LIT_BINARY_RAW(i, _) =>
LitBinary(Rc::new(i.as_str().as_bytes().iter().map(|&x| x).collect())), LitBinary(Rc::new(i.as_str().as_bytes().iter().map(|&x| x).collect())),
token::LPAREN => { self.expect(&token::RPAREN); LitNil }, token::LPAREN => { self.expect(&token::RPAREN); LitNil },
@ -1948,7 +1948,12 @@ impl<'a> Parser<'a> {
}); });
return self.mk_expr(lo, body.span.hi, ExprProc(decl, fakeblock)); return self.mk_expr(lo, body.span.hi, ExprProc(decl, fakeblock));
}, },
token::IDENT(id @ ast::Ident{name:token::SELF_KEYWORD_NAME,ctxt:_},false) => { // FIXME #13626: Should be able to stick in
// token::SELF_KEYWORD_NAME
token::IDENT(id @ ast::Ident{
name: ast::Name(token::SELF_KEYWORD_NAME_NUM),
ctxt: _
} ,false) => {
self.bump(); self.bump();
let path = ast_util::ident_to_path(mk_sp(lo, hi), id); let path = ast_util::ident_to_path(mk_sp(lo, hi), id);
ex = ExprPath(path); ex = ExprPath(path);
@ -4770,8 +4775,7 @@ impl<'a> Parser<'a> {
match self.token { match self.token {
token::LIT_STR(s) | token::LIT_STR_RAW(s, _) => { token::LIT_STR(s) | token::LIT_STR_RAW(s, _) => {
self.bump(); self.bump();
let identifier_string = token::get_ident(s); let the_string = s.as_str();
let the_string = identifier_string.get();
match abi::lookup(the_string) { match abi::lookup(the_string) {
Some(abi) => Some(abi), Some(abi) => Some(abi),
None => { None => {
@ -5389,9 +5393,9 @@ impl<'a> Parser<'a> {
pub fn parse_optional_str(&mut self) pub fn parse_optional_str(&mut self)
-> Option<(InternedString, ast::StrStyle)> { -> Option<(InternedString, ast::StrStyle)> {
let (s, style) = match self.token { let (s, style) = match self.token {
token::LIT_STR(s) => (self.id_to_interned_str(s), ast::CookedStr), token::LIT_STR(s) => (self.id_to_interned_str(s.ident()), ast::CookedStr),
token::LIT_STR_RAW(s, n) => { token::LIT_STR_RAW(s, n) => {
(self.id_to_interned_str(s), ast::RawStr(n)) (self.id_to_interned_str(s.ident()), ast::RawStr(n))
} }
_ => return None _ => return None
}; };

View file

@ -78,14 +78,14 @@ pub enum Token {
QUESTION, QUESTION,
/* Literals */ /* Literals */
LIT_BYTE(Ident), LIT_BYTE(Name),
LIT_CHAR(Ident), LIT_CHAR(Name),
LIT_INTEGER(Ident), LIT_INTEGER(Name),
LIT_FLOAT(Ident), LIT_FLOAT(Name),
LIT_STR(Ident), LIT_STR(Name),
LIT_STR_RAW(Ident, uint), /* raw str delimited by n hash symbols */ LIT_STR_RAW(Name, uint), /* raw str delimited by n hash symbols */
LIT_BINARY(Ident), LIT_BINARY(Name),
LIT_BINARY_RAW(Ident, uint), /* raw binary str delimited by n hash symbols */ LIT_BINARY_RAW(Name, uint), /* raw binary str delimited by n hash symbols */
/* Name components */ /* Name components */
/// An identifier contains an "is_mod_name" boolean, /// An identifier contains an "is_mod_name" boolean,
@ -97,7 +97,7 @@ pub enum Token {
/* For interpolation */ /* For interpolation */
INTERPOLATED(Nonterminal), INTERPOLATED(Nonterminal),
DOC_COMMENT(Ident), DOC_COMMENT(Name),
// Junk. These carry no data because we don't really care about the data // Junk. These carry no data because we don't really care about the data
// they *would* carry, and don't really want to allocate a new ident for // they *would* carry, and don't really want to allocate a new ident for
@ -107,7 +107,7 @@ pub enum Token {
WS, WS,
/// Comment /// Comment
COMMENT, COMMENT,
SHEBANG(Ident), SHEBANG(Name),
EOF, EOF,
} }
@ -207,28 +207,28 @@ pub fn to_string(t: &Token) -> String {
/* Literals */ /* Literals */
LIT_BYTE(b) => { LIT_BYTE(b) => {
format!("b'{}'", get_ident(b).get()) format!("b'{}'", b.as_str())
} }
LIT_CHAR(c) => { LIT_CHAR(c) => {
format!("'{}'", get_ident(c).get()) format!("'{}'", c.as_str())
} }
LIT_INTEGER(c) | LIT_FLOAT(c) => { LIT_INTEGER(c) | LIT_FLOAT(c) => {
get_ident(c).get().to_string() c.as_str().to_string()
} }
LIT_STR(s) => { LIT_STR(s) => {
format!("\"{}\"", get_ident(s).get()) format!("\"{}\"", s.as_str())
} }
LIT_STR_RAW(s, n) => { LIT_STR_RAW(s, n) => {
format!("r{delim}\"{string}\"{delim}", format!("r{delim}\"{string}\"{delim}",
delim="#".repeat(n), string=get_ident(s)) delim="#".repeat(n), string=s.as_str())
} }
LIT_BINARY(v) => { LIT_BINARY(v) => {
format!("b\"{}\"", get_ident(v).get()) format!("b\"{}\"", v.as_str())
} }
LIT_BINARY_RAW(s, n) => { LIT_BINARY_RAW(s, n) => {
format!("br{delim}\"{string}\"{delim}", format!("br{delim}\"{string}\"{delim}",
delim="#".repeat(n), string=get_ident(s).get()) delim="#".repeat(n), string=s.as_str())
} }
/* Name components */ /* Name components */
@ -239,7 +239,7 @@ pub fn to_string(t: &Token) -> String {
UNDERSCORE => "_".to_string(), UNDERSCORE => "_".to_string(),
/* Other */ /* Other */
DOC_COMMENT(s) => get_ident(s).get().to_string(), DOC_COMMENT(s) => s.as_str().to_string(),
EOF => "<eof>".to_string(), EOF => "<eof>".to_string(),
WS => " ".to_string(), WS => " ".to_string(),
COMMENT => "/* */".to_string(), COMMENT => "/* */".to_string(),
@ -374,19 +374,19 @@ macro_rules! declare_special_idents_and_keywords {(
$( ($rk_name:expr, $rk_variant:ident, $rk_str:expr); )* $( ($rk_name:expr, $rk_variant:ident, $rk_str:expr); )*
} }
) => { ) => {
static STRICT_KEYWORD_START: Name = first!($( $sk_name, )*); static STRICT_KEYWORD_START: Name = first!($( Name($sk_name), )*);
static STRICT_KEYWORD_FINAL: Name = last!($( $sk_name, )*); static STRICT_KEYWORD_FINAL: Name = last!($( Name($sk_name), )*);
static RESERVED_KEYWORD_START: Name = first!($( $rk_name, )*); static RESERVED_KEYWORD_START: Name = first!($( Name($rk_name), )*);
static RESERVED_KEYWORD_FINAL: Name = last!($( $rk_name, )*); static RESERVED_KEYWORD_FINAL: Name = last!($( Name($rk_name), )*);
pub mod special_idents { pub mod special_idents {
use ast::Ident; use ast::{Ident, Name};
$( pub static $si_static: Ident = Ident { name: $si_name, ctxt: 0 }; )* $( pub static $si_static: Ident = Ident { name: Name($si_name), ctxt: 0 }; )*
} }
pub mod special_names { pub mod special_names {
use ast::Name; use ast::Name;
$( pub static $si_static: Name = $si_name; )* $( pub static $si_static: Name = Name($si_name); )*
} }
/** /**
@ -407,8 +407,8 @@ macro_rules! declare_special_idents_and_keywords {(
impl Keyword { impl Keyword {
pub fn to_name(&self) -> Name { pub fn to_name(&self) -> Name {
match *self { match *self {
$( $sk_variant => $sk_name, )* $( $sk_variant => Name($sk_name), )*
$( $rk_variant => $rk_name, )* $( $rk_variant => Name($rk_name), )*
} }
} }
} }
@ -427,8 +427,11 @@ macro_rules! declare_special_idents_and_keywords {(
}} }}
// If the special idents get renumbered, remember to modify these two as appropriate // If the special idents get renumbered, remember to modify these two as appropriate
pub static SELF_KEYWORD_NAME: Name = 1; pub static SELF_KEYWORD_NAME: Name = Name(SELF_KEYWORD_NAME_NUM);
static STATIC_KEYWORD_NAME: Name = 2; static STATIC_KEYWORD_NAME: Name = Name(STATIC_KEYWORD_NAME_NUM);
pub static SELF_KEYWORD_NAME_NUM: u32 = 1;
static STATIC_KEYWORD_NAME_NUM: u32 = 2;
// NB: leaving holes in the ident table is bad! a different ident will get // NB: leaving holes in the ident table is bad! a different ident will get
// interned with the id from the hole, but it will be between the min and max // interned with the id from the hole, but it will be between the min and max
@ -438,8 +441,8 @@ declare_special_idents_and_keywords! {
pub mod special_idents { pub mod special_idents {
// These ones are statics // These ones are statics
(0, invalid, ""); (0, invalid, "");
(super::SELF_KEYWORD_NAME, self_, "self"); (super::SELF_KEYWORD_NAME_NUM, self_, "self");
(super::STATIC_KEYWORD_NAME, statik, "static"); (super::STATIC_KEYWORD_NAME_NUM, statik, "static");
(3, static_lifetime, "'static"); (3, static_lifetime, "'static");
// for matcher NTs // for matcher NTs
@ -479,8 +482,8 @@ declare_special_idents_and_keywords! {
(29, Ref, "ref"); (29, Ref, "ref");
(30, Return, "return"); (30, Return, "return");
// Static and Self are also special idents (prefill de-dupes) // Static and Self are also special idents (prefill de-dupes)
(super::STATIC_KEYWORD_NAME, Static, "static"); (super::STATIC_KEYWORD_NAME_NUM, Static, "static");
(super::SELF_KEYWORD_NAME, Self, "self"); (super::SELF_KEYWORD_NAME_NUM, Self, "self");
(31, Struct, "struct"); (31, Struct, "struct");
(32, Super, "super"); (32, Super, "super");
(33, True, "true"); (33, True, "true");
@ -687,7 +690,7 @@ pub fn fresh_name(src: &Ident) -> Name {
// create a fresh mark. // create a fresh mark.
pub fn fresh_mark() -> Mrk { pub fn fresh_mark() -> Mrk {
gensym("mark") gensym("mark").uint() as u32
} }
// See the macro above about the types of keywords // See the macro above about the types of keywords
@ -701,10 +704,13 @@ pub fn is_keyword(kw: keywords::Keyword, tok: &Token) -> bool {
pub fn is_any_keyword(tok: &Token) -> bool { pub fn is_any_keyword(tok: &Token) -> bool {
match *tok { match *tok {
token::IDENT(sid, false) => match sid.name { token::IDENT(sid, false) => {
SELF_KEYWORD_NAME | STATIC_KEYWORD_NAME | let n = sid.name;
STRICT_KEYWORD_START .. RESERVED_KEYWORD_FINAL => true,
_ => false, n == SELF_KEYWORD_NAME
|| n == STATIC_KEYWORD_NAME
|| STRICT_KEYWORD_START <= n
&& n <= RESERVED_KEYWORD_FINAL
}, },
_ => false _ => false
} }
@ -712,10 +718,13 @@ pub fn is_any_keyword(tok: &Token) -> bool {
pub fn is_strict_keyword(tok: &Token) -> bool { pub fn is_strict_keyword(tok: &Token) -> bool {
match *tok { match *tok {
token::IDENT(sid, false) => match sid.name { token::IDENT(sid, false) => {
SELF_KEYWORD_NAME | STATIC_KEYWORD_NAME | let n = sid.name;
STRICT_KEYWORD_START .. STRICT_KEYWORD_FINAL => true,
_ => false, n == SELF_KEYWORD_NAME
|| n == STATIC_KEYWORD_NAME
|| STRICT_KEYWORD_START <= n
&& n <= STRICT_KEYWORD_FINAL
}, },
_ => false, _ => false,
} }
@ -723,9 +732,11 @@ pub fn is_strict_keyword(tok: &Token) -> bool {
pub fn is_reserved_keyword(tok: &Token) -> bool { pub fn is_reserved_keyword(tok: &Token) -> bool {
match *tok { match *tok {
token::IDENT(sid, false) => match sid.name { token::IDENT(sid, false) => {
RESERVED_KEYWORD_START .. RESERVED_KEYWORD_FINAL => true, let n = sid.name;
_ => false,
RESERVED_KEYWORD_START <= n
&& n <= RESERVED_KEYWORD_FINAL
}, },
_ => false, _ => false,
} }

View file

@ -52,7 +52,7 @@ impl<T: Eq + Hash + Clone + 'static> Interner<T> {
} }
let mut vect = self.vect.borrow_mut(); let mut vect = self.vect.borrow_mut();
let new_idx = (*vect).len() as Name; let new_idx = Name((*vect).len() as u32);
(*map).insert(val.clone(), new_idx); (*map).insert(val.clone(), new_idx);
(*vect).push(val); (*vect).push(val);
new_idx new_idx
@ -60,7 +60,7 @@ impl<T: Eq + Hash + Clone + 'static> Interner<T> {
pub fn gensym(&self, val: T) -> Name { pub fn gensym(&self, val: T) -> Name {
let mut vect = self.vect.borrow_mut(); let mut vect = self.vect.borrow_mut();
let new_idx = (*vect).len() as Name; let new_idx = Name((*vect).len() as u32);
// leave out of .map to avoid colliding // leave out of .map to avoid colliding
(*vect).push(val); (*vect).push(val);
new_idx new_idx
@ -68,7 +68,7 @@ impl<T: Eq + Hash + Clone + 'static> Interner<T> {
pub fn get(&self, idx: Name) -> T { pub fn get(&self, idx: Name) -> T {
let vect = self.vect.borrow(); let vect = self.vect.borrow();
(*(*vect).get(idx as uint)).clone() (*(*vect).get(idx.uint())).clone()
} }
pub fn len(&self) -> uint { pub fn len(&self) -> uint {
@ -155,7 +155,7 @@ impl StrInterner {
None => (), None => (),
} }
let new_idx = self.len() as Name; let new_idx = Name(self.len() as u32);
let val = RcStr::new(val); let val = RcStr::new(val);
map.insert(val.clone(), new_idx); map.insert(val.clone(), new_idx);
self.vect.borrow_mut().push(val); self.vect.borrow_mut().push(val);
@ -163,7 +163,7 @@ impl StrInterner {
} }
pub fn gensym(&self, val: &str) -> Name { pub fn gensym(&self, val: &str) -> Name {
let new_idx = self.len() as Name; 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(RcStr::new(val));
new_idx new_idx
@ -180,23 +180,23 @@ impl StrInterner {
/// Create a gensym with the same name as an existing /// Create a gensym with the same name as an existing
/// entry. /// entry.
pub fn gensym_copy(&self, idx : Name) -> Name { pub fn gensym_copy(&self, idx : Name) -> Name {
let new_idx = self.len() as Name; let new_idx = Name(self.len() as u32);
// leave out of map to avoid colliding // leave out of map to avoid colliding
let mut vect = self.vect.borrow_mut(); let mut vect = self.vect.borrow_mut();
let existing = (*vect.get(idx as uint)).clone(); let existing = (*vect.get(idx.uint())).clone();
vect.push(existing); vect.push(existing);
new_idx new_idx
} }
pub fn get(&self, idx: Name) -> RcStr { pub fn get(&self, idx: Name) -> RcStr {
(*self.vect.borrow().get(idx as uint)).clone() (*self.vect.borrow().get(idx.uint())).clone()
} }
/// Returns this string with lifetime tied to the interner. Since /// Returns this string with lifetime tied to the interner. Since
/// strings may never be removed from the interner, this is safe. /// strings may never be removed from the interner, this is safe.
pub fn get_ref<'a>(&'a self, idx: Name) -> &'a str { pub fn get_ref<'a>(&'a self, idx: Name) -> &'a str {
let vect = self.vect.borrow(); let vect = self.vect.borrow();
let s: &str = vect.get(idx as uint).as_slice(); let s: &str = vect.get(idx.uint()).as_slice();
unsafe { unsafe {
mem::transmute(s) mem::transmute(s)
} }