From 1153b5dcc86c3567b0a86e441938f05d4f2e295b Mon Sep 17 00:00:00 2001 From: Paul Stansifer Date: Wed, 18 Jul 2012 16:18:02 -0700 Subject: intern identifiers --- src/libsyntax/ast.rs | 50 +++------ src/libsyntax/ast_map.rs | 37 +++---- src/libsyntax/ast_util.rs | 10 +- src/libsyntax/attr.rs | 112 ++++++++++----------- src/libsyntax/ext/auto_serialize.rs | 73 ++++++++------ src/libsyntax/ext/base.rs | 34 +++++-- src/libsyntax/ext/concat_idents.rs | 8 +- src/libsyntax/ext/expand.rs | 16 +-- src/libsyntax/ext/fmt.rs | 26 +++-- src/libsyntax/ext/ident_to_str.rs | 4 +- src/libsyntax/ext/log_syntax.rs | 3 +- src/libsyntax/ext/pipes.rs | 2 +- src/libsyntax/ext/pipes/ast_builder.rs | 15 ++- src/libsyntax/ext/pipes/check.rs | 10 +- src/libsyntax/ext/pipes/liveness.rs | 6 +- src/libsyntax/ext/pipes/parse_proto.rs | 15 +-- src/libsyntax/ext/pipes/pipec.rs | 142 ++++++++++++++------------ src/libsyntax/ext/pipes/proto.rs | 41 ++++---- src/libsyntax/ext/qquote.rs | 57 ++++++----- src/libsyntax/ext/simplext.rs | 33 +++--- src/libsyntax/ext/source_util.rs | 5 +- src/libsyntax/ext/trace_macros.rs | 6 +- src/libsyntax/ext/tt/earley_parser.rs | 13 +-- src/libsyntax/ext/tt/macro_rules.rs | 19 ++-- src/libsyntax/ext/tt/transcribe.rs | 14 +-- src/libsyntax/fold.rs | 5 +- src/libsyntax/parse/attr.rs | 12 +-- src/libsyntax/parse/comments.rs | 2 +- src/libsyntax/parse/common.rs | 10 +- src/libsyntax/parse/eval.rs | 23 +++-- src/libsyntax/parse/parser.rs | 59 +++++------ src/libsyntax/parse/token.rs | 76 ++++++++++++-- src/libsyntax/print/pprust.rs | 179 +++++++++++++++++---------------- src/libsyntax/util/interner.rs | 9 +- src/libsyntax/visit.rs | 6 +- 35 files changed, 617 insertions(+), 515 deletions(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index c7ff6671e0f..7d9803b4cc3 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -30,8 +30,18 @@ fn deserialize_span(_d: D) -> span { #[auto_serialize] type spanned = {node: T, span: span}; -#[auto_serialize] -type ident = @~str; +fn serialize_ident(s: S, i: ident) { + let intr = unsafe{ task::local_data_get(parse::token::interner_key) }; + + s.emit_str(*(*intr.get()).get(i)); +} +fn deserialize_ident(d: D) -> ident { + let intr = unsafe{ task::local_data_get(parse::token::interner_key) }; + + (*intr.get()).intern(@d.read_str()) +} + +type ident = token::str_num; // Functions may or may not have names. #[auto_serialize] @@ -127,9 +137,9 @@ type meta_item = spanned; #[auto_serialize] enum meta_item_ { - meta_word(ident), - meta_list(ident, ~[@meta_item]), - meta_name_value(ident, lit), + meta_word(~str), + meta_list(~str, ~[@meta_item]), + meta_name_value(~str, lit), } #[auto_serialize] @@ -815,36 +825,6 @@ enum inlined_item { ii_dtor(class_dtor, ident, ~[ty_param], def_id /* parent id */) } -// Convenience functions - -pure fn simple_path(id: ident, span: span) -> @path { - @{span: span, - global: false, - idents: ~[id], - rp: none, - types: ~[]} -} - -pure fn empty_span() -> span { - {lo: 0, hi: 0, expn_info: none} -} - -// Convenience implementations - -impl ident: ops::add { - pure fn add(&&id: ident) -> @path { - simple_path(self, empty_span()) + id - } -} - -impl @path: ops::add { - pure fn add(&&id: ident) -> @path { - @{ - idents: vec::append_one(self.idents, id) - with *self - } - } -} // // Local Variables: diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index 70aaa5e8be6..2cc8cb23f2e 100644 --- a/src/libsyntax/ast_map.rs +++ b/src/libsyntax/ast_map.rs @@ -4,31 +4,33 @@ import ast::*; import print::pprust; import ast_util::{path_to_ident, stmt_id}; import diagnostic::span_handler; +import parse::token::ident_interner; enum path_elt { path_mod(ident), path_name(ident) } type path = ~[path_elt]; /* FIXMEs that say "bad" are as per #2543 */ -fn path_to_str_with_sep(p: path, sep: ~str) -> ~str { +fn path_to_str_with_sep(p: path, sep: ~str, itr: ident_interner) -> ~str { let strs = do vec::map(p) |e| { match e { - path_mod(s) => /* FIXME (#2543) */ copy *s, - path_name(s) => /* FIXME (#2543) */ copy *s + path_mod(s) => *itr.get(s), + path_name(s) => *itr.get(s) } }; str::connect(strs, sep) } -fn path_ident_to_str(p: path, i: ident) -> ~str { +fn path_ident_to_str(p: path, i: ident, itr: ident_interner) -> ~str { if vec::is_empty(p) { - /* FIXME (#2543) */ copy *i + //FIXME /* FIXME (#2543) */ copy *i + *itr.get(i) } else { - fmt!{"%s::%s", path_to_str(p), *i} + fmt!{"%s::%s", path_to_str(p, itr), *itr.get(i)} } } -fn path_to_str(p: path) -> ~str { - path_to_str_with_sep(p, ~"::") +fn path_to_str(p: path, itr: ident_interner) -> ~str { + path_to_str_with_sep(p, ~"::", itr) } enum ast_node { @@ -291,43 +293,42 @@ fn map_stmt(stmt: @stmt, cx: ctx, v: vt) { visit::visit_stmt(stmt, cx, v); } -fn node_id_to_str(map: map, id: node_id) -> ~str { +fn node_id_to_str(map: map, id: node_id, itr: ident_interner) -> ~str { match map.find(id) { none => { fmt!{"unknown node (id=%d)", id} } some(node_item(item, path)) => { - fmt!{"item %s (id=%?)", path_ident_to_str(*path, item.ident), id} + fmt!{"item %s (id=%?)", path_ident_to_str(*path, item.ident, itr), id} } some(node_foreign_item(item, abi, path)) => { fmt!{"foreign item %s with abi %? (id=%?)", - path_ident_to_str(*path, item.ident), abi, id} + path_ident_to_str(*path, item.ident, itr), abi, id} } some(node_method(m, impl_did, path)) => { fmt!{"method %s in %s (id=%?)", - *m.ident, path_to_str(*path), id} + *itr.get(m.ident), path_to_str(*path, itr), id} } some(node_trait_method(tm, impl_did, path)) => { let m = ast_util::trait_method_to_ty_method(*tm); fmt!{"method %s in %s (id=%?)", - *m.ident, path_to_str(*path), id} + *itr.get(m.ident), path_to_str(*path, itr), id} } some(node_variant(variant, def_id, path)) => { fmt!{"variant %s in %s (id=%?)", - *variant.node.name, path_to_str(*path), id} + *itr.get(variant.node.name), path_to_str(*path, itr), id} } some(node_expr(expr)) => { - fmt!{"expr %s (id=%?)", - pprust::expr_to_str(expr), id} + fmt!{"expr %s (id=%?)", pprust::expr_to_str(expr, itr), id} } some(node_stmt(stmt)) => { fmt!{"stmt %s (id=%?)", - pprust::stmt_to_str(*stmt), id} + pprust::stmt_to_str(*stmt, itr), id} } // FIXMEs are as per #2410 some(node_export(_, path)) => { fmt!{"export %s (id=%?)", // add more info here - path_to_str(*path), id} + path_to_str(*path, itr), id} } some(node_arg(_, _)) => { // add more info here fmt!{"arg (id=%?)", id} diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index d949c546155..fe1924d1dbe 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -21,13 +21,14 @@ pure fn mk_sp(lo: uint, hi: uint) -> span { // make this a const, once the compiler supports it pure fn dummy_sp() -> span { return mk_sp(0u, 0u); } -pure fn path_name(p: @path) -> ~str { path_name_i(p.idents) } -pure fn path_name_i(idents: ~[ident]) -> ~str { + +pure fn path_name_i(idents: ~[ident], intr: token::ident_interner) -> ~str { // FIXME: Bad copies (#2543 -- same for everything else that says "bad") - str::connect(idents.map(|i|*i), ~"::") + str::connect(idents.map(|i| *intr.get(i)), ~"::") } + pure fn path_to_ident(p: @path) -> ident { vec::last(p.idents) } pure fn local_def(id: node_id) -> def_id { {crate: local_crate, node: id} } @@ -408,7 +409,8 @@ fn dtor_dec() -> fn_decl { let nil_t = @{id: 0, node: ty_nil, span: dummy_sp()}; // dtor has one argument, of type () {inputs: ~[{mode: ast::expl(ast::by_ref), - ty: nil_t, ident: @~"_", id: 0}], + ty: nil_t, ident: parse::token::special_idents::underscore, + id: 0}], output: nil_t, purity: impure_fn, cf: return_val} } diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 7c04d6e4570..71fc7f94e36 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -49,23 +49,23 @@ export require_unique_names; /* Constructors */ -fn mk_name_value_item_str(+name: ast::ident, +value: ~str) -> +fn mk_name_value_item_str(name: ~str, +value: ~str) -> @ast::meta_item { let value_lit = dummy_spanned(ast::lit_str(@value)); return mk_name_value_item(name, value_lit); } -fn mk_name_value_item(+name: ast::ident, +value: ast::lit) +fn mk_name_value_item(name: ~str, +value: ast::lit) -> @ast::meta_item { return @dummy_spanned(ast::meta_name_value(name, value)); } -fn mk_list_item(+name: ast::ident, +items: ~[@ast::meta_item]) -> +fn mk_list_item(name: ~str, +items: ~[@ast::meta_item]) -> @ast::meta_item { return @dummy_spanned(ast::meta_list(name, items)); } -fn mk_word_item(+name: ast::ident) -> @ast::meta_item { +fn mk_word_item(name: ~str) -> @ast::meta_item { return @dummy_spanned(ast::meta_word(name)); } @@ -78,7 +78,7 @@ fn mk_sugared_doc_attr(text: ~str, lo: uint, hi: uint) -> ast::attribute { let lit = spanned(lo, hi, ast::lit_str(@text)); let attr = { style: doc_comment_style(text), - value: spanned(lo, hi, ast::meta_name_value(@~"doc", lit)), + value: spanned(lo, hi, ast::meta_name_value(~"doc", lit)), is_sugared_doc: true }; return spanned(lo, hi, attr); @@ -98,8 +98,8 @@ fn attr_metas(attrs: ~[ast::attribute]) -> ~[@ast::meta_item] { fn desugar_doc_attr(attr: ast::attribute) -> ast::attribute { if attr.node.is_sugared_doc { let comment = get_meta_item_value_str(@attr.node.value).get(); - let meta = mk_name_value_item_str(@~"doc", - strip_doc_comment_decoration(*comment)); + let meta = mk_name_value_item_str(~"doc", + strip_doc_comment_decoration(comment)); return mk_attr(meta); } else { attr @@ -108,16 +108,15 @@ fn desugar_doc_attr(attr: ast::attribute) -> ast::attribute { /* Accessors */ -fn get_attr_name(attr: ast::attribute) -> ast::ident { +fn get_attr_name(attr: ast::attribute) -> ~str { get_meta_item_name(@attr.node.value) } -// All "bad" FIXME copies are as per #2543 -fn get_meta_item_name(meta: @ast::meta_item) -> ast::ident { +fn get_meta_item_name(meta: @ast::meta_item) -> ~str { match meta.node { - ast::meta_word(n) => /* FIXME (#2543) */ copy n, - ast::meta_name_value(n, _) => /* FIXME (#2543) */ copy n, - ast::meta_list(n, _) => /* FIXME (#2543) */ copy n + ast::meta_word(n) => n, + ast::meta_name_value(n, _) => n, + ast::meta_list(n, _) => n } } @@ -125,13 +124,13 @@ fn get_meta_item_name(meta: @ast::meta_item) -> ast::ident { * Gets the string value if the meta_item is a meta_name_value variant * containing a string, otherwise none */ -fn get_meta_item_value_str(meta: @ast::meta_item) -> option<@~str> { +fn get_meta_item_value_str(meta: @ast::meta_item) -> option<~str> { match meta.node { - ast::meta_name_value(_, v) => match v.node { - ast::lit_str(s) => option::some(s), + ast::meta_name_value(_, v) => match v.node { + ast::lit_str(s) => option::some(*s), + _ => option::none + }, _ => option::none - }, - _ => option::none } } @@ -147,9 +146,7 @@ fn get_meta_item_list(meta: @ast::meta_item) -> option<~[@ast::meta_item]> { * If the meta item is a nam-value type with a string value then returns * a tuple containing the name and string value, otherwise `none` */ -fn get_name_value_str_pair( - item: @ast::meta_item -) -> option<(ast::ident, @~str)> { +fn get_name_value_str_pair(item: @ast::meta_item) -> option<(~str, ~str)> { match attr::get_meta_item_value_str(item) { some(value) => { let name = attr::get_meta_item_name(item); @@ -163,11 +160,11 @@ fn get_name_value_str_pair( /* Searching */ /// Search a list of attributes and return only those with a specific name -fn find_attrs_by_name(attrs: ~[ast::attribute], +name: ~str) -> +fn find_attrs_by_name(attrs: ~[ast::attribute], name: ~str) -> ~[ast::attribute] { let filter = ( fn@(a: ast::attribute) -> option { - if *get_attr_name(a) == name { + if get_attr_name(a) == name { option::some(a) } else { option::none } } @@ -176,10 +173,10 @@ fn find_attrs_by_name(attrs: ~[ast::attribute], +name: ~str) -> } /// Searcha list of meta items and return only those with a specific name -fn find_meta_items_by_name(metas: ~[@ast::meta_item], +name: ~str) -> +fn find_meta_items_by_name(metas: ~[@ast::meta_item], name: ~str) -> ~[@ast::meta_item] { let filter = fn@(&&m: @ast::meta_item) -> option<@ast::meta_item> { - if *get_meta_item_name(m) == name { + if get_meta_item_name(m) == name { option::some(m) } else { option::none } }; @@ -191,14 +188,9 @@ fn find_meta_items_by_name(metas: ~[@ast::meta_item], +name: ~str) -> * comparison is performed structurally. */ fn contains(haystack: ~[@ast::meta_item], needle: @ast::meta_item) -> bool { - debug!{"looking for %s", - print::pprust::meta_item_to_str(*needle)}; for haystack.each |item| { - debug!{"looking in %s", - print::pprust::meta_item_to_str(*item)}; - if eq(item, needle) { debug!{"found it!"}; return true; } + if eq(item, needle) { return true; } } - #debug("found it not :("); return false; } @@ -223,17 +215,18 @@ fn eq(a: @ast::meta_item, b: @ast::meta_item) -> bool { } } -fn contains_name(metas: ~[@ast::meta_item], +name: ~str) -> bool { +fn contains_name(metas: ~[@ast::meta_item], name: ~str) -> bool { let matches = find_meta_items_by_name(metas, name); return vec::len(matches) > 0u; } -fn attrs_contains_name(attrs: ~[ast::attribute], +name: ~str) -> bool { +fn attrs_contains_name(attrs: ~[ast::attribute], name: ~str) -> bool { vec::is_not_empty(find_attrs_by_name(attrs, name)) } -fn first_attr_value_str_by_name(attrs: ~[ast::attribute], +name: ~str) - -> option<@~str> { +fn first_attr_value_str_by_name(attrs: ~[ast::attribute], name: ~str) + -> option<~str> { + let mattrs = find_attrs_by_name(attrs, name); if vec::len(mattrs) > 0u { return get_meta_item_value_str(attr_meta(mattrs[0])); @@ -241,18 +234,16 @@ fn first_attr_value_str_by_name(attrs: ~[ast::attribute], +name: ~str) return option::none; } -fn last_meta_item_by_name( - items: ~[@ast::meta_item], - +name: ~str -) -> option<@ast::meta_item> { +fn last_meta_item_by_name(items: ~[@ast::meta_item], name: ~str) + -> option<@ast::meta_item> { + let items = attr::find_meta_items_by_name(items, name); vec::last_opt(items) } -fn last_meta_item_value_str_by_name( - items: ~[@ast::meta_item], - +name: ~str -) -> option<@~str> { +fn last_meta_item_value_str_by_name(items: ~[@ast::meta_item], name: ~str) + -> option<~str> { + match last_meta_item_by_name(items, name) { some(item) => match attr::get_meta_item_value_str(item) { some(value) => some(value), @@ -262,10 +253,9 @@ fn last_meta_item_value_str_by_name( } } -fn last_meta_item_list_by_name( - items: ~[@ast::meta_item], - +name: ~str -) -> option<~[@ast::meta_item]> { +fn last_meta_item_list_by_name(items: ~[@ast::meta_item], name: ~str) + -> option<~[@ast::meta_item]> { + match last_meta_item_by_name(items, name) { some(item) => attr::get_meta_item_list(item), none => none @@ -279,11 +269,11 @@ fn last_meta_item_list_by_name( // the item name (See [Fixme-sorting]) fn sort_meta_items(+items: ~[@ast::meta_item]) -> ~[@ast::meta_item] { pure fn lteq(ma: &@ast::meta_item, mb: &@ast::meta_item) -> bool { - pure fn key(m: &ast::meta_item) -> ast::ident { + pure fn key(m: &ast::meta_item) -> ~str { match m.node { - ast::meta_word(name) => /* FIXME (#2543) */ copy name, - ast::meta_name_value(name, _) => /* FIXME (#2543) */ copy name, - ast::meta_list(name, _) => /* FIXME (#2543) */ copy name + ast::meta_word(name) => name, + ast::meta_name_value(name, _) => name, + ast::meta_list(name, _) => name } } key(*ma) <= key(*mb) @@ -295,7 +285,7 @@ fn sort_meta_items(+items: ~[@ast::meta_item]) -> ~[@ast::meta_item] { return vec::from_mut(v); } -fn remove_meta_items_by_name(items: ~[@ast::meta_item], name: ast::ident) -> +fn remove_meta_items_by_name(items: ~[@ast::meta_item], name: ~str) -> ~[@ast::meta_item] { return vec::filter_map(items, |item| { @@ -335,17 +325,17 @@ fn foreign_abi(attrs: ~[ast::attribute]) -> Either<~str, ast::foreign_abi> { option::none => { either::Right(ast::foreign_abi_cdecl) } - option::some(@~"rust-intrinsic") => { + option::some(~"rust-intrinsic") => { either::Right(ast::foreign_abi_rust_intrinsic) } - option::some(@~"cdecl") => { + option::some(~"cdecl") => { either::Right(ast::foreign_abi_cdecl) } - option::some(@~"stdcall") => { + option::some(~"stdcall") => { either::Right(ast::foreign_abi_stdcall) } option::some(t) => { - either::Left(~"unsupported abi: " + *t) + either::Left(~"unsupported abi: " + t) } }; } @@ -362,8 +352,8 @@ fn find_inline_attr(attrs: ~[ast::attribute]) -> inline_attr { // FIXME (#2809)---validate the usage of #[inline] and #[inline(always)] do vec::foldl(ia_none, attrs) |ia,attr| { match attr.node.value.node { - ast::meta_word(@~"inline") => ia_hint, - ast::meta_list(@~"inline", items) => { + ast::meta_word(~"inline") => ia_hint, + ast::meta_list(~"inline", items) => { if !vec::is_empty(find_meta_items_by_name(items, ~"always")) { ia_always } else if !vec::is_empty( @@ -386,11 +376,11 @@ fn require_unique_names(diagnostic: span_handler, let name = get_meta_item_name(meta); // FIXME: How do I silence the warnings? --pcw (#2619) - if map.contains_key(*name) { + if map.contains_key(name) { diagnostic.span_fatal(meta.span, - fmt!{"duplicate meta item `%s`", *name}); + fmt!{"duplicate meta item `%s`", name}); } - map.insert(*name, ()); + map.insert(name, ()); } } diff --git a/src/libsyntax/ext/auto_serialize.rs b/src/libsyntax/ext/auto_serialize.rs index 1fc77bae8bf..e5b65b41fc8 100644 --- a/src/libsyntax/ext/auto_serialize.rs +++ b/src/libsyntax/ext/auto_serialize.rs @@ -84,15 +84,15 @@ mod syntax { export parse; } -type ser_tps_map = map::hashmap<~str, fn@(@ast::expr) -> ~[@ast::stmt]>; -type deser_tps_map = map::hashmap<~str, fn@() -> @ast::expr>; +type ser_tps_map = map::hashmap ~[@ast::stmt]>; +type deser_tps_map = map::hashmap @ast::expr>; fn expand(cx: ext_ctxt, span: span, _mitem: ast::meta_item, in_items: ~[@ast::item]) -> ~[@ast::item] { fn not_auto_serialize(a: ast::attribute) -> bool { - attr::get_attr_name(a) != @~"auto_serialize" + attr::get_attr_name(a) != ~"auto_serialize" } fn filter_attrs(item: @ast::item) -> @ast::item { @@ -156,7 +156,11 @@ impl ext_ctxt: ext_ctxt_helpers { let head = vec::init(base_path.idents); let tail = vec::last(base_path.idents); self.path(base_path.span, - vec::append(head, ~[@(helper_name + ~"_" + *tail)])) + vec::append(head, + ~[self.parse_sess().interner. + intern(@(helper_name + ~"_" + + *self.parse_sess().interner.get( + tail)))])) } fn path(span: span, strs: ~[ast::ident]) -> @ast::path { @@ -181,7 +185,7 @@ impl ext_ctxt: ext_ctxt_helpers { let args = do vec::map(input_tys) |ty| { {mode: ast::expl(ast::by_ref), ty: ty, - ident: @~"", + ident: parse::token::special_idents::invalid, id: self.next_id()} }; @@ -352,7 +356,7 @@ fn ser_variant(cx: ext_ctxt, argfn: fn(-@ast::expr, uint, ast::blk) -> @ast::expr) -> ast::arm { let vnames = do vec::from_fn(vec::len(tys)) |i| { - @fmt!{"__v%u", i} + cx.parse_sess().interner.intern(@fmt!{"__v%u", i}) }; let pats = do vec::from_fn(vec::len(tys)) |i| { cx.binder_pat(tys[i].span, vnames[i]) @@ -384,7 +388,7 @@ fn is_vec_or_str(ty: @ast::ty) -> bool { // This may be wrong if the user has shadowed (!) str ast::ty_path(@{span: _, global: _, idents: ids, rp: none, types: _}, _) - if ids == ~[@~"str"] => true, + if ids == ~[parse::token::special_idents::str] => true, _ => false } } @@ -434,7 +438,8 @@ fn ser_ty(cx: ext_ctxt, tps: ser_tps_map, fld.node.ident, ~[])); let s = cx.clone(s); - let f = cx.lit_str(fld.span, fld.node.ident); + let f = cx.lit_str(fld.span, cx.parse_sess().interner.get( + fld.node.ident)); let i = cx.lit_uint(fld.span, fidx); let l = ser_lambda(cx, tps, fld.node.mt.ty, cx.clone(s), vf); #ast[stmt]{$(s).emit_rec_field($(f), $(i), $(l));} @@ -487,7 +492,7 @@ fn ser_ty(cx: ext_ctxt, tps: ser_tps_map, vec::is_empty(path.types) { let ident = path.idents[0]; - match tps.find(*ident) { + match tps.find(ident) { some(f) => f(v), none => ser_path(cx, tps, path, s, v) } @@ -545,7 +550,7 @@ fn mk_ser_fn(cx: ext_ctxt, span: span, name: ast::ident, ty: cx.ty_fn(span, ~[cx.ty_path(span, ~[tp.ident], ~[])], cx.ty_nil(span)), - ident: @(~"__s" + *tp.ident), + ident: cx.ident_of(~"__s" + cx.str_of(tp.ident)), id: cx.next_id()}); debug!{"tp_inputs = %?", tp_inputs}; @@ -553,35 +558,36 @@ fn mk_ser_fn(cx: ext_ctxt, span: span, name: ast::ident, let ser_inputs: ~[ast::arg] = vec::append(~[{mode: ast::expl(ast::by_ref), - ty: cx.ty_path(span, ~[@~"__S"], ~[]), - ident: @~"__s", + ty: cx.ty_path(span, ~[cx.ident_of(~"__S")], ~[]), + ident: cx.ident_of(~"__s"), id: cx.next_id()}, {mode: ast::expl(ast::by_ref), ty: v_ty, - ident: @~"__v", + ident: cx.ident_of(~"__v"), id: cx.next_id()}], tp_inputs); - let tps_map = map::str_hash(); + let tps_map = map::uint_hash(); do vec::iter2(tps, tp_inputs) |tp, arg| { let arg_ident = arg.ident; tps_map.insert( - *tp.ident, + tp.ident, fn@(v: @ast::expr) -> ~[@ast::stmt] { let f = cx.var_ref(span, arg_ident); - debug!{"serializing type arg %s", *arg_ident}; + debug!{"serializing type arg %s", cx.str_of(arg_ident)}; ~[#ast[stmt]{$(f)($(v));}] }); } let ser_bnds = @~[ ast::bound_trait(cx.ty_path(span, - ~[@~"std", @~"serialization", - @~"serializer"], + ~[cx.ident_of(~"std"), + cx.ident_of(~"serialization"), + cx.ident_of(~"serializer")], ~[]))]; let ser_tps: ~[ast::ty_param] = - vec::append(~[{ident: @~"__S", + vec::append(~[{ident: cx.ident_of(~"__S"), id: cx.next_id(), bounds: ser_bnds}], vec::map(tps, |tp| cx.clone_ty_param(tp))); @@ -593,7 +599,7 @@ fn mk_ser_fn(cx: ext_ctxt, span: span, name: ast::ident, let ser_blk = cx.blk(span, f(cx, tps_map, #ast{ __s }, #ast{ __v })); - @{ident: @(~"serialize_" + *name), + @{ident: cx.ident_of(~"serialize_" + cx.str_of(name)), attrs: ~[], id: cx.next_id(), node: ast::item_fn({inputs: ser_inputs, @@ -670,7 +676,7 @@ fn deser_ty(cx: ext_ctxt, tps: deser_tps_map, let fields = do vec::from_fn(vec::len(flds)) |fidx| { let fld = flds[fidx]; let d = cx.clone(d); - let f = cx.lit_str(fld.span, fld.node.ident); + let f = cx.lit_str(fld.span, @cx.str_of(fld.node.ident)); let i = cx.lit_uint(fld.span, fidx); let l = deser_lambda(cx, tps, fld.node.mt.ty, cx.clone(d)); {node: {mutbl: fld.node.mt.mutbl, @@ -713,7 +719,7 @@ fn deser_ty(cx: ext_ctxt, tps: deser_tps_map, vec::is_empty(path.types) { let ident = path.idents[0]; - match tps.find(*ident) { + match tps.find(ident) { some(f) => f(), none => deser_path(cx, tps, path, d) } @@ -756,23 +762,23 @@ fn mk_deser_fn(cx: ext_ctxt, span: span, ty: cx.ty_fn(span, ~[], cx.ty_path(span, ~[tp.ident], ~[])), - ident: @(~"__d" + *tp.ident), + ident: cx.ident_of(~"__d" + cx.str_of(tp.ident)), id: cx.next_id()}); debug!{"tp_inputs = %?", tp_inputs}; let deser_inputs: ~[ast::arg] = vec::append(~[{mode: ast::expl(ast::by_ref), - ty: cx.ty_path(span, ~[@~"__D"], ~[]), - ident: @~"__d", + ty: cx.ty_path(span, ~[cx.ident_of(~"__D")], ~[]), + ident: cx.ident_of(~"__d"), id: cx.next_id()}], tp_inputs); - let tps_map = map::str_hash(); + let tps_map = map::uint_hash(); do vec::iter2(tps, tp_inputs) |tp, arg| { let arg_ident = arg.ident; tps_map.insert( - *tp.ident, + tp.ident, fn@() -> @ast::expr { let f = cx.var_ref(span, arg_ident); #ast{ $(f)() } @@ -782,11 +788,12 @@ fn mk_deser_fn(cx: ext_ctxt, span: span, let deser_bnds = @~[ ast::bound_trait(cx.ty_path( span, - ~[@~"std", @~"serialization", @~"deserializer"], + ~[cx.ident_of(~"std"), cx.ident_of(~"serialization"), + cx.ident_of(~"deserializer")], ~[]))]; let deser_tps: ~[ast::ty_param] = - vec::append(~[{ident: @~"__D", + vec::append(~[{ident: cx.ident_of(~"__D"), id: cx.next_id(), bounds: deser_bnds}], vec::map(tps, |tp| { @@ -798,7 +805,7 @@ fn mk_deser_fn(cx: ext_ctxt, span: span, let deser_blk = cx.expr_blk(f(cx, tps_map, #ast[expr]{__d})); - @{ident: @(~"deserialize_" + *name), + @{ident: cx.ident_of(~"deserialize_" + cx.str_of(name)), attrs: ~[], id: cx.next_id(), node: ast::item_fn({inputs: deser_inputs, @@ -853,7 +860,7 @@ fn ser_enum(cx: ext_ctxt, tps: ser_tps_map, e_name: ast::ident, // Generate body s.emit_enum_variant("foo", 0u, // 3u, {|| blk }) |-s, blk| { - let v_name = cx.lit_str(v_span, v_name); + let v_name = cx.lit_str(v_span, @cx.str_of(v_name)); let v_id = cx.lit_uint(v_span, vidx); let sz = cx.lit_uint(v_span, vec::len(variant_tys)); let body = cx.lambda(blk); @@ -877,7 +884,7 @@ fn ser_enum(cx: ext_ctxt, tps: ser_tps_map, e_name: ast::ident, } }; let lam = cx.lambda(cx.blk(e_span, ~[cx.alt_stmt(arms, e_span, v)])); - let e_name = cx.lit_str(e_span, e_name); + let e_name = cx.lit_str(e_span, @cx.str_of(e_name)); ~[#ast[stmt]{ $(s).emit_enum($(e_name), $(lam)) }] } @@ -935,7 +942,7 @@ fn deser_enum(cx: ext_ctxt, tps: deser_tps_map, e_name: ast::ident, arms += ~[impossible_case]; // Generate code like: - let e_name = cx.lit_str(e_span, e_name); + let e_name = cx.lit_str(e_span, @cx.str_of(e_name)); let alt_expr = cx.expr(e_span, ast::expr_match(#ast{__i}, arms, ast::alt_exhaustive)); let var_lambda = #ast{ |__i| $(alt_expr) }; diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index b8c036f5724..bb8a845d731 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -23,7 +23,7 @@ type syntax_expander_ = // second argument is the origin of the macro, if user-defined type syntax_expander = {expander: syntax_expander_, span: option}; -type macro_def = {ident: ast::ident, ext: syntax_extension}; +type macro_def = {name: ~str, ext: syntax_extension}; // macro_definer is obsolete, remove when #old_macros go away. type macro_definer = @@ -141,6 +141,9 @@ trait ext_ctxt { fn next_id() -> ast::node_id; pure fn trace_macros() -> bool; fn set_trace_macros(x: bool); + /* for unhygienic identifier transformation */ + fn str_of(id: ast::ident) -> ~str; + fn ident_of(st: ~str) -> ast::ident; } fn mk_ctxt(parse_sess: parse::parse_sess, @@ -211,6 +214,13 @@ fn mk_ctxt(parse_sess: parse::parse_sess, fn set_trace_macros(x: bool) { self.trace_mac = x } + + fn str_of(id: ast::ident) -> ~str { + *self.parse_sess.interner.get(id) + } + fn ident_of(st: ~str) -> ast::ident { + self.parse_sess.interner.intern(@st) + } } let imp : ctxt_repr = { parse_sess: parse_sess, @@ -264,12 +274,12 @@ fn get_mac_args(cx: ext_ctxt, sp: span, arg: ast::mac_arg, cx.span_fatal(sp, fmt!{"#%s needs at least %u arguments.", name, min}); } - _ => return elts /* we're good */ + _ => return elts /* we are good */ } } _ => { cx.span_fatal(sp, fmt!{"#%s: malformed invocation", name}) - } + } }, none => cx.span_fatal(sp, fmt!{"#%s: missing arguments", name}) } @@ -298,22 +308,24 @@ fn tt_args_to_original_flavor(cx: ext_ctxt, sp: span, arg: ~[ast::token_tree]) fn ms(m: matcher_) -> matcher { {node: m, span: {lo: 0u, hi: 0u, expn_info: none}} } + let arg_nm = cx.parse_sess().interner.gensym(@~"arg"); let argument_gram = ~[ms(match_seq(~[ - ms(match_nonterminal(@~"arg",@~"expr", 0u)) + ms(match_nonterminal(arg_nm, parse::token::special_idents::expr, 0u)) ], some(parse::token::COMMA), true, 0u, 1u))]; let arg_reader = new_tt_reader(cx.parse_sess().span_diagnostic, cx.parse_sess().interner, none, arg); let args = match parse_or_else(cx.parse_sess(), cx.cfg(), arg_reader as reader, - argument_gram).get(@~"arg") { - @matched_seq(s, _) => do s.map() |lf| { - match lf { - @matched_nonterminal(parse::token::nt_expr(arg)) => { - arg /* whew! list of exprs, here we come! */ - } - _ => fail ~"badly-structured parse result" + argument_gram).get(arg_nm) { + @matched_seq(s, _) => { + do s.map() |lf| { + match lf { + @matched_nonterminal(parse::token::nt_expr(arg)) => + arg, /* whew! list of exprs, here we come! */ + _ => fail ~"badly-structured parse result" + } } }, _ => fail ~"badly-structured parse result" diff --git a/src/libsyntax/ext/concat_idents.rs b/src/libsyntax/ext/concat_idents.rs index f5d22e6754c..b53a0439e59 100644 --- a/src/libsyntax/ext/concat_idents.rs +++ b/src/libsyntax/ext/concat_idents.rs @@ -3,14 +3,16 @@ import base::*; fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg, _body: ast::mac_body) -> @ast::expr { let args = get_mac_args_no_max(cx,sp,arg,1u,~"concat_idents"); - let mut res = ~""; + let mut res_str = ~""; for args.each |e| { - res += *expr_to_ident(cx, e, ~"expected an ident"); + res_str += *cx.parse_sess().interner.get( + expr_to_ident(cx, e, ~"expected an ident")); } + let res = cx.parse_sess().interner.intern(@res_str); return @{id: cx.next_id(), callee_id: cx.next_id(), - node: ast::expr_path(@{span: sp, global: false, idents: ~[@res], + node: ast::expr_path(@{span: sp, global: false, idents: ~[res], rp: none, types: ~[]}), span: sp}; } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 9b50101683a..fb083744321 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -25,7 +25,9 @@ fn expand_expr(exts: hashmap<~str, syntax_extension>, cx: ext_ctxt, match mac.node { mac_invoc(pth, args, body) => { assert (vec::len(pth.idents) > 0u); - let extname = pth.idents[0]; + /* using idents and token::special_idents would make the + the macro names be hygienic */ + let extname = cx.parse_sess().interner.get(pth.idents[0]); match exts.find(*extname) { none => { cx.span_fatal(pth.span, @@ -49,7 +51,7 @@ fn expand_expr(exts: hashmap<~str, syntax_extension>, cx: ext_ctxt, } some(macro_defining(ext)) => { let named_extension = ext(cx, mac.span, args, body); - exts.insert(*named_extension.ident, named_extension.ext); + exts.insert(named_extension.name, named_extension.ext); (ast::expr_rec(~[], none), s) } some(expr_tt(_)) => { @@ -68,7 +70,9 @@ fn expand_expr(exts: hashmap<~str, syntax_extension>, cx: ext_ctxt, // finished transitioning. mac_invoc_tt(pth, tts) => { assert (vec::len(pth.idents) == 1u); - let extname = pth.idents[0]; + /* using idents and token::special_idents would make the + the macro names be hygienic */ + let extname = cx.parse_sess().interner.get(pth.idents[0]); match exts.find(*extname) { none => { cx.span_fatal(pth.span, @@ -146,7 +150,7 @@ fn expand_mod_items(exts: hashmap<~str, syntax_extension>, cx: ext_ctxt, ast::meta_name_value(n, _) => n, ast::meta_list(n, _) => n }; - match exts.find(*mname) { + match exts.find(mname) { none | some(normal(_)) | some(macro_defining(_)) | some(expr_tt(_)) | some(item_tt(*)) => items, some(item_decorator(dec_fn)) => { @@ -194,7 +198,7 @@ fn expand_item_mac(exts: hashmap<~str, syntax_extension>, fld: ast_fold) -> option<@ast::item> { match it.node { item_mac({node: mac_invoc_tt(pth, tts), span}) => { - let extname = pth.idents[0]; + let extname = cx.parse_sess().interner.get(pth.idents[0]); match exts.find(*extname) { none => { cx.span_fatal(pth.span, @@ -211,7 +215,7 @@ fn expand_item_mac(exts: hashmap<~str, syntax_extension>, ~"expr macro in item position: " + *extname), mr_def(mdef) => { - exts.insert(*mdef.ident, mdef.ext); + exts.insert(mdef.name, mdef.ext); none } }; diff --git a/src/libsyntax/ext/fmt.rs b/src/libsyntax/ext/fmt.rs index f8966196749..9392ea5ad3c 100644 --- a/src/libsyntax/ext/fmt.rs +++ b/src/libsyntax/ext/fmt.rs @@ -37,12 +37,13 @@ fn expand_syntax_ext(cx: ext_ctxt, sp: span, arg: ast::mac_arg, fn pieces_to_expr(cx: ext_ctxt, sp: span, pieces: ~[piece], args: ~[@ast::expr]) -> @ast::expr { - fn make_path_vec(_cx: ext_ctxt, ident: ast::ident) -> ~[ast::ident] { - return ~[@~"extfmt", @~"rt", ident]; + fn make_path_vec(_cx: ext_ctxt, ident: @~str) -> ~[ast::ident] { + let intr = _cx.parse_sess().interner; + return ~[intr.intern(@~"extfmt"), intr.intern(@~"rt"), + intr.intern(ident)]; } - fn make_rt_path_expr(cx: ext_ctxt, sp: span, - ident: ast::ident) -> @ast::expr { - let path = make_path_vec(cx, ident); + fn make_rt_path_expr(cx: ext_ctxt, sp: span, nm: @~str) -> @ast::expr { + let path = make_path_vec(cx, nm); return mk_path(cx, sp, path); } // Produces an AST expression that represents a RT::conv record, @@ -94,11 +95,13 @@ fn pieces_to_expr(cx: ext_ctxt, sp: span, fn make_conv_rec(cx: ext_ctxt, sp: span, flags_expr: @ast::expr, width_expr: @ast::expr, precision_expr: @ast::expr, ty_expr: @ast::expr) -> @ast::expr { + let intr = cx.parse_sess().interner; return mk_rec_e(cx, sp, - ~[{ident: @~"flags", ex: flags_expr}, - {ident: @~"width", ex: width_expr}, - {ident: @~"precision", ex: precision_expr}, - {ident: @~"ty", ex: ty_expr}]); + ~[{ident: intr.intern(@~"flags"), ex: flags_expr}, + {ident: intr.intern(@~"width"), ex: width_expr}, + {ident: intr.intern(@~"precision"), + ex: precision_expr}, + {ident: intr.intern(@~"ty"), ex: ty_expr}]); } let rt_conv_flags = make_flags(cx, sp, cnv.flags); let rt_conv_width = make_count(cx, sp, cnv.width); @@ -268,7 +271,10 @@ fn pieces_to_expr(cx: ext_ctxt, sp: span, } let arg_vec = mk_fixed_vec_e(cx, fmt_sp, piece_exprs); - return mk_call(cx, fmt_sp, ~[@~"str", @~"concat"], ~[arg_vec]); + return mk_call(cx, fmt_sp, + ~[cx.parse_sess().interner.intern(@~"str"), + cx.parse_sess().interner.intern(@~"concat")], + ~[arg_vec]); } // // Local Variables: diff --git a/src/libsyntax/ext/ident_to_str.rs b/src/libsyntax/ext/ident_to_str.rs index 06faff9ee1b..9daaf164562 100644 --- a/src/libsyntax/ext/ident_to_str.rs +++ b/src/libsyntax/ext/ident_to_str.rs @@ -6,6 +6,6 @@ fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg, _body: ast::mac_body) -> @ast::expr { let args = get_mac_args(cx,sp,arg,1u,option::some(1u),~"ident_to_str"); - return mk_uniq_str(cx, sp, *expr_to_ident(cx, args[0u], - ~"expected an ident")); + return mk_uniq_str(cx, sp, *cx.parse_sess().interner.get( + expr_to_ident(cx, args[0u], ~"expected an ident"))); } diff --git a/src/libsyntax/ext/log_syntax.rs b/src/libsyntax/ext/log_syntax.rs index 4ab3bb29045..61bb00fd6de 100644 --- a/src/libsyntax/ext/log_syntax.rs +++ b/src/libsyntax/ext/log_syntax.rs @@ -6,8 +6,7 @@ fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, tt: ~[ast::token_tree]) cx.print_backtrace(); io::stdout().write_line( - print::pprust::unexpanded_tt_to_str(ast::tt_delim(tt), - cx.parse_sess().interner)); + print::pprust::tt_to_str(ast::tt_delim(tt),cx.parse_sess().interner)); //trivial expression return mr_expr(@{id: cx.next_id(), callee_id: cx.next_id(), diff --git a/src/libsyntax/ext/pipes.rs b/src/libsyntax/ext/pipes.rs index b9ff13c9578..beda46a2c3b 100644 --- a/src/libsyntax/ext/pipes.rs +++ b/src/libsyntax/ext/pipes.rs @@ -54,7 +54,7 @@ fn expand_proto(cx: ext_ctxt, _sp: span, id: ast::ident, let rdr = tt_rdr as reader; let rust_parser = parser(sess, cfg, rdr.dup(), SOURCE_FILE); - let proto = rust_parser.parse_proto(id); + let proto = rust_parser.parse_proto(cx.str_of(id)); // check for errors visit(proto, cx); diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs index 39132fd0d59..45873f81dea 100644 --- a/src/libsyntax/ext/pipes/ast_builder.rs +++ b/src/libsyntax/ext/pipes/ast_builder.rs @@ -15,14 +15,10 @@ mod syntax { export parse; } -fn ident(s: &str) -> ast::ident { - @(s.to_unique()) -} - -fn path(id: ident, span: span) -> @ast::path { +fn path(ids: ~[ident], span: span) -> @ast::path { @{span: span, global: false, - idents: ~[id], + idents: ids, rp: none, types: ~[]} } @@ -94,7 +90,8 @@ trait ext_ctxt_ast_builder { impl ext_ctxt: ext_ctxt_ast_builder { fn ty_option(ty: @ast::ty) -> @ast::ty { - self.ty_path_ast_builder(path(@~"option", self.empty_span()) + self.ty_path_ast_builder(path(~[self.ident_of(~"option")], + self.empty_span()) .add_ty(ty)) } @@ -126,7 +123,7 @@ impl ext_ctxt: ext_ctxt_ast_builder { ty: self.ty_infer(), pat: @{id: self.next_id(), node: ast::pat_ident(ast::bind_by_implicit_ref, - path(ident, + path(~[ident], self.empty_span()), none), span: self.empty_span()}, @@ -301,6 +298,6 @@ impl ext_ctxt: ext_ctxt_ast_builder { fn ty_vars(+ty_params: ~[ast::ty_param]) -> ~[@ast::ty] { ty_params.map(|p| self.ty_path_ast_builder( - path(p.ident, self.empty_span()))) + path(~[p.ident], self.empty_span()))) } } diff --git a/src/libsyntax/ext/pipes/check.rs b/src/libsyntax/ext/pipes/check.rs index e286b4f76be..b7ad5c21bd9 100644 --- a/src/libsyntax/ext/pipes/check.rs +++ b/src/libsyntax/ext/pipes/check.rs @@ -21,8 +21,6 @@ that. import ext::base::ext_ctxt; -import ast::{ident}; - import proto::{state, protocol, next_state}; import ast_builder::empty_span; @@ -36,11 +34,11 @@ impl ext_ctxt: proto::visitor<(), (), ()> { state.span, // use a real span! fmt!{"state %s contains no messages, \ consider stepping to a terminal state instead", - *state.name}) + state.name}) } } - fn visit_message(name: ident, _span: span, _tys: &[@ast::ty], + fn visit_message(name: ~str, _span: span, _tys: &[@ast::ty], this: state, next: next_state) { match next { some({state: next, tys: next_tys}) => { @@ -51,7 +49,7 @@ impl ext_ctxt: proto::visitor<(), (), ()> { self.span_err( proto.get_state(next).span, fmt!{"message %s steps to undefined state, %s", - *name, *next}); + name, next}); } else { let next = proto.get_state(next); @@ -61,7 +59,7 @@ impl ext_ctxt: proto::visitor<(), (), ()> { next.span, // use a real span fmt!{"message %s target (%s) \ needs %u type parameters, but got %u", - *name, *next.name, + name, next.name, next.ty_params.len(), next_tys.len()}); } diff --git a/src/libsyntax/ext/pipes/liveness.rs b/src/libsyntax/ext/pipes/liveness.rs index 17e569552a7..2325e4ed27d 100644 --- a/src/libsyntax/ext/pipes/liveness.rs +++ b/src/libsyntax/ext/pipes/liveness.rs @@ -70,10 +70,10 @@ fn analyze(proto: protocol, _cx: ext_ctxt) { } if self_live.len() > 0 { - let states = str::connect(self_live.map(|s| *s.name), ~" "); + let states = str::connect(self_live.map(|s| s.name), ~" "); debug!{"protocol %s is unbounded due to loops involving: %s", - *proto.name, states}; + proto.name, states}; // Someday this will be configurable with a warning //cx.span_warn(empty_span(), @@ -85,7 +85,7 @@ fn analyze(proto: protocol, _cx: ext_ctxt) { proto.bounded = some(false); } else { - debug!{"protocol %s is bounded. yay!", *proto.name}; + debug!{"protocol %s is bounded. yay!", proto.name}; proto.bounded = some(true); } } \ No newline at end of file diff --git a/src/libsyntax/ext/pipes/parse_proto.rs b/src/libsyntax/ext/pipes/parse_proto.rs index 84180ff3797..4dc61e54aa4 100644 --- a/src/libsyntax/ext/pipes/parse_proto.rs +++ b/src/libsyntax/ext/pipes/parse_proto.rs @@ -1,18 +1,17 @@ // Parsing pipes protocols from token trees. import parse::parser; -import ast::ident; import parse::token; import pipec::*; trait proto_parser { - fn parse_proto(id: ident) -> protocol; + fn parse_proto(id: ~str) -> protocol; fn parse_state(proto: protocol); } impl parser: proto_parser { - fn parse_proto(id: ident) -> protocol { + fn parse_proto(id: ~str) -> protocol { let proto = protocol(id, self.span); self.parse_seq_to_before_end(token::EOF, @@ -24,9 +23,11 @@ impl parser: proto_parser { fn parse_state(proto: protocol) { let id = self.parse_ident(); + let name = *self.interner.get(id); + self.expect(token::COLON); let dir = match copy self.token { - token::IDENT(n, _) => self.get_str(n), + token::IDENT(n, _) => self.interner.get(n), _ => fail }; self.bump(); @@ -41,7 +42,7 @@ impl parser: proto_parser { } else { ~[] }; - let state = proto.add_state_poly(id, dir, typarms); + let state = proto.add_state_poly(name, id, dir, typarms); // parse the messages self.parse_unspanned_seq( @@ -51,7 +52,7 @@ impl parser: proto_parser { } fn parse_message(state: state) { - let mname = self.parse_ident(); + let mname = *self.interner.get(self.parse_ident()); let args = if self.token == token::LPAREN { self.parse_unspanned_seq(token::LPAREN, @@ -66,7 +67,7 @@ impl parser: proto_parser { let next = match copy self.token { token::IDENT(_, _) => { - let name = self.parse_ident(); + let name = *self.interner.get(self.parse_ident()); let ntys = if self.token == token::LT { self.parse_unspanned_seq(token::LT, token::GT, diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs index f7f2981f066..b5a1ae588a7 100644 --- a/src/libsyntax/ext/pipes/pipec.rs +++ b/src/libsyntax/ext/pipes/pipec.rs @@ -13,8 +13,7 @@ import parse; import parse::*; import proto::*; -import ast_builder::append_types; -import ast_builder::path; +import ast_builder::{append_types, path, empty_span}; // Transitional reexports so qquote can find the paths it is looking for mod syntax { @@ -47,17 +46,17 @@ impl message: gen_send { debug!("pipec: next state exists"); let next = this.proto.get_state(next); assert next_tys.len() == next.ty_params.len(); - let arg_names = tys.mapi(|i, _ty| @(~"x_" + i.to_str())); + let arg_names = tys.mapi(|i, _ty| cx.ident_of(~"x_"+i.to_str())); let args_ast = (arg_names, tys).map( |n, t| cx.arg_mode(n, t, ast::by_copy) ); let pipe_ty = cx.ty_path_ast_builder( - path(this.data_name(), span) + path(~[this.data_name()], span) .add_tys(cx.ty_vars(this.ty_params))); let args_ast = vec::append( - ~[cx.arg_mode(@~"pipe", + ~[cx.arg_mode(cx.ident_of(~"pipe"), pipe_ty, ast::by_copy)], args_ast); @@ -75,10 +74,10 @@ impl message: gen_send { body += ~"let b = pipe.reuse_buffer();\n"; body += fmt!("let %s = pipes::send_packet_buffered(\ ptr::addr_of(b.buffer.data.%s));\n", - sp, *next.name); - body += fmt!("let %s = pipes::recv_packet_buffered(\ + sp, next.name); + body += fmt!{"let %s = pipes::recv_packet_buffered(\ ptr::addr_of(b.buffer.data.%s));\n", - rp, *next.name); + rp, next.name}; } else { let pat = match (this.dir, next.dir) { @@ -91,10 +90,10 @@ impl message: gen_send { body += fmt!("let %s = pipes::entangle();\n", pat); } body += fmt!("let message = %s::%s(%s);\n", - *this.proto.name, - *self.name(), - str::connect(vec::append_one(arg_names, @~"s") - .map(|x| *x), + this.proto.name, + self.name(), + str::connect(vec::append_one( + arg_names.map(|x| cx.str_of(x)), ~"s"), ~", ")); if !try { @@ -110,17 +109,15 @@ impl message: gen_send { let body = cx.parse_expr(body); - let mut rty = cx.ty_path_ast_builder(path(next.data_name(), + let mut rty = cx.ty_path_ast_builder(path(~[next.data_name()], span) .add_tys(next_tys)); if try { rty = cx.ty_option(rty); } - let name = if try { - @(~"try_" + *self.name()) - } - else { self.name() }; + let name = cx.ident_of(if try { ~"try_" + self.name() + } else { self.name() } ); cx.item_fn_poly(name, args_ast, @@ -131,16 +128,16 @@ impl message: gen_send { message(id, span, tys, this, none) => { debug!{"pipec: no next state"}; - let arg_names = tys.mapi(|i, _ty| @(~"x_" + i.to_str())); + let arg_names = tys.mapi(|i, _ty| (~"x_" + i.to_str())); let args_ast = (arg_names, tys).map( - |n, t| cx.arg_mode(n, t, ast::by_copy) + |n, t| cx.arg_mode(cx.ident_of(n), t, ast::by_copy) ); let args_ast = vec::append( - ~[cx.arg_mode(@~"pipe", + ~[cx.arg_mode(cx.ident_of(~"pipe"), cx.ty_path_ast_builder( - path(this.data_name(), span) + path(~[this.data_name()], span) .add_tys(cx.ty_vars(this.ty_params))), ast::by_copy)], args_ast); @@ -149,13 +146,13 @@ impl message: gen_send { ~"" } else { - ~"(" + str::connect(arg_names.map(|x| *x), ~", ") + ~")" + ~"(" + str::connect(arg_names, ~", ") + ~")" }; let mut body = ~"{ "; body += fmt!{"let message = %s::%s%s;\n", - *this.proto.name, - *self.name(), + this.proto.name, + self.name(), message_args}; if !try { @@ -170,11 +167,11 @@ impl message: gen_send { let body = cx.parse_expr(body); let name = if try { - @(~"try_" + *self.name()) + ~"try_" + self.name() } else { self.name() }; - cx.item_fn_poly(name, + cx.item_fn_poly(cx.ident_of(name), args_ast, if try { cx.ty_option(cx.ty_nil_ast_builder()) @@ -188,7 +185,7 @@ impl message: gen_send { } fn to_ty(cx: ext_ctxt) -> @ast::ty { - cx.ty_path_ast_builder(path(self.name(), self.span()) + cx.ty_path_ast_builder(path(~[cx.ident_of(self.name())], self.span()) .add_tys(cx.ty_vars(self.get_params()))) } } @@ -212,21 +209,23 @@ impl state: to_type_decls { let tys = match next { some({state: next, tys: next_tys}) => { let next = this.proto.get_state(next); - let next_name = next.data_name(); + let next_name = cx.str_of(next.data_name()); let dir = match this.dir { - send => @~"server", - recv => @~"client" + send => ~"server", + recv => ~"client" }; vec::append_one(tys, - cx.ty_path_ast_builder((dir + next_name) - .add_tys(next_tys))) + cx.ty_path_ast_builder( + path(~[cx.ident_of(dir), + cx.ident_of(next_name)], span) + .add_tys(next_tys))) } none => tys }; - let v = cx.variant(name, span, tys); + let v = cx.variant(cx.ident_of(name), span, tys); vec::push(items_msg, v); } @@ -258,9 +257,13 @@ impl state: to_type_decls { self.data_name(), self.span, cx.ty_path_ast_builder( - (@~"pipes" + @(dir.to_str() + ~"_packet")) + path(~[cx.ident_of(~"pipes"), + cx.ident_of(dir.to_str() + ~"_packet")], + empty_span()) .add_ty(cx.ty_path_ast_builder( - (self.proto.name + self.data_name()) + path(~[cx.ident_of(self.proto.name), + self.data_name()], + empty_span()) .add_tys(cx.ty_vars(self.ty_params))))), self.ty_params)); } @@ -270,10 +273,14 @@ impl state: to_type_decls { self.data_name(), self.span, cx.ty_path_ast_builder( - (@~"pipes" + @(dir.to_str() - + ~"_packet_buffered")) + path(~[cx.ident_of(~"pipes"), + cx.ident_of(dir.to_str() + + ~"_packet_buffered")], + empty_span()) .add_tys(~[cx.ty_path_ast_builder( - (self.proto.name + self.data_name()) + path(~[cx.ident_of(self.proto.name), + self.data_name()], + empty_span()) .add_tys(cx.ty_vars(self.ty_params))), self.proto.buffer_ty_path(cx)])), self.ty_params)); @@ -315,16 +322,17 @@ impl protocol: gen_init { cx.parse_item(fmt!{"fn init%s() -> (client::%s, server::%s)\ { import pipes::has_buffer; %s }", - start_state.ty_params.to_source(), - start_state.to_ty(cx).to_source(), - start_state.to_ty(cx).to_source(), - body.to_source()}) + start_state.ty_params.to_source(cx), + start_state.to_ty(cx).to_source(cx), + start_state.to_ty(cx).to_source(cx), + body.to_source(cx)}) } fn gen_buffer_init(ext_cx: ext_ctxt) -> @ast::expr { ext_cx.rec(self.states.map_to_vec(|s| { let fty = s.to_ty(ext_cx); - ext_cx.field_imm(s.name, #ast { pipes::mk_packet::<$(fty)>() }) + ext_cx.field_imm(ext_cx.ident_of(s.name), + #ast { pipes::mk_packet::<$(fty)>() }) })) } @@ -341,9 +349,11 @@ impl protocol: gen_init { ext_cx.block( self.states.map_to_vec( |s| ext_cx.parse_stmt( - fmt!{"data.%s.set_buffer(buffer)", *s.name})), + fmt!{"data.%s.set_buffer(buffer)", + s.name})), ext_cx.parse_expr( - fmt!{"ptr::addr_of(data.%s)", *self.states[0].name}))); + fmt!{"ptr::addr_of(data.%s)", + self.states[0].name}))); #ast {{ let buffer = $(buffer); @@ -357,14 +367,14 @@ impl protocol: gen_init { let mut params: ~[ast::ty_param] = ~[]; for (copy self.states).each |s| { for s.ty_params.each |tp| { - match params.find(|tpp| *tp.ident == *tpp.ident) { + match params.find(|tpp| tp.ident == tpp.ident) { none => vec::push(params, tp), _ => () } } } - cx.ty_path_ast_builder(path(@~"__Buffer", self.span) + cx.ty_path_ast_builder(path(~[cx.ident_of(~"__Buffer")], self.span) .add_tys(cx.ty_vars(params))) } @@ -373,7 +383,7 @@ impl protocol: gen_init { let mut params: ~[ast::ty_param] = ~[]; let fields = do (copy self.states).map_to_vec |s| { for s.ty_params.each |tp| { - match params.find(|tpp| *tp.ident == *tpp.ident) { + match params.find(|tpp| tp.ident == tpp.ident) { none => vec::push(params, tp), _ => () } @@ -382,11 +392,11 @@ impl protocol: gen_init { let fty = #ast[ty] { pipes::packet<$(ty)> }; - cx.ty_field_imm(s.name, fty) + cx.ty_field_imm(cx.ident_of(s.name), fty) }; cx.item_ty_poly( - @~"__Buffer", + cx.ident_of(~"__Buffer"), cx.empty_span(), cx.ty_rec(fields), params) @@ -410,56 +420,56 @@ impl protocol: gen_init { } vec::push(items, - cx.item_mod(@~"client", + cx.item_mod(cx.ident_of(~"client"), self.span, client_states)); vec::push(items, - cx.item_mod(@~"server", + cx.item_mod(cx.ident_of(~"server"), self.span, server_states)); - cx.item_mod(self.name, self.span, items) + cx.item_mod(cx.ident_of(self.name), self.span, items) } } trait to_source { // Takes a thing and generates a string containing rust code for it. - fn to_source() -> ~str; + fn to_source(cx: ext_ctxt) -> ~str; } impl @ast::item: to_source { - fn to_source() -> ~str { - item_to_str(self) + fn to_source(cx: ext_ctxt) -> ~str { + item_to_str(self, cx.parse_sess().interner) } } impl ~[@ast::item]: to_source { - fn to_source() -> ~str { - str::connect(self.map(|i| i.to_source()), ~"\n\n") + fn to_source(cx: ext_ctxt) -> ~str { + str::connect(self.map(|i| i.to_source(cx)), ~"\n\n") } } impl @ast::ty: to_source { - fn to_source() -> ~str { - ty_to_str(self) + fn to_source(cx: ext_ctxt) -> ~str { + ty_to_str(self, cx.parse_sess().interner) } } impl ~[@ast::ty]: to_source { - fn to_source() -> ~str { - str::connect(self.map(|i| i.to_source()), ~", ") + fn to_source(cx: ext_ctxt) -> ~str { + str::connect(self.map(|i| i.to_source(cx)), ~", ") } } impl ~[ast::ty_param]: to_source { - fn to_source() -> ~str { - pprust::typarams_to_str(self) + fn to_source(cx: ext_ctxt) -> ~str { + pprust::typarams_to_str(self, cx.parse_sess().interner) } } impl @ast::expr: to_source { - fn to_source() -> ~str { - pprust::expr_to_str(self) + fn to_source(cx: ext_ctxt) -> ~str { + pprust::expr_to_str(self, cx.parse_sess().interner) } } diff --git a/src/libsyntax/ext/pipes/proto.rs b/src/libsyntax/ext/pipes/proto.rs index 9e44ce7acda..62c5329525f 100644 --- a/src/libsyntax/ext/pipes/proto.rs +++ b/src/libsyntax/ext/pipes/proto.rs @@ -1,8 +1,6 @@ import to_str::ToStr; import dvec::{DVec, dvec}; -import ast::{ident}; - import ast_builder::{path, append_types}; enum direction { @@ -27,15 +25,15 @@ impl direction { } } -type next_state = option<{state: ident, tys: ~[@ast::ty]}>; +type next_state = option<{state: ~str, tys: ~[@ast::ty]}>; enum message { // name, span, data, current state, next state - message(ident, span, ~[@ast::ty], state, next_state) + message(~str, span, ~[@ast::ty], state, next_state) } impl message { - fn name() -> ident { + fn name() -> ~str { match self { message(id, _, _, _, _) => id } @@ -58,7 +56,8 @@ impl message { enum state { state_(@{ id: uint, - name: ident, + name: ~str, + ident: ast::ident, span: span, dir: direction, ty_params: ~[ast::ty_param], @@ -68,7 +67,7 @@ enum state { } impl state { - fn add_message(name: ident, span: span, + fn add_message(name: ~str, span: span, +data: ~[@ast::ty], next: next_state) { self.messages.push(message(name, span, data, self, next)); @@ -78,14 +77,15 @@ impl state { (*self).proto.filename() } - fn data_name() -> ident { - self.name + fn data_name() -> ast::ident { + self.ident } /// Returns the type that is used for the messages. fn to_ty(cx: ext_ctxt) -> @ast::ty { cx.ty_path_ast_builder - (path(self.name, self.span).add_tys(cx.ty_vars(self.ty_params))) + (path(~[cx.ident_of(self.name)],self.span).add_tys( + cx.ty_vars(self.ty_params))) } /// Iterate over the states that can be reached in one message @@ -105,18 +105,18 @@ impl state { type protocol = @protocol_; -fn protocol(name: ident, +span: span) -> protocol { +fn protocol(name: ~str, +span: span) -> protocol { @protocol_(name, span) } struct protocol_ { - let name: ident; + let name: ~str; let span: span; let states: DVec; let mut bounded: option; - new(name: ident, span: span) { + new(name: ~str, span: span) { self.name = name; self.span = span; self.states = dvec(); @@ -124,18 +124,18 @@ struct protocol_ { } /// Get a state. - fn get_state(name: ident) -> state { + fn get_state(name: ~str) -> state { self.states.find(|i| i.name == name).get() } fn get_state_by_id(id: uint) -> state { self.states[id] } - fn has_state(name: ident) -> bool { + fn has_state(name: ~str) -> bool { self.states.find(|i| i.name == name) != none } fn filename() -> ~str { - ~"proto://" + *self.name + ~"proto://" + self.name } fn num_states() -> uint { self.states.len() } @@ -162,17 +162,14 @@ struct protocol_ { } impl protocol { - fn add_state(name: ident, dir: direction) -> state { - self.add_state_poly(name, dir, ~[]) - } - - fn add_state_poly(name: ident, dir: direction, + fn add_state_poly(name: ~str, ident: ast::ident, dir: direction, +ty_params: ~[ast::ty_param]) -> state { let messages = dvec(); let state = state_(@{ id: self.states.len(), name: name, + ident: ident, span: self.span, dir: dir, ty_params: ty_params, @@ -188,7 +185,7 @@ impl protocol { trait visitor { fn visit_proto(proto: protocol, st: &[Tstate]) -> Tproto; fn visit_state(state: state, m: &[Tmessage]) -> Tstate; - fn visit_message(name: ident, spane: span, tys: &[@ast::ty], + fn visit_message(name: ~str, spane: span, tys: &[@ast::ty], this: state, next: next_state) -> Tmessage; } diff --git a/src/libsyntax/ext/qquote.rs b/src/libsyntax/ext/qquote.rs index 6b5dce312d6..8024f5f9542 100644 --- a/src/libsyntax/ext/qquote.rs +++ b/src/libsyntax/ext/qquote.rs @@ -3,6 +3,7 @@ import ast::{crate, expr_, mac_invoc, import parse::parser; import parse::parser::parse_from_source_str; import dvec::{DVec, dvec}; +import parse::token::ident_interner; import fold::*; import visit::*; @@ -26,6 +27,14 @@ enum fragment { from_ty(@ast::ty) } +fn ids_ext(cx: ext_ctxt, strs: ~[~str]) -> ~[ast::ident] { + strs.map(|str| cx.parse_sess().interner.intern(@str)) +} +fn id_ext(cx: ext_ctxt, str: ~str) -> ast::ident { + cx.parse_sess().interner.intern(@str) +} + + trait qq_helper { fn span() -> span; fn visit(aq_ctxt, vt); @@ -40,7 +49,7 @@ impl @ast::crate: qq_helper { fn extract_mac() -> option {fail} fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr { mk_path(cx, sp, - ~[@~"syntax", @~"ext", @~"qquote", @~"parse_crate"]) + ids_ext(cx, ~[~"syntax", ~"ext", ~"qquote", ~"parse_crate"])) } fn get_fold_fn() -> ~str {~"fold_crate"} } @@ -55,7 +64,7 @@ impl @ast::expr: qq_helper { } fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr { mk_path(cx, sp, - ~[@~"syntax", @~"ext", @~"qquote", @~"parse_expr"]) + ids_ext(cx, ~[~"syntax", ~"ext", ~"qquote", ~"parse_expr"])) } fn get_fold_fn() -> ~str {~"fold_expr"} } @@ -70,7 +79,7 @@ impl @ast::ty: qq_helper { } fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr { mk_path(cx, sp, - ~[@~"syntax", @~"ext", @~"qquote", @~"parse_ty"]) + ids_ext(cx, ~[~"syntax", ~"ext", ~"qquote", ~"parse_ty"])) } fn get_fold_fn() -> ~str {~"fold_ty"} } @@ -80,7 +89,7 @@ impl @ast::item: qq_helper { fn extract_mac() -> option {fail} fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr { mk_path(cx, sp, - ~[@~"syntax", @~"ext", @~"qquote", @~"parse_item"]) + ids_ext(cx, ~[~"syntax", ~"ext", ~"qquote", ~"parse_item"])) } fn get_fold_fn() -> ~str {~"fold_item"} } @@ -90,7 +99,7 @@ impl @ast::stmt: qq_helper { fn extract_mac() -> option {fail} fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr { mk_path(cx, sp, - ~[@~"syntax", @~"ext", @~"qquote", @~"parse_stmt"]) + ids_ext(cx, ~[~"syntax", ~"ext", ~"qquote", ~"parse_stmt"])) } fn get_fold_fn() -> ~str {~"fold_stmt"} } @@ -99,7 +108,8 @@ impl @ast::pat: qq_helper { fn visit(cx: aq_ctxt, v: vt) {visit_pat(self, cx, v);} fn extract_mac() -> option {fail} fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr { - mk_path(cx, sp, ~[@~"syntax", @~"ext", @~"qquote", @~"parse_pat"]) + mk_path(cx, sp, ids_ext(cx, ~[~"syntax", ~"ext", ~"qquote", + ~"parse_pat"])) } fn get_fold_fn() -> ~str {~"fold_pat"} } @@ -159,7 +169,7 @@ fn expand_ast(ecx: ext_ctxt, _sp: span, } match (args[0].node) { ast::expr_path(@{idents: id, _}) if vec::len(id) == 1u - => what = *id[0], + => what = *ecx.parse_sess().interner.get(id[0]), _ => ecx.span_fatal(args[0].span, ~"expected an identifier") } } @@ -243,19 +253,21 @@ fn finish let cx = ecx; let cfg_call = || mk_call_( - cx, sp, mk_access(cx, sp, ~[@~"ext_cx"], @~"cfg"), ~[]); + cx, sp, mk_access(cx, sp, ids_ext(cx, ~[~"ext_cx"]), + id_ext(cx, ~"cfg")), ~[]); let parse_sess_call = || mk_call_( - cx, sp, mk_access(cx, sp, ~[@~"ext_cx"], @~"parse_sess"), ~[]); + cx, sp, mk_access(cx, sp, ids_ext(cx, ~[~"ext_cx"]), + id_ext(cx, ~"parse_sess")), ~[]); let pcall = mk_call(cx,sp, - ~[@~"syntax", @~"parse", @~"parser", - @~"parse_from_source_str"], + ids_ext(cx, ~[~"syntax", ~"parse", ~"parser", + ~"parse_from_source_str"]), ~[node.mk_parse_fn(cx,sp), mk_uniq_str(cx,sp, fname), mk_call(cx,sp, - ~[@~"syntax",@~"ext", - @~"qquote", @~"mk_file_substr"], + ids_ext(cx, ~[~"syntax",~"ext", + ~"qquote", ~"mk_file_substr"]), ~[mk_uniq_str(cx,sp, loc.file.name), mk_uint(cx,sp, loc.line), mk_uint(cx,sp, loc.col)]), @@ -267,16 +279,17 @@ fn finish let mut rcall = pcall; if (g_len > 0u) { rcall = mk_call(cx,sp, - ~[@~"syntax", @~"ext", @~"qquote", @~"replace"], + ids_ext(cx, ~[~"syntax", ~"ext", ~"qquote", + ~"replace"]), ~[pcall, mk_uniq_vec_e(cx,sp, qcx.gather.map_to_vec(|g| { mk_call(cx,sp, - ~[@~"syntax", @~"ext", - @~"qquote", @g.constr], + ids_ext(cx, ~[~"syntax", ~"ext", + ~"qquote", g.constr]), ~[g.e])})), mk_path(cx,sp, - ~[@~"syntax", @~"ext", @~"qquote", - @node.get_fold_fn()])]); + ids_ext(cx, ~[~"syntax", ~"ext", ~"qquote", + node.get_fold_fn()]))]); } return rcall; } @@ -331,14 +344,6 @@ fn replace_ty(repls: ~[fragment], } } -fn print_expr(expr: @ast::expr) { - let stdout = io::stdout(); - let pp = pprust::rust_printer(stdout); - pprust::print_expr(pp, expr); - pp::eof(pp.s); - stdout.write_str(~"\n"); -} - fn mk_file_substr(fname: ~str, line: uint, col: uint) -> codemap::file_substr { codemap::fss_external({filename: fname, line: line, col: col}) diff --git a/src/libsyntax/ext/simplext.rs b/src/libsyntax/ext/simplext.rs index e8899a2e541..5b9bac1948f 100644 --- a/src/libsyntax/ext/simplext.rs +++ b/src/libsyntax/ext/simplext.rs @@ -1,5 +1,5 @@ import codemap::span; -import std::map::{hashmap, str_hash, box_str_hash}; +import std::map::{hashmap, str_hash, uint_hash}; import dvec::{DVec, dvec}; import base::*; @@ -135,7 +135,7 @@ fn acumm_bindings(_cx: ext_ctxt, _b_dest: bindings, _b_src: bindings) { } fn pattern_to_selectors(cx: ext_ctxt, e: @expr) -> binders { let res: binders = - {real_binders: box_str_hash::(), + {real_binders: uint_hash::(), literal_ast_matchers: dvec()}; //this oughta return binders instead, but macro args are a sequence of //expressions, rather than a single expression @@ -153,7 +153,7 @@ bindings. Most of the work is done in p_t_s, which generates the selectors. */ fn use_selectors_to_bind(b: binders, e: @expr) -> option { - let res = box_str_hash::>(); + let res = uint_hash::>(); //need to do this first, to check vec lengths. for b.literal_ast_matchers.each |sel| { match sel(match_expr(e)) { none => return none, _ => () } @@ -237,7 +237,7 @@ fn follow_for_trans(cx: ext_ctxt, mmaybe: option>, /* helper for transcribe_exprs: what vars from `b` occur in `e`? */ fn free_vars(b: bindings, e: @expr, it: fn(ident)) { - let idents: hashmap = box_str_hash::<()>(); + let idents: hashmap = uint_hash::<()>(); fn mark_ident(&&i: ident, _fld: ast_fold, b: bindings, idents: hashmap) -> ident { if b.contains_key(i) { idents.insert(i, ()); } @@ -253,6 +253,12 @@ fn free_vars(b: bindings, e: @expr, it: fn(ident)) { for idents.each_key |x| { it(x); }; } +fn wrong_occurs(cx: ext_ctxt, l: ident, l_c: uint, r: ident, r_c: uint) + -> ~str { + fmt!{"'%s' occurs %u times, but '%s' occurs %u times", + *cx.parse_sess().interner.get(l), l_c, + *cx.parse_sess().interner.get(r), r_c} +} /* handle sequences (anywhere in the AST) of exprs, either real or ...ed */ fn transcribe_exprs(cx: ext_ctxt, b: bindings, idx_path: @mut ~[uint], @@ -279,10 +285,8 @@ fn transcribe_exprs(cx: ext_ctxt, b: bindings, idx_path: @mut ~[uint], some({rep_count: old_len, name: old_name}) => { let len = vec::len(*ms); if old_len != len { - let msg = - fmt!{"'%s' occurs %u times, but ", *fv, len} + - fmt!{"'%s' occurs %u times", *old_name, - old_len}; + let msg = wrong_occurs(cx, fv, len, + old_name, old_len); cx.span_fatal(repeat_me.span, msg); } } @@ -626,7 +630,7 @@ fn add_new_extension(cx: ext_ctxt, sp: span, arg: ast::mac_arg, _body: ast::mac_body) -> base::macro_def { let args = get_mac_args_no_max(cx, sp, arg, 0u, ~"macro"); - let mut macro_name: option<@~str> = none; + let mut macro_name: option<~str> = none; let mut clauses: ~[@clause] = ~[]; for args.each |arg| { match arg.node { @@ -643,12 +647,15 @@ fn add_new_extension(cx: ext_ctxt, sp: span, arg: ast::mac_arg, match mac.node { mac_invoc(pth, invoc_arg, body) => { match path_to_ident(pth) { - some(id) => match macro_name { - none => macro_name = some(id), - some(other_id) => if id != other_id { + some(id) => { + let id_str = cx.str_of(id); + match macro_name { + none => macro_name = some(id_str), + some(other_id) => if id_str != other_id { cx.span_fatal(pth.span, ~"macro name must be " + ~"consistent"); + } } }, none => cx.span_fatal(pth.span, @@ -688,7 +695,7 @@ fn add_new_extension(cx: ext_ctxt, sp: span, arg: ast::mac_arg, let ext = |a,b,c,d, move clauses| generic_extension(a,b,c,d,clauses); - return {ident: + return {name: match macro_name { some(id) => id, none => cx.span_fatal(sp, ~"macro definition must have " + diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index e05a713165b..c323f201b83 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -43,14 +43,15 @@ fn expand_file(cx: ext_ctxt, sp: span, arg: ast::mac_arg, fn expand_stringify(cx: ext_ctxt, sp: span, arg: ast::mac_arg, _body: ast::mac_body) -> @ast::expr { let args = get_mac_args(cx, sp, arg, 1u, option::some(1u), ~"stringify"); - return mk_uniq_str(cx, sp, pprust::expr_to_str(args[0])); + let s = pprust::expr_to_str(args[0], cx.parse_sess().interner); + return mk_uniq_str(cx, sp, s); } fn expand_mod(cx: ext_ctxt, sp: span, arg: ast::mac_arg, _body: ast::mac_body) -> @ast::expr { get_mac_args(cx, sp, arg, 0u, option::some(0u), ~"file"); return mk_uniq_str(cx, sp, - str::connect(cx.mod_path().map(|x|*x), ~"::")); + str::connect(cx.mod_path().map(|x| cx.str_of(x)), ~"::")); } fn expand_include(cx: ext_ctxt, sp: span, arg: ast::mac_arg, diff --git a/src/libsyntax/ext/trace_macros.rs b/src/libsyntax/ext/trace_macros.rs index d4f1493169f..22f0aeaa2c0 100644 --- a/src/libsyntax/ext/trace_macros.rs +++ b/src/libsyntax/ext/trace_macros.rs @@ -15,10 +15,10 @@ fn expand_trace_macros(cx: ext_ctxt, sp: span, let rdr = tt_rdr as reader; let rust_parser = parser(sess, cfg, rdr.dup(), SOURCE_FILE); - let arg = rust_parser.parse_ident(); + let arg = cx.str_of(rust_parser.parse_ident()); match arg { - @~"true" => cx.set_trace_macros(true), - @~"false" => cx.set_trace_macros(false), + ~"true" => cx.set_trace_macros(true), + ~"false" => cx.set_trace_macros(false), _ => cx.span_fatal(sp, ~"trace_macros! only accepts `true` or `false`") } let rust_parser = parser(sess, cfg, rdr.dup(), SOURCE_FILE); diff --git a/src/libsyntax/ext/tt/earley_parser.rs b/src/libsyntax/ext/tt/earley_parser.rs index 77ba941015b..896b6f6e54f 100644 --- a/src/libsyntax/ext/tt/earley_parser.rs +++ b/src/libsyntax/ext/tt/earley_parser.rs @@ -10,7 +10,7 @@ import parse::parse_sess; import dvec::{DVec, dvec}; import ast::{matcher, match_tok, match_seq, match_nonterminal, ident}; import ast_util::mk_sp; -import std::map::{hashmap, box_str_hash}; +import std::map::{hashmap, uint_hash}; /* This is an Earley-like parser, without support for in-grammar nonterminals, onlyl calling out to the main rust parser for named nonterminals (which it @@ -120,14 +120,14 @@ fn nameize(p_s: parse_sess, ms: ~[matcher], res: ~[@named_match]) } {node: match_nonterminal(bind_name, _, idx), span: sp} => { if ret_val.contains_key(bind_name) { - p_s.span_diagnostic.span_fatal(sp, ~"Duplicated bind name: " - + *bind_name) + p_s.span_diagnostic.span_fatal(sp, ~"Duplicated bind name: "+ + *p_s.interner.get(bind_name)) } ret_val.insert(bind_name, res[idx]); } } } - let ret_val = box_str_hash::<@named_match>(); + let ret_val = uint_hash::<@named_match>(); for ms.each() |m| { n_rec(p_s, m, res, ret_val) } return ret_val; } @@ -274,7 +274,8 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher]) let nts = str::connect(vec::map(bb_eis, |ei| { match ei.elts[ei.idx].node { match_nonterminal(bind,name,_) => { - fmt!{"%s ('%s')", *name, *bind} + fmt!{"%s ('%s')", *sess.interner.get(name), + *sess.interner.get(bind)} } _ => fail } }), ~" or "); @@ -298,7 +299,7 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher]) match ei.elts[ei.idx].node { match_nonterminal(_, name, idx) => { ei.matches[idx].push(@matched_nonterminal( - parse_nt(rust_parser, *name))); + parse_nt(rust_parser, *sess.interner.get(name)))); ei.idx += 1u; } _ => fail diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 05db498a022..be7594ff843 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -8,6 +8,7 @@ import parse::parser::{parser, SOURCE_FILE}; import earley_parser::{parse, parse_or_else, success, failure, named_match, matched_seq, matched_nonterminal, error}; import std::map::hashmap; +import parse::token::special_idents; fn add_new_extension(cx: ext_ctxt, sp: span, name: ident, arg: ~[ast::token_tree]) -> base::mac_result { @@ -16,14 +17,17 @@ fn add_new_extension(cx: ext_ctxt, sp: span, name: ident, {node: m, span: {lo: 0u, hi: 0u, expn_info: none}} } + let lhs_nm = cx.parse_sess().interner.gensym(@~"lhs"); + let rhs_nm = cx.parse_sess().interner.gensym(@~"rhs"); + // The grammar for macro_rules! is: // $( $lhs:mtcs => $rhs:tt );+ // ...quasiquoting this would be nice. let argument_gram = ~[ ms(match_seq(~[ - ms(match_nonterminal(@~"lhs",@~"matchers", 0u)), + ms(match_nonterminal(lhs_nm, special_idents::matchers, 0u)), ms(match_tok(FAT_ARROW)), - ms(match_nonterminal(@~"rhs",@~"tt", 1u)), + ms(match_nonterminal(rhs_nm, special_idents::tt, 1u)), ], some(SEMI), false, 0u, 2u)), //to phase into semicolon-termination instead of //semicolon-separation @@ -37,11 +41,11 @@ fn add_new_extension(cx: ext_ctxt, sp: span, name: ident, arg_reader as reader, argument_gram); // Extract the arguments: - let lhses:~[@named_match] = match argument_map.get(@~"lhs") { + let lhses:~[@named_match] = match argument_map.get(lhs_nm) { @matched_seq(s, sp) => s, _ => cx.span_bug(sp, ~"wrong-structured lhs") }; - let rhses:~[@named_match] = match argument_map.get(@~"rhs") { + let rhses:~[@named_match] = match argument_map.get(rhs_nm) { @matched_seq(s, sp) => s, _ => cx.span_bug(sp, ~"wrong-structured rhs") }; @@ -53,8 +57,9 @@ fn add_new_extension(cx: ext_ctxt, sp: span, name: ident, -> mac_result { if cx.trace_macros() { - io::println(fmt!("%s! { %s }", *name, - print::pprust::unexpanded_tt_to_str( + io::println(fmt!("%s! { %s }", + cx.str_of(name), + print::pprust::tt_to_str( ast::tt_delim(arg), cx.parse_sess().interner))); } @@ -103,7 +108,7 @@ fn add_new_extension(cx: ext_ctxt, sp: span, name: ident, arg, lhses, rhses); return mr_def({ - ident: name, + name: *cx.parse_sess().interner.get(name), ext: expr_tt({expander: exp, span: some(sp)}) }); } \ No newline at end of file diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index a166957231e..1653c57bf2c 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -47,7 +47,7 @@ fn new_tt_reader(sp_diag: span_handler, itr: ident_interner, mut cur: @{readme: src, mut idx: 0u, dotdotdoted: false, sep: none, up: tt_frame_up(option::none)}, interpolations: match interp { /* just a convienience */ - none => std::map::box_str_hash::<@named_match>(), + none => std::map::uint_hash::<@named_match>(), some(x) => x }, mut repeat_idx: ~[mut], mut repeat_len: ~[], @@ -100,8 +100,8 @@ enum lis { lis_unconstrained, lis_constraint(uint, ident), lis_contradiction(~str) } -fn lockstep_iter_size(&&t: token_tree, &&r: tt_reader) -> lis { - fn lis_merge(lhs: lis, rhs: lis) -> lis { +fn lockstep_iter_size(t: token_tree, r: tt_reader) -> lis { + fn lis_merge(lhs: lis, rhs: lis, r: tt_reader) -> lis { match lhs { lis_unconstrained => rhs, lis_contradiction(_) => lhs, @@ -110,9 +110,11 @@ fn lockstep_iter_size(&&t: token_tree, &&r: tt_reader) -> lis { lis_contradiction(_) => rhs, lis_constraint(r_len, _) if l_len == r_len => lhs, lis_constraint(r_len, r_id) => { + let l_n = *r.interner.get(l_id); + let r_n = *r.interner.get(r_id); lis_contradiction(fmt!{"Inconsistent lockstep iteration: \ '%s' has %u items, but '%s' has %u", - *l_id, l_len, *r_id, r_len}) + l_n, l_len, r_n, r_len}) } } } @@ -120,7 +122,7 @@ fn lockstep_iter_size(&&t: token_tree, &&r: tt_reader) -> lis { match t { tt_delim(tts) | tt_seq(_, tts, _, _) => { vec::foldl(lis_unconstrained, tts, {|lis, tt| - lis_merge(lis, lockstep_iter_size(tt, r)) }) + lis_merge(lis, lockstep_iter_size(tt, r), r) }) } tt_tok(*) => lis_unconstrained, tt_nonterminal(_, name) => match *lookup_cur_matched(r, name) { @@ -230,7 +232,7 @@ fn tt_next_token(&&r: tt_reader) -> {tok: token, sp: span} { r.sp_diag.span_fatal( copy r.cur_span, /* blame the macro writer */ fmt!{"variable '%s' is still repeating at this depth", - *ident}); + *r.interner.get(ident)}); } } } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 705f21895b6..05191c677a0 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -81,15 +81,14 @@ type ast_fold_precursor = @{ fn fold_meta_item_(&&mi: @meta_item, fld: ast_fold) -> @meta_item { return @{node: match mi.node { - meta_word(id) => meta_word(fld.fold_ident(id)), + meta_word(id) => meta_word(id), meta_list(id, mis) => { let fold_meta_item = |x|fold_meta_item_(x, fld); meta_list(/* FIXME: (#2543) */ copy id, vec::map(mis, fold_meta_item)) } meta_name_value(id, s) => { - meta_name_value(fld.fold_ident(id), - /* FIXME (#2543) */ copy s) + meta_name_value(id, /* FIXME (#2543) */ copy s) } }, span: fld.new_span(mi.span)}; diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs index cbb6709d9c8..54b0e3388f7 100644 --- a/src/libsyntax/parse/attr.rs +++ b/src/libsyntax/parse/attr.rs @@ -66,7 +66,7 @@ impl parser: parser_attr { } token::DOC_COMMENT(s) => { let attr = ::attr::mk_sugared_doc_attr( - *self.get_str(s), self.span.lo, self.span.hi); + *self.id_to_str(s), self.span.lo, self.span.hi); if attr.node.style != ast::attr_outer { self.fatal(~"expected outer comment"); } @@ -128,7 +128,7 @@ impl parser: parser_attr { } token::DOC_COMMENT(s) => { let attr = ::attr::mk_sugared_doc_attr( - *self.get_str(s), self.span.lo, self.span.hi); + *self.id_to_str(s), self.span.lo, self.span.hi); self.bump(); if attr.node.style == ast::attr_inner { inner_attrs += ~[attr]; @@ -145,22 +145,22 @@ impl parser: parser_attr { fn parse_meta_item() -> @ast::meta_item { let lo = self.span.lo; - let ident = self.parse_ident(); + let name = *self.id_to_str(self.parse_ident()); match self.token { token::EQ => { self.bump(); let lit = self.parse_lit(); let mut hi = self.span.hi; - return @spanned(lo, hi, ast::meta_name_value(ident, lit)); + return @spanned(lo, hi, ast::meta_name_value(name, lit)); } token::LPAREN => { let inner_items = self.parse_meta_seq(); let mut hi = self.span.hi; - return @spanned(lo, hi, ast::meta_list(ident, inner_items)); + return @spanned(lo, hi, ast::meta_list(name, inner_items)); } _ => { let mut hi = self.span.hi; - return @spanned(lo, hi, ast::meta_word(ident)); + return @spanned(lo, hi, ast::meta_word(name)); } } } diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs index b10da4482e4..09edbda4335 100644 --- a/src/libsyntax/parse/comments.rs +++ b/src/libsyntax/parse/comments.rs @@ -276,7 +276,7 @@ fn gather_comments_and_literals(span_diagnostic: diagnostic::span_handler, srdr: io::Reader) -> {cmnts: ~[cmnt], lits: ~[lit]} { let src = @str::from_bytes(srdr.read_whole_stream()); - let itr = parse::token::mk_ident_interner(); + let itr = parse::token::mk_fake_ident_interner(); let rdr = lexer::new_low_level_string_reader (span_diagnostic, codemap::new_filemap(path, src, 0u, 0u), itr); diff --git a/src/libsyntax/parse/common.rs b/src/libsyntax/parse/common.rs index 59dad16dc44..1d260268d3f 100644 --- a/src/libsyntax/parse/common.rs +++ b/src/libsyntax/parse/common.rs @@ -85,7 +85,7 @@ impl parser: parser_common { fn parse_ident() -> ast::ident { match copy self.token { - token::IDENT(i, _) => { self.bump(); return self.get_str(i); } + token::IDENT(i, _) => { self.bump(); return i; } token::INTERPOLATED(token::nt_ident(*)) => { self.bug( ~"ident interpolation not converted to real token"); } _ => { self.fatal(~"expected ident, found `" @@ -110,6 +110,8 @@ impl parser: parser_common { return if self.token == tok { self.bump(); true } else { false }; } + // Storing keywords as interned idents instead of strings would be nifty. + // A sanity check that the word we are asking for is a known keyword fn require_keyword(word: ~str) { if !self.keywords.contains_key_ref(&word) { @@ -119,7 +121,7 @@ impl parser: parser_common { fn token_is_word(word: ~str, ++tok: token::token) -> bool { match tok { - token::IDENT(sid, false) => { word == *self.get_str(sid) } + token::IDENT(sid, false) => { *self.id_to_str(sid) == word } _ => { false } } } @@ -136,7 +138,7 @@ impl parser: parser_common { fn is_any_keyword(tok: token::token) -> bool { match tok { token::IDENT(sid, false) => { - self.keywords.contains_key_ref(self.get_str(sid)) + self.keywords.contains_key_ref(self.id_to_str(sid)) } _ => false } @@ -148,7 +150,7 @@ impl parser: parser_common { let mut bump = false; let val = match self.token { token::IDENT(sid, false) => { - if word == *self.get_str(sid) { + if word == *self.id_to_str(sid) { bump = true; true } else { false } diff --git a/src/libsyntax/parse/eval.rs b/src/libsyntax/parse/eval.rs index 6b0112922a5..60d2fadb04c 100644 --- a/src/libsyntax/parse/eval.rs +++ b/src/libsyntax/parse/eval.rs @@ -78,10 +78,10 @@ fn parse_companion_mod(cx: ctx, prefix: ~str, suffix: option<~str>) } } -fn cdir_path_opt(id: ast::ident, attrs: ~[ast::attribute]) -> @~str { +fn cdir_path_opt(default: ~str, attrs: ~[ast::attribute]) -> ~str { match ::attr::first_attr_value_str_by_name(attrs, ~"path") { - some(d) => return d, - none => return id + some(d) => d, + none => default } } @@ -90,11 +90,12 @@ fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: ~str, &items: ~[@ast::item]) { match cdir.node { ast::cdir_src_mod(id, attrs) => { - let file_path = cdir_path_opt(@(*id + ~".rs"), attrs); + let file_path = cdir_path_opt((cx.sess.interner.get(id) + ~".rs"), + attrs); let full_path = - if path::path_is_absolute(*file_path) { - *file_path - } else { prefix + path::path_sep() + *file_path }; + if path::path_is_absolute(file_path) { + file_path + } else { prefix + path::path_sep() + file_path }; let (p0, r0) = new_parser_etc_from_file(cx.sess, cx.cfg, full_path, SOURCE_FILE); let inner_attrs = p0.parse_inner_attrs_and_next(); @@ -111,11 +112,11 @@ fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: ~str, vec::push(items, i); } ast::cdir_dir_mod(id, cdirs, attrs) => { - let path = cdir_path_opt(id, attrs); + let path = cdir_path_opt(*cx.sess.interner.get(id), attrs); let full_path = - if path::path_is_absolute(*path) { - *path - } else { prefix + path::path_sep() + *path }; + if path::path_is_absolute(path) { + path + } else { prefix + path::path_sep() + path }; let (m0, a0) = eval_crate_directives_to_mod( cx, cdirs, full_path, none); let i = diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 648ec3e60db..fea79309c21 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -6,7 +6,7 @@ import std::map::{hashmap, str_hash}; import token::{can_begin_expr, is_ident, is_ident_or_path, is_plain_ident, INTERPOLATED}; import codemap::{span,fss_none}; -import util::interner; +import util::interner::interner; import ast_util::{spanned, respan, mk_sp, ident_to_path, operator_prec}; import lexer::reader; import prec::{as_prec, token_to_binop}; @@ -193,12 +193,14 @@ struct parser { let mut restriction: restriction; let mut quote_depth: uint; // not (yet) related to the quasiquoter let reader: reader; + let interner: interner<@~str>; let keywords: hashmap<~str, ()>; let restricted_keywords: hashmap<~str, ()>; new(sess: parse_sess, cfg: ast::crate_cfg, +rdr: reader, ftype: file_type) { self.reader <- rdr; + self.interner = self.reader.interner(); let tok0 = self.reader.next_token(); let span0 = tok0.sp; self.sess = sess; @@ -268,11 +270,10 @@ struct parser { fn warn(m: ~str) { self.sess.span_diagnostic.span_warn(copy self.span, m) } - pure fn get_str(i: token::str_num) -> @~str { - self.reader.interner().get(i) - } fn get_id() -> node_id { next_node_id(self.sess) } + pure fn id_to_str(id: ident) -> @~str { self.sess.interner.get(id) } + fn parse_ty_fn(purity: ast::purity) -> ty_ { let proto, bounds; if self.eat_keyword(~"extern") { @@ -398,9 +399,9 @@ struct parser { } } - fn region_from_name(s: option<@~str>) -> @region { + fn region_from_name(s: option) -> @region { let r = match s { - some (string) => re_named(string), + some (id) => re_named(id), none => re_anon }; @@ -414,8 +415,7 @@ struct parser { match copy self.token { token::IDENT(sid, _) => { self.bump(); - let n = self.get_str(sid); - self.region_from_name(some(n)) + self.region_from_name(some(sid)) } _ => { self.region_from_name(none) @@ -430,7 +430,7 @@ struct parser { token::IDENT(sid, _) => { if self.look_ahead(1u) == token::BINOP(token::SLASH) { self.bump(); self.bump(); - some(self.get_str(sid)) + some(sid) } else { none } @@ -583,7 +583,7 @@ struct parser { let name = self.parse_value_ident(); self.bump(); name - } else { @~"" } + } else { token::special_idents::invalid } }; let t = self.parse_ty(false); @@ -678,10 +678,10 @@ struct parser { token::LIT_INT(i, it) => lit_int(i, it), token::LIT_UINT(u, ut) => lit_uint(u, ut), token::LIT_INT_UNSUFFIXED(i) => lit_int_unsuffixed(i), - token::LIT_FLOAT(s, ft) => lit_float(self.get_str(s), ft), - token::LIT_STR(s) => lit_str(self.get_str(s)), - token::LPAREN => { self.expect(token::RPAREN); lit_nil } - _ => self.unexpected_last(tok) + token::LIT_FLOAT(s, ft) => lit_float(self.id_to_str(s), ft), + token::LIT_STR(s) => lit_str(self.id_to_str(s)), + token::LPAREN => { self.expect(token::RPAREN); lit_nil }, + _ => { self.unexpected_last(tok); } } } @@ -1140,8 +1140,7 @@ struct parser { self.parse_seq_to_gt(some(token::COMMA), |p| p.parse_ty(false)) } else { ~[] }; - e = self.mk_pexpr(lo, hi, expr_field(self.to_expr(e), - self.get_str(i), + e = self.mk_pexpr(lo, hi, expr_field(self.to_expr(e), i, tys)); } _ => self.unexpected() @@ -2123,9 +2122,6 @@ struct parser { } fn expr_is_complete(e: pexpr) -> bool { - log(debug, (~"expr_is_complete", self.restriction, - print::pprust::expr_to_str(*e), - classify::expr_requires_semi_to_be_stmt(*e))); return self.restriction == RESTRICT_STMT_EXPR && !classify::expr_requires_semi_to_be_stmt(*e); } @@ -2306,8 +2302,9 @@ struct parser { fn is_self_ident() -> bool { match self.token { - token::IDENT(sid, false) if ~"self" == *self.get_str(sid) => true, - _ => false + token::IDENT(id, false) if id == token::special_idents::self_ + => true, + _ => false } } @@ -2522,11 +2519,13 @@ struct parser { } // This is a new-style impl declaration. - let ident = @~"__extensions__"; // XXX: clownshoes + // XXX: clownshoes + let ident = token::special_idents::clownshoes_extensions; // Parse the type. let ty = self.parse_ty(false); + // Parse traits, if necessary. let traits = if self.token == token::COLON { self.bump(); @@ -2595,7 +2594,8 @@ struct parser { match the_ctor { some((_, _, _, s_first)) => { self.span_note(s, #fmt("Duplicate constructor \ - declaration for class %s", *class_name)); + declaration for class %s", + *self.interner.get(class_name))); self.span_fatal(copy s_first, ~"First constructor \ declared here"); } @@ -2608,7 +2608,8 @@ struct parser { match the_dtor { some((_, _, s_first)) => { self.span_note(s, #fmt("Duplicate destructor \ - declaration for class %s", *class_name)); + declaration for class %s", + *self.interner.get(class_name))); self.span_fatal(copy s_first, ~"First destructor \ declared here"); } @@ -3081,7 +3082,7 @@ struct parser { let ty_params = self.parse_ty_params(); // Newtype syntax if self.token == token::EQ { - self.check_restricted_keywords_(*id); + self.check_restricted_keywords_(*self.id_to_str(id)); self.bump(); let ty = self.parse_ty(false); self.expect(token::SEMI); @@ -3297,7 +3298,7 @@ struct parser { let lo = self.span.lo; let first_ident = self.parse_ident(); let mut path = ~[first_ident]; - debug!{"parsed view_path: %s", *first_ident}; + debug!{"parsed view_path: %s", *self.id_to_str(first_ident)}; match self.token { token::EQ => { // x = foo::bar @@ -3323,7 +3324,7 @@ struct parser { token::IDENT(i, _) => { self.bump(); - vec::push(path, self.get_str(i)); + vec::push(path, i); } // foo::bar::{a,b,c} @@ -3458,8 +3459,8 @@ struct parser { fn parse_str() -> @~str { match copy self.token { - token::LIT_STR(s) => { self.bump(); self.get_str(s) } - _ => self.fatal(~"expected string literal") + token::LIT_STR(s) => { self.bump(); self.id_to_str(s) } + _ => self.fatal(~"expected string literal") } } diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 10fac8d0e23..8eb9270efe2 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -277,23 +277,83 @@ pure fn is_bar(t: token) -> bool { match t { BINOP(OR) | OROR => true, _ => false } } -type ident_interner = util::interner::interner<@~str>; mod special_idents { - const underscore : uint = 0u; - const anon : uint = 1u; - const destr : uint = 2u; // 'drop', but that's reserved + import ast::ident; + const underscore : ident = 0u; + const anon : ident = 1u; + const dtor : ident = 2u; // 'drop', but that's reserved + const invalid : ident = 3u; // '' + const unary : ident = 4u; + const not_fn : ident = 5u; + const idx_fn : ident = 6u; + const unary_minus_fn : ident = 7u; + const clownshoes_extensions : ident = 8u; + + const self_ : ident = 9u; // 'self' + + /* for matcher NTs */ + const item : ident = 10u; + const block : ident = 11u; + const stmt : ident = 12u; + const pat : ident = 13u; + const expr : ident = 14u; + const ty : ident = 15u; + const ident : ident = 16u; + const path : ident = 17u; + const tt : ident = 18u; + const matchers : ident = 19u; + + const str : ident = 20u; // for the type + + /* outside of libsyntax */ + const ty_visitor : ident = 21u; + const arg : ident = 22u; + const descrim : ident = 23u; + const clownshoe_abi : ident = 24u; + const clownshoe_stack_shim : ident = 25u; + const tydesc : ident = 26u; + const literally_dtor : ident = 27u; + const main : ident = 28u; + const opaque : ident = 29u; + const blk : ident = 30u; + const static : ident = 31u; + const intrinsic : ident = 32u; + } +type ident_interner = util::interner::interner<@~str>; + +/** Key for thread-local data for sneaking interner information to the + * serializer/deserializer. It sounds like a hack because it is one. */ +fn interner_key(+_x: @@ident_interner) { } + fn mk_ident_interner() -> ident_interner { /* the indices here must correspond to the numbers in special_idents */ - let init_vec = ~[@~"_", @~"anon", @~"drop"]; - - let rv = @interner::mk_prefill::<@~str>(|x| str::hash(*x), - |x,y| str::eq(*x, *y), init_vec); + let init_vec = ~[@~"_", @~"anon", @~"drop", @~"", @~"unary", @~"!", + @~"[]", @~"unary-", @~"__extensions__", @~"self", + @~"item", @~"block", @~"stmt", @~"pat", @~"expr", + @~"ty", @~"ident", @~"path", @~"tt", @~"matchers", + @~"str", @~"ty_visitor", @~"arg", @~"descrim", + @~"__rust_abi", @~"__rust_stack_shim", @~"tydesc", + @~"dtor", @~"main", @~"", @~"blk", @~"static", + @~"intrinsic"]; + + let rv = interner::mk_prefill::<@~str>(|x| str::hash(*x), + |x,y| str::eq(*x, *y), init_vec); + + /* having multiple interners will just confuse the serializer */ + unsafe{ assert task::local_data_get(interner_key) == none }; + unsafe{ task::local_data_set(interner_key, @rv) }; rv } +/* for when we don't care about the contents; doesn't interact with TLD or + serialization */ +fn mk_fake_ident_interner() -> ident_interner { + interner::mk::<@~str>(|x| str::hash(*x), |x,y| str::eq(*x, *y)) +} + /** * All the valid words that have meaning in the Rust language. * diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index b8872f76d8d..573eeffd968 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -8,9 +8,7 @@ import ast::{required, provided}; import ast_util::{operator_prec}; import dvec::{DVec, dvec}; import parse::classify::*; -import util::interner; - -type ident_interner = interner::interner<@~str>; +import parse::token::ident_interner; // The ps is stored here to prevent recursive type. enum ann_node { @@ -47,19 +45,7 @@ fn end(s: ps) { pp::end(s.s); } -fn rust_printer(writer: io::Writer) -> ps { - return @{s: pp::mk_printer(writer, default_columns), - cm: none::, - intr: token::mk_ident_interner(), - comments: none::<~[comments::cmnt]>, - literals: none::<~[comments::lit]>, - mut cur_cmnt: 0u, - mut cur_lit: 0u, - boxes: dvec(), - ann: no_ann()}; -} - -fn unexpanded_rust_printer(writer: io::Writer, intr: ident_interner) -> ps { +fn rust_printer(writer: io::Writer, intr: ident_interner) -> ps { return @{s: pp::mk_printer(writer, default_columns), cm: none::, intr: intr, @@ -79,7 +65,7 @@ const default_columns: uint = 78u; // Requires you to pass an input filename and reader so that // it can scan the input text for comments and literals to // copy forward. -fn print_crate(cm: codemap, intr: interner::interner<@~str>, +fn print_crate(cm: codemap, intr: ident_interner, span_diagnostic: diagnostic::span_handler, crate: @ast::crate, filename: ~str, in: io::Reader, out: io::Writer, ann: pp_ann, is_expanded: bool) { @@ -107,41 +93,46 @@ fn print_crate_(s: ps, &&crate: @ast::crate) { eof(s.s); } -fn ty_to_str(ty: @ast::ty) -> ~str { return to_str(ty, print_type); } +fn ty_to_str(ty: @ast::ty, intr: ident_interner) -> ~str { + to_str(ty, print_type, intr) +} -fn pat_to_str(pat: @ast::pat) -> ~str { return to_str(pat, print_pat); } +fn pat_to_str(pat: @ast::pat, intr: ident_interner) -> ~str { + to_str(pat, print_pat, intr) +} -fn expr_to_str(e: @ast::expr) -> ~str { return to_str(e, print_expr); } +fn expr_to_str(e: @ast::expr, intr: ident_interner) -> ~str { + to_str(e, print_expr, intr) +} -fn unexpanded_tt_to_str(tt: ast::token_tree, intr: ident_interner) - -> ~str { - let buffer = io::mem_buffer(); - let s = unexpanded_rust_printer(io::mem_buffer_writer(buffer), intr); - print_tt(s, tt); - eof(s.s); - io::mem_buffer_str(buffer) +fn tt_to_str(tt: ast::token_tree, intr: ident_interner) -> ~str { + to_str(tt, print_tt, intr) } -fn stmt_to_str(s: ast::stmt) -> ~str { return to_str(s, print_stmt); } +fn stmt_to_str(s: ast::stmt, intr: ident_interner) -> ~str { + to_str(s, print_stmt, intr) +} -fn item_to_str(i: @ast::item) -> ~str { return to_str(i, print_item); } +fn item_to_str(i: @ast::item, intr: ident_interner) -> ~str { + to_str(i, print_item, intr) +} -fn attr_to_str(i: ast::attribute) -> ~str { - return to_str(i, print_attribute); +fn attr_to_str(i: ast::attribute, intr: ident_interner) -> ~str { + to_str(i, print_attribute, intr) } -fn typarams_to_str(tps: ~[ast::ty_param]) -> ~str { - return to_str(tps, print_type_params) +fn typarams_to_str(tps: ~[ast::ty_param], intr: ident_interner) -> ~str { + to_str(tps, print_type_params, intr) } -fn path_to_str(&&p: @ast::path) -> ~str { - return to_str(p, |a,b| print_path(a, b, false)); +fn path_to_str(&&p: @ast::path, intr: ident_interner) -> ~str { + to_str(p, |a,b| print_path(a, b, false), intr) } fn fun_to_str(decl: ast::fn_decl, name: ast::ident, - params: ~[ast::ty_param]) -> ~str { + params: ~[ast::ty_param], intr: ident_interner) -> ~str { let buffer = io::mem_buffer(); - let s = rust_printer(io::mem_buffer_writer(buffer)); + let s = rust_printer(io::mem_buffer_writer(buffer), intr); print_fn(s, decl, name, params, none); end(s); // Close the head box end(s); // Close the outer box @@ -162,9 +153,9 @@ fn test_fun_to_str() { assert fun_to_str(decl, "a", ~[]) == "fn a()"; } -fn block_to_str(blk: ast::blk) -> ~str { +fn block_to_str(blk: ast::blk, intr: ident_interner) -> ~str { let buffer = io::mem_buffer(); - let s = rust_printer(io::mem_buffer_writer(buffer)); + let s = rust_printer(io::mem_buffer_writer(buffer), intr); // containing cbox, will be closed by print-block at } cbox(s, indent_unit); // head-ibox, will be closed by print-block after { @@ -174,16 +165,16 @@ fn block_to_str(blk: ast::blk) -> ~str { io::mem_buffer_str(buffer) } -fn meta_item_to_str(mi: ast::meta_item) -> ~str { - return to_str(@mi, print_meta_item); +fn meta_item_to_str(mi: ast::meta_item, intr: ident_interner) -> ~str { + to_str(@mi, print_meta_item, intr) } -fn attribute_to_str(attr: ast::attribute) -> ~str { - return to_str(attr, print_attribute); +fn attribute_to_str(attr: ast::attribute, intr: ident_interner) -> ~str { + to_str(attr, print_attribute, intr) } -fn variant_to_str(var: ast::variant) -> ~str { - return to_str(var, print_variant); +fn variant_to_str(var: ast::variant, intr: ident_interner) -> ~str { + to_str(var, print_variant, intr) } #[test] @@ -349,7 +340,7 @@ fn print_region(s: ps, region: @ast::region) { ast::re_anon => word_space(s, ~"&"), ast::re_named(name) => { word(s.s, ~"&"); - word(s.s, *name); + print_ident(s, name); } } } @@ -389,7 +380,7 @@ fn print_type_ex(s: ps, &&ty: @ast::ty, print_colons: bool) { fn print_field(s: ps, f: ast::ty_field) { cbox(s, indent_unit); print_mutability(s, f.node.mt.mutbl); - word(s.s, *f.node.ident); + print_ident(s, f.node.ident); word_space(s, ~":"); print_type(s, f.node.mt.ty); end(s); @@ -446,7 +437,8 @@ fn print_item(s: ps, &&item: @ast::item) { match item.node { ast::item_const(ty, expr) => { head(s, ~"const"); - word_space(s, *item.ident + ~":"); + print_ident(s, item.ident); + word_space(s, ~":"); print_type(s, ty); space(s.s); end(s); // end the head-ibox @@ -464,7 +456,8 @@ fn print_item(s: ps, &&item: @ast::item) { } ast::item_mod(_mod) => { head(s, ~"mod"); - word_nbsp(s, *item.ident); + print_ident(s, item.ident); + nbsp(s); bopen(s); print_mod(s, _mod, item.attrs); bclose(s, item.span); @@ -472,7 +465,8 @@ fn print_item(s: ps, &&item: @ast::item) { ast::item_foreign_mod(nmod) => { head(s, ~"extern"); word_nbsp(s, ~"mod"); - word_nbsp(s, *item.ident); + print_ident(s, item.ident); + nbsp(s); bopen(s); print_foreign_mod(s, nmod, item.attrs); bclose(s, item.span); @@ -481,7 +475,7 @@ fn print_item(s: ps, &&item: @ast::item) { ibox(s, indent_unit); ibox(s, 0u); word_nbsp(s, ~"type"); - word(s.s, *item.ident); + print_ident(s, item.ident); print_type_params(s, params); end(s); // end the inner ibox @@ -498,6 +492,7 @@ fn print_item(s: ps, &&item: @ast::item) { head(s, ~"struct"); print_struct(s, struct_def, tps, item.ident, item.span); } + ast::item_impl(tps, traits, ty, methods) => { head(s, ~"impl"); if tps.is_not_empty() { @@ -522,7 +517,7 @@ fn print_item(s: ps, &&item: @ast::item) { } ast::item_trait(tps, traits, methods) => { head(s, ~"trait"); - word(s.s, *item.ident); + print_ident(s, item.ident); print_type_params(s, tps); if vec::len(traits) != 0u { word_space(s, ~":"); @@ -535,7 +530,9 @@ fn print_item(s: ps, &&item: @ast::item) { bclose(s, item.span); } ast::item_mac({node: ast::mac_invoc_tt(pth, tts), _}) => { - head(s, path_to_str(pth) + ~"! " + *item.ident); + print_path(s, pth, false); + head(s, ~"! "); + print_ident(s, item.ident); bopen(s); for tts.each |tt| { print_tt(s, tt); } bclose(s, item.span); @@ -552,7 +549,7 @@ fn print_enum_def(s: ps, enum_definition: ast::enum_def, span: ast::span) { let mut newtype = vec::len(enum_definition.variants) == 1u && - str::eq(ident, enum_definition.variants[0].node.name); + ident == enum_definition.variants[0].node.name; if newtype { match enum_definition.variants[0].node.kind { ast::tuple_variant_kind(args) if args.len() == 1 => {} @@ -566,7 +563,7 @@ fn print_enum_def(s: ps, enum_definition: ast::enum_def, head(s, ~"enum"); } - word(s.s, *ident); + print_ident(s, ident); print_type_params(s, params); space(s.s); if newtype { @@ -599,7 +596,8 @@ fn print_variants(s: ps, variants: ~[ast::variant], span: ast::span) { fn print_struct(s: ps, struct_def: @ast::struct_def, tps: ~[ast::ty_param], ident: ast::ident, span: ast::span) { - word_nbsp(s, *ident); + print_ident(s, ident); + nbsp(s); print_type_params(s, tps); if vec::len(struct_def.traits) != 0u { word_space(s, ~":"); @@ -639,7 +637,7 @@ fn print_struct(s: ps, struct_def: @ast::struct_def, tps: ~[ast::ty_param], if mutability == ast::class_mutable { word_nbsp(s, ~"mut"); } - word(s.s, *ident); + print_ident(s, ident); word_nbsp(s, ~":"); print_type(s, field.node.ty); word(s.s, ~";"); @@ -684,7 +682,8 @@ fn print_tt(s: ps, tt: ast::token_tree) { s.s.token_tree_last_was_ident = false; } ast::tt_nonterminal(_, name) => { - word(s.s, ~"$" + *name); + word(s.s, ~"$"); + print_ident(s, name); s.s.token_tree_last_was_ident = true; } } @@ -693,7 +692,7 @@ fn print_tt(s: ps, tt: ast::token_tree) { fn print_variant(s: ps, v: ast::variant) { match v.node.kind { ast::tuple_variant_kind(args) => { - word(s.s, *v.node.name); + print_ident(s, v.node.name); if vec::len(args) > 0u { popen(s); fn print_variant_arg(s: ps, arg: ast::variant_arg) { @@ -780,7 +779,7 @@ fn print_attribute(s: ps, attr: ast::attribute) { if attr.node.is_sugared_doc { let meta = attr::attr_meta(attr); let comment = attr::get_meta_item_value_str(meta).get(); - word(s.s, *comment); + word(s.s, comment); } else { word(s.s, ~"#["); print_meta_item(s, @attr.node.value); @@ -935,7 +934,8 @@ fn print_mac(s: ps, m: ast::mac) { // FIXME: extension 'body' (#2339) } ast::mac_invoc_tt(pth, tts) => { - head(s, path_to_str(pth) + ~"!"); + print_path(s, pth, false); + head(s, ~"!"); bopen(s); for tts.each() |tt| { print_tt(s, tt); } bclose(s, m.span); @@ -956,7 +956,7 @@ fn print_vstore(s: ps, t: ast::vstore) { ast::re_anon => word(s.s, ~"&"), ast::re_named(name) => { word(s.s, ~"&"); - word(s.s, *name); + print_ident(s, name); word(s.s, ~"."); } } @@ -967,7 +967,7 @@ fn print_expr(s: ps, &&expr: @ast::expr) { fn print_field(s: ps, field: ast::field) { ibox(s, indent_unit); if field.node.mutbl == ast::m_mutbl { word_nbsp(s, ~"mut"); } - word(s.s, *field.node.ident); + print_ident(s, field.node.ident); word_space(s, ~":"); print_expr(s, field.node.expr); end(s); @@ -1125,7 +1125,7 @@ fn print_expr(s: ps, &&expr: @ast::expr) { ast::expr_loop(blk, opt_ident) => { head(s, ~"loop"); space(s.s); - option::iter(opt_ident, |ident| word_space(s, *ident)); + option::iter(opt_ident, |ident| {print_ident(s, ident); space(s.s)}); print_block(s, blk); } ast::expr_match(expr, arms, mode) => { @@ -1270,7 +1270,7 @@ fn print_expr(s: ps, &&expr: @ast::expr) { print_expr_parens_if_not_bot(s, expr); } word(s.s, ~"."); - word(s.s, *id); + print_ident(s, id); if vec::len(tys) > 0u { word(s.s, ~"::<"); commasep(s, inconsistent, tys, print_type); @@ -1294,12 +1294,12 @@ fn print_expr(s: ps, &&expr: @ast::expr) { ast::expr_break(opt_ident) => { word(s.s, ~"break"); space(s.s); - option::iter(opt_ident, |ident| word_space(s, *ident)); + option::iter(opt_ident, |ident| {print_ident(s, ident); space(s.s)}); } ast::expr_again(opt_ident) => { word(s.s, ~"again"); space(s.s); - option::iter(opt_ident, |ident| word_space(s, *ident)); + option::iter(opt_ident, |ident| {print_ident(s, ident); space(s.s)}); } ast::expr_ret(result) => { word(s.s, ~"return"); @@ -1395,7 +1395,7 @@ fn print_decl(s: ps, decl: @ast::decl) { } } -fn print_ident(s: ps, ident: ast::ident) { word(s.s, *ident); } +fn print_ident(s: ps, ident: ast::ident) { word(s.s, *s.intr.get(ident)); } fn print_for_decl(s: ps, loc: @ast::local, coll: @ast::expr) { print_local_decl(s, loc); @@ -1410,7 +1410,7 @@ fn print_path(s: ps, &&path: @ast::path, colons_before_params: bool) { let mut first = true; for path.idents.each |id| { if first { first = false; } else { word(s.s, ~"::"); } - word(s.s, *id); + print_ident(s, id); } if path.rp.is_some() || !path.types.is_empty() { if colons_before_params { word(s.s, ~"::"); } @@ -1471,7 +1471,7 @@ fn print_pat(s: ps, &&pat: @ast::pat) { word(s.s, ~"{"); fn print_field(s: ps, f: ast::field_pat) { cbox(s, indent_unit); - word(s.s, *f.ident); + print_ident(s, f.ident); word_space(s, ~":"); print_pat(s, f.pat); end(s); @@ -1489,7 +1489,7 @@ fn print_pat(s: ps, &&pat: @ast::pat) { word(s.s, ~"{"); fn print_field(s: ps, f: ast::field_pat) { cbox(s, indent_unit); - word(s.s, *f.ident); + print_ident(s, f.ident); word_space(s, ~":"); print_pat(s, f.pat); end(s); @@ -1542,7 +1542,7 @@ fn print_fn(s: ps, decl: ast::fn_decl, name: ast::ident, typarams: ~[ast::ty_param], opt_self_ty: option) { head(s, fn_header_info_to_str(opt_self_ty, decl.purity, none)); - word(s.s, *name); + print_ident(s, name); print_type_params(s, typarams); print_fn_args_and_ret(s, decl, ~[], opt_self_ty); } @@ -1568,7 +1568,7 @@ fn print_fn_args(s: ps, decl: ast::fn_decl, if first { first = false; } else { word_space(s, ~","); } if cap_item.is_move { word_nbsp(s, ~"move") } else { word_nbsp(s, ~"copy") } - word(s.s, *cap_item.name); + print_ident(s, cap_item.name); } end(s); @@ -1638,7 +1638,7 @@ fn print_type_params(s: ps, &¶ms: ~[ast::ty_param]) { if vec::len(params) > 0u { word(s.s, ~"<"); fn printParam(s: ps, param: ast::ty_param) { - word(s.s, *param.ident); + print_ident(s, param.ident); print_bounds(s, param.bounds); } commasep(s, inconsistent, params, printParam); @@ -1649,14 +1649,14 @@ fn print_type_params(s: ps, &¶ms: ~[ast::ty_param]) { fn print_meta_item(s: ps, &&item: @ast::meta_item) { ibox(s, indent_unit); match item.node { - ast::meta_word(name) => word(s.s, *name), + ast::meta_word(name) => word(s.s, name), ast::meta_name_value(name, value) => { - word_space(s, *name); + word_space(s, name); word_space(s, ~"="); print_literal(s, @value); } ast::meta_list(name, items) => { - word(s.s, *name); + word(s.s, name); popen(s); commasep(s, consistent, items, print_meta_item); pclose(s); @@ -1669,7 +1669,8 @@ fn print_view_path(s: ps, &&vp: @ast::view_path) { match vp.node { ast::view_path_simple(ident, path, _) => { if path.idents[vec::len(path.idents)-1u] != ident { - word_space(s, *ident); + print_ident(s, ident); + space(s.s); word_space(s, ~"="); } print_path(s, path, false); @@ -1684,7 +1685,7 @@ fn print_view_path(s: ps, &&vp: @ast::view_path) { print_path(s, path, false); word(s.s, ~"::{"); do commasep(s, inconsistent, idents) |s, w| { - word(s.s, *w.node.name) + print_ident(s, w.node.name); } word(s.s, ~"}"); } @@ -1702,7 +1703,7 @@ fn print_view_item(s: ps, item: @ast::view_item) { match item.node { ast::view_item_use(id, mta, _) => { head(s, ~"use"); - word(s.s, *id); + print_ident(s, id); if vec::len(mta) > 0u { popen(s); commasep(s, consistent, mta, print_meta_item); @@ -1749,10 +1750,12 @@ fn print_arg(s: ps, input: ast::arg) { ibox(s, indent_unit); print_arg_mode(s, input.mode); match input.ty.node { - ast::ty_infer => word(s.s, *input.ident), + ast::ty_infer => print_ident(s, input.ident), _ => { - if str::len(*input.ident) > 0u { - word_space(s, *input.ident + ~":"); + if input.ident != parse::token::special_idents::invalid { + print_ident(s, input.ident); + word(s.s, ~":"); + space(s.s); } print_type(s, input.ty); } @@ -1768,7 +1771,7 @@ fn print_ty_fn(s: ps, opt_proto: option, ibox(s, indent_unit); word(s.s, fn_header_info_to_str(opt_self_ty, decl.purity, opt_proto)); print_bounds(s, bounds); - match id { some(id) => { word(s.s, ~" "); word(s.s, *id); } _ => () } + match id { some(id) => { word(s.s, ~" "); print_ident(s, id); } _ => () } match tps { some(tps) => print_type_params(s, tps), _ => () } zerobreak(s.s); @@ -1880,7 +1883,9 @@ fn print_literal(s: ps, &&lit: @ast::lit) { } } -fn lit_to_str(l: @ast::lit) -> ~str { return to_str(l, print_literal); } +fn lit_to_str(l: @ast::lit) -> ~str { + return to_str(l, print_literal, parse::token::mk_fake_ident_interner()); +} fn next_lit(s: ps, pos: uint) -> option { match s.literals { @@ -1961,9 +1966,9 @@ fn print_string(s: ps, st: ~str) { word(s.s, ~"\""); } -fn to_str(t: T, f: fn@(ps, T)) -> ~str { +fn to_str(t: T, f: fn@(ps, T), intr: ident_interner) -> ~str { let buffer = io::mem_buffer(); - let s = rust_printer(io::mem_buffer_writer(buffer)); + let s = rust_printer(io::mem_buffer_writer(buffer), intr); f(s, t); eof(s.s); io::mem_buffer_str(buffer) diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs index 19b27be83e2..5cecd315ac4 100644 --- a/src/libsyntax/util/interner.rs +++ b/src/libsyntax/util/interner.rs @@ -21,7 +21,7 @@ fn mk(+hasher: hashfn, +eqer: eqfn) -> interner { fn mk_prefill(hasher: hashfn, eqer: eqfn, init: ~[T]) -> interner { - let rv = mk(hasher, eqer); + let rv = mk(copy hasher, copy eqer); for init.each() |v| { rv.intern(v); } return rv; } @@ -30,6 +30,7 @@ fn mk_prefill(hasher: hashfn, eqer: eqfn, /* when traits can extend traits, we should extend index to get [] */ trait interner { fn intern(T) -> uint; + fn gensym(T) -> uint; pure fn get(uint) -> T; fn len() -> uint; } @@ -46,6 +47,12 @@ impl hash_interner: interner { } } } + fn gensym(val: T) -> uint { + let new_idx = self.vect.len(); + // leave out of .map to avoid colliding + self.vect.push(val); + return new_idx; + } // this isn't "pure" in the traditional sense, because it can go from // failing to returning a value as items are interned. But for typestate, diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index f9d861f15e1..51104e97119 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -27,9 +27,9 @@ enum fn_kind { fn name_of_fn(fk: fn_kind) -> ident { match fk { fk_item_fn(name, _) | fk_method(name, _, _) - | fk_ctor(name, _, _, _, _) => /* FIXME (#2543) */ copy name, - fk_anon(*) | fk_fn_block(*) => @~"anon", - fk_dtor(*) => @~"drop" + | fk_ctor(name, _, _, _, _) => /* FIXME (#2543) */ copy name, + fk_anon(*) | fk_fn_block(*) => parse::token::special_idents::anon, + fk_dtor(*) => parse::token::special_idents::dtor } } -- cgit 1.4.1-3-g733a5