match mode {
ast::BindByValue(ast::MutMutable) => {
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); });
}
}
let string = name.as_str_slice();
match intr.find_equiv(&string) {
None => token::str_to_ident(string),
- Some(val) => ast::Ident::new(val as ast::Name),
+ Some(val) => ast::Ident::new(val),
}
}
pub fn new(name: Name) -> Ident { Ident {name: name, ctxt: EMPTY_CTXT}}
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_ident(*self).get())
- }
+ self.name.as_str()
}
}
/// A name is a part of an identifier, representing a string or gensym. It's
/// 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
pub type Mrk = u32;
pub fn ident_of(&self, st: &str) -> ast::Ident {
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`,
to: Name,
ctxt: SyntaxContext,
table: &SCTable) -> SyntaxContext {
- let key = (ctxt,id,to);
- let new_ctxt = |_: &(SyntaxContext, Ident, Mrk)|
+ let key = (ctxt, id, to);
+ let new_ctxt = |_: &(SyntaxContext, Ident, Name)|
idx_push(&mut *table.table.borrow_mut(), Rename(id, to, ctxt));
*table.rename_memo.borrow_mut().find_or_insert_with(key, new_ctxt)
}
/// 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.len() - 1) as u32
}
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> {
let idents = vec!(id_ext("syntax"), id_ext("ast"), id_ext(name));
cx.expr_path(cx.path_global(sp, idents))
}
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));
}
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));
}
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));
}
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));
}
LIT_STR(ident) => {
return cx.expr_call(sp,
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) => {
return cx.expr_call(sp,
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) => {
DOC_COMMENT(ident) => {
return cx.expr_call(sp,
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"),
token::DOC_COMMENT(s) => {
let attr = ::attr::mk_sugared_doc_attr(
attr::mk_attr_id(),
- self.id_to_interned_str(s),
+ self.id_to_interned_str(s.ident()),
self.span.lo,
self.span.hi
);
let Span { lo, hi, .. } = self.span;
self.bump();
attr::mk_sugared_doc_attr(attr::mk_attr_id(),
- self.id_to_interned_str(s),
+ self.id_to_interned_str(s.ident()),
lo,
hi)
}
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
/// 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);
- self.with_str_from(start, str_to_ident)
+ self.with_str_from(start, token::intern)
}
- /// As ident_from, with an explicit endpoint.
- pub fn ident_from_to(&self, start: BytePos, end: BytePos) -> ast::Ident {
+ /// As name_from, with an explicit endpoint.
+ pub fn name_from_to(&self, start: BytePos, end: BytePos) -> ast::Name {
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`
return self.with_str_from(start_bpos, |string| {
// but comments with only more "/"s are not
let tok = if is_doc_comment(string) {
- token::DOC_COMMENT(str_to_ident(string))
+ token::DOC_COMMENT(token::intern(string))
} else {
token::COMMENT
};
let start = self.last_pos;
while !self.curr_is('\n') && !self.is_eof() { self.bump(); }
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)
});
}
self.translate_crlf(start_bpos, string,
"bare CR not allowed in block doc-comment")
} else { string.into_maybe_owned() };
- token::DOC_COMMENT(str_to_ident(string.as_slice()))
+ token::DOC_COMMENT(token::intern(string.as_slice()))
} else {
token::COMMENT
};
}
'u' | 'i' => {
self.scan_int_suffix();
- return token::LIT_INTEGER(self.ident_from(start_bpos));
+ return token::LIT_INTEGER(self.name_from(start_bpos));
},
'f' => {
let last_pos = self.last_pos;
self.scan_float_suffix();
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
- 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) {
self.err_span_(start_bpos, self.last_pos, "no valid digits found for number");
// eat any 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
}
let last_pos = self.last_pos;
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') {
// or it might be an integer literal suffixed as a float
self.scan_float_suffix();
let last_pos = self.last_pos;
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 {
// it might be a float if it has an exponent
if self.curr_is('e') || self.curr_is('E') {
self.scan_float_suffix();
let last_pos = self.last_pos;
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!
self.scan_int_suffix();
- return token::LIT_INTEGER(self.ident_from(start_bpos));
+ return token::LIT_INTEGER(self.name_from(start_bpos));
}
}
start - BytePos(1), last_bpos,
"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
return token::LIT_CHAR(id);
}
valid &= self.scan_char_or_byte(ch_start, ch, /* ascii_only = */ false, '"');
}
// adjust for the ACSII " at the start of the literal
- let id = if valid { self.ident_from(start_bpos + BytePos(1)) }
- else { str_to_ident("??") };
+ let id = if valid { self.name_from(start_bpos + BytePos(1)) }
+ else { token::intern("??") };
self.bump();
return token::LIT_STR(id);
}
}
self.bump();
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 {
- str_to_ident("??")
+ token::intern("??")
};
return token::LIT_STR_RAW(id, hash_count);
}
"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
return token::LIT_BYTE(id);
}
self.bump();
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();
return token::LIT_BINARY(id);
}
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);
}
}
match *tok {
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_INTEGER(s) => parse::integer_lit(self.id_to_interned_str(s).get(),
- &self.sess.span_diagnostic, self.span),
+ token::LIT_INTEGER(s) => parse::integer_lit(s.as_str(),
+ &self.sess.span_diagnostic, self.span),
token::LIT_FLOAT(s) => parse::float_lit(s.as_str()),
token::LIT_STR(s) => {
LitStr(token::intern_and_get_ident(parse::str_lit(s.as_str()).as_slice()),
ast::RawStr(n))
}
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, _) =>
LitBinary(Rc::new(i.as_str().as_bytes().iter().map(|&x| x).collect())),
token::LPAREN => { self.expect(&token::RPAREN); LitNil },
});
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();
let path = ast_util::ident_to_path(mk_sp(lo, hi), id);
ex = ExprPath(path);
match self.token {
token::LIT_STR(s) | token::LIT_STR_RAW(s, _) => {
self.bump();
- let identifier_string = token::get_ident(s);
- let the_string = identifier_string.get();
+ let the_string = s.as_str();
match abi::lookup(the_string) {
Some(abi) => Some(abi),
None => {
pub fn parse_optional_str(&mut self)
-> Option<(InternedString, ast::StrStyle)> {
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) => {
- (self.id_to_interned_str(s), ast::RawStr(n))
+ (self.id_to_interned_str(s.ident()), ast::RawStr(n))
}
_ => return None
};
QUESTION,
/* Literals */
- LIT_BYTE(Ident),
- LIT_CHAR(Ident),
- LIT_INTEGER(Ident),
- LIT_FLOAT(Ident),
- LIT_STR(Ident),
- LIT_STR_RAW(Ident, uint), /* raw str delimited by n hash symbols */
- LIT_BINARY(Ident),
- LIT_BINARY_RAW(Ident, uint), /* raw binary str delimited by n hash symbols */
+ LIT_BYTE(Name),
+ LIT_CHAR(Name),
+ LIT_INTEGER(Name),
+ LIT_FLOAT(Name),
+ LIT_STR(Name),
+ LIT_STR_RAW(Name, uint), /* raw str delimited by n hash symbols */
+ LIT_BINARY(Name),
+ LIT_BINARY_RAW(Name, uint), /* raw binary str delimited by n hash symbols */
/* Name components */
/// An identifier contains an "is_mod_name" boolean,
/* For interpolation */
INTERPOLATED(Nonterminal),
- DOC_COMMENT(Ident),
+ DOC_COMMENT(Name),
// 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
WS,
/// Comment
COMMENT,
- SHEBANG(Ident),
+ SHEBANG(Name),
EOF,
}
/* Literals */
LIT_BYTE(b) => {
- format!("b'{}'", get_ident(b).get())
+ format!("b'{}'", b.as_str())
}
LIT_CHAR(c) => {
- format!("'{}'", get_ident(c).get())
+ format!("'{}'", c.as_str())
}
LIT_INTEGER(c) | LIT_FLOAT(c) => {
- get_ident(c).get().to_string()
+ c.as_str().to_string()
}
LIT_STR(s) => {
- format!("\"{}\"", get_ident(s).get())
+ format!("\"{}\"", s.as_str())
}
LIT_STR_RAW(s, n) => {
format!("r{delim}\"{string}\"{delim}",
- delim="#".repeat(n), string=get_ident(s))
+ delim="#".repeat(n), string=s.as_str())
}
LIT_BINARY(v) => {
- format!("b\"{}\"", get_ident(v).get())
+ format!("b\"{}\"", v.as_str())
}
LIT_BINARY_RAW(s, n) => {
format!("br{delim}\"{string}\"{delim}",
- delim="#".repeat(n), string=get_ident(s).get())
+ delim="#".repeat(n), string=s.as_str())
}
/* Name components */
UNDERSCORE => "_".to_string(),
/* Other */
- DOC_COMMENT(s) => get_ident(s).get().to_string(),
+ DOC_COMMENT(s) => s.as_str().to_string(),
EOF => "<eof>".to_string(),
WS => " ".to_string(),
COMMENT => "/* */".to_string(),
$( ($rk_name:expr, $rk_variant:ident, $rk_str:expr); )*
}
) => {
- static STRICT_KEYWORD_START: Name = first!($( $sk_name, )*);
- static STRICT_KEYWORD_FINAL: Name = last!($( $sk_name, )*);
- static RESERVED_KEYWORD_START: Name = first!($( $rk_name, )*);
- static RESERVED_KEYWORD_FINAL: Name = last!($( $rk_name, )*);
+ static STRICT_KEYWORD_START: Name = first!($( Name($sk_name), )*);
+ static STRICT_KEYWORD_FINAL: Name = last!($( Name($sk_name), )*);
+ static RESERVED_KEYWORD_START: Name = first!($( Name($rk_name), )*);
+ static RESERVED_KEYWORD_FINAL: Name = last!($( Name($rk_name), )*);
pub mod special_idents {
- use ast::Ident;
- $( pub static $si_static: Ident = Ident { name: $si_name, ctxt: 0 }; )*
+ use ast::{Ident, Name};
+ $( pub static $si_static: Ident = Ident { name: Name($si_name), ctxt: 0 }; )*
}
pub mod special_names {
use ast::Name;
- $( pub static $si_static: Name = $si_name; )*
+ $( pub static $si_static: Name = Name($si_name); )*
}
/**
impl Keyword {
pub fn to_name(&self) -> Name {
match *self {
- $( $sk_variant => $sk_name, )*
- $( $rk_variant => $rk_name, )*
+ $( $sk_variant => Name($sk_name), )*
+ $( $rk_variant => Name($rk_name), )*
}
}
}
}}
// If the special idents get renumbered, remember to modify these two as appropriate
-pub static SELF_KEYWORD_NAME: Name = 1;
-static STATIC_KEYWORD_NAME: Name = 2;
+pub static SELF_KEYWORD_NAME: Name = Name(SELF_KEYWORD_NAME_NUM);
+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
// interned with the id from the hole, but it will be between the min and max
pub mod special_idents {
// These ones are statics
(0, invalid, "");
- (super::SELF_KEYWORD_NAME, self_, "self");
- (super::STATIC_KEYWORD_NAME, statik, "static");
+ (super::SELF_KEYWORD_NAME_NUM, self_, "self");
+ (super::STATIC_KEYWORD_NAME_NUM, statik, "static");
(3, static_lifetime, "'static");
// for matcher NTs
(29, Ref, "ref");
(30, Return, "return");
// Static and Self are also special idents (prefill de-dupes)
- (super::STATIC_KEYWORD_NAME, Static, "static");
- (super::SELF_KEYWORD_NAME, Self, "self");
+ (super::STATIC_KEYWORD_NAME_NUM, Static, "static");
+ (super::SELF_KEYWORD_NAME_NUM, Self, "self");
(31, Struct, "struct");
(32, Super, "super");
(33, True, "true");
// create a fresh mark.
pub fn fresh_mark() -> Mrk {
- gensym("mark")
+ gensym("mark").uint() as u32
}
// See the macro above about the types of keywords
pub fn is_any_keyword(tok: &Token) -> bool {
match *tok {
- token::IDENT(sid, false) => match sid.name {
- SELF_KEYWORD_NAME | STATIC_KEYWORD_NAME |
- STRICT_KEYWORD_START .. RESERVED_KEYWORD_FINAL => true,
- _ => false,
+ token::IDENT(sid, false) => {
+ let n = sid.name;
+
+ n == SELF_KEYWORD_NAME
+ || n == STATIC_KEYWORD_NAME
+ || STRICT_KEYWORD_START <= n
+ && n <= RESERVED_KEYWORD_FINAL
},
_ => false
}
pub fn is_strict_keyword(tok: &Token) -> bool {
match *tok {
- token::IDENT(sid, false) => match sid.name {
- SELF_KEYWORD_NAME | STATIC_KEYWORD_NAME |
- STRICT_KEYWORD_START .. STRICT_KEYWORD_FINAL => true,
- _ => false,
+ token::IDENT(sid, false) => {
+ let n = sid.name;
+
+ n == SELF_KEYWORD_NAME
+ || n == STATIC_KEYWORD_NAME
+ || STRICT_KEYWORD_START <= n
+ && n <= STRICT_KEYWORD_FINAL
},
_ => false,
}
pub fn is_reserved_keyword(tok: &Token) -> bool {
match *tok {
- token::IDENT(sid, false) => match sid.name {
- RESERVED_KEYWORD_START .. RESERVED_KEYWORD_FINAL => true,
- _ => false,
+ token::IDENT(sid, false) => {
+ let n = sid.name;
+
+ RESERVED_KEYWORD_START <= n
+ && n <= RESERVED_KEYWORD_FINAL
},
_ => false,
}
}
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);
(*vect).push(val);
new_idx
pub fn gensym(&self, val: T) -> Name {
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
(*vect).push(val);
new_idx
pub fn get(&self, idx: Name) -> T {
let vect = self.vect.borrow();
- (*(*vect).get(idx as uint)).clone()
+ (*(*vect).get(idx.uint())).clone()
}
pub fn len(&self) -> uint {
None => (),
}
- let new_idx = self.len() as Name;
+ let new_idx = Name(self.len() as u32);
let val = RcStr::new(val);
map.insert(val.clone(), new_idx);
self.vect.borrow_mut().push(val);
}
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
self.vect.borrow_mut().push(RcStr::new(val));
new_idx
/// Create a gensym with the same name as an existing
/// entry.
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
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);
new_idx
}
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
/// strings may never be removed from the interner, this is safe.
pub fn get_ref<'a>(&'a self, idx: Name) -> &'a str {
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 {
mem::transmute(s)
}