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/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 ++-- 21 files changed, 298 insertions(+), 244 deletions(-) (limited to 'src/libsyntax/ext') 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)}); } } } -- cgit 1.4.1-3-g733a5