提交 9a4c6698 编写于 作者: G Graydon Hoare

syntax: remove remaining #syntaxext machinery. Close #3516.

上级 e24ae850
...@@ -831,14 +831,6 @@ enum matcher_ { ...@@ -831,14 +831,6 @@ enum matcher_ {
type mac = spanned<mac_>; type mac = spanned<mac_>;
type mac_arg = Option<@expr>;
#[auto_serialize]
#[auto_deserialize]
type mac_body_ = {span: span};
type mac_body = Option<mac_body_>;
#[auto_serialize] #[auto_serialize]
#[auto_deserialize] #[auto_deserialize]
enum mac_ { enum mac_ {
......
...@@ -13,11 +13,8 @@ ...@@ -13,11 +13,8 @@
use diagnostic::span_handler; use diagnostic::span_handler;
use codemap::{CodeMap, span, ExpnInfo, ExpandedFrom}; use codemap::{CodeMap, span, ExpnInfo, ExpandedFrom};
use ast_util::dummy_sp; use ast_util::dummy_sp;
use parse::token;
// obsolete old-style #macro code:
//
// syntax_expander, normal, builtin
//
// new-style macro! tt code: // new-style macro! tt code:
// //
// syntax_expander_tt, syntax_expander_tt_item, mac_result, // syntax_expander_tt, syntax_expander_tt_item, mac_result,
...@@ -27,12 +24,6 @@ ...@@ -27,12 +24,6 @@
// is now probably a redundant AST node, can be merged with // is now probably a redundant AST node, can be merged with
// ast::mac_invoc_tt. // ast::mac_invoc_tt.
// second argument is the span to blame for general argument problems
type syntax_expander_ =
fn@(ext_ctxt, span, ast::mac_arg, ast::mac_body) -> @ast::expr;
// second argument is the origin of the macro, if user-defined
type syntax_expander = {expander: syntax_expander_, span: Option<span>};
type macro_def = {name: ~str, ext: syntax_extension}; type macro_def = {name: ~str, ext: syntax_extension};
type item_decorator = type item_decorator =
...@@ -56,10 +47,7 @@ enum mac_result { ...@@ -56,10 +47,7 @@ enum mac_result {
enum syntax_extension { enum syntax_extension {
// normal() is obsolete, remove when #old_macros go away. // #[auto_serialize] and such
normal(syntax_expander),
// #[auto_serialize] and such. will probably survive death of #old_macros
item_decorator(item_decorator), item_decorator(item_decorator),
// Token-tree expanders // Token-tree expanders
...@@ -73,8 +61,6 @@ enum syntax_extension { ...@@ -73,8 +61,6 @@ enum syntax_extension {
// A temporary hard-coded map of methods for expanding syntax extension // A temporary hard-coded map of methods for expanding syntax extension
// AST nodes into full ASTs // AST nodes into full ASTs
fn syntax_expander_table() -> HashMap<~str, syntax_extension> { fn syntax_expander_table() -> HashMap<~str, syntax_extension> {
fn builtin(f: syntax_expander_) -> syntax_extension
{normal({expander: f, span: None})}
fn builtin_normal_tt(f: syntax_expander_tt_) -> syntax_extension { fn builtin_normal_tt(f: syntax_expander_tt_) -> syntax_extension {
normal_tt({expander: f, span: None}) normal_tt({expander: f, span: None})
} }
...@@ -85,18 +71,19 @@ fn builtin_item_tt(f: syntax_expander_tt_item_) -> syntax_extension { ...@@ -85,18 +71,19 @@ fn builtin_item_tt(f: syntax_expander_tt_item_) -> syntax_extension {
syntax_expanders.insert(~"macro_rules", syntax_expanders.insert(~"macro_rules",
builtin_item_tt( builtin_item_tt(
ext::tt::macro_rules::add_new_extension)); ext::tt::macro_rules::add_new_extension));
syntax_expanders.insert(~"fmt", builtin(ext::fmt::expand_syntax_ext)); syntax_expanders.insert(~"fmt",
builtin_normal_tt(ext::fmt::expand_syntax_ext));
syntax_expanders.insert( syntax_expanders.insert(
~"auto_serialize", ~"auto_serialize",
item_decorator(ext::auto_serialize::expand_auto_serialize)); item_decorator(ext::auto_serialize::expand_auto_serialize));
syntax_expanders.insert( syntax_expanders.insert(
~"auto_deserialize", ~"auto_deserialize",
item_decorator(ext::auto_serialize::expand_auto_deserialize)); item_decorator(ext::auto_serialize::expand_auto_deserialize));
syntax_expanders.insert(~"env", builtin(ext::env::expand_syntax_ext)); syntax_expanders.insert(~"env",
builtin_normal_tt(ext::env::expand_syntax_ext));
syntax_expanders.insert(~"concat_idents", syntax_expanders.insert(~"concat_idents",
builtin(ext::concat_idents::expand_syntax_ext)); builtin_normal_tt(
syntax_expanders.insert(~"ident_to_str", ext::concat_idents::expand_syntax_ext));
builtin(ext::ident_to_str::expand_syntax_ext));
syntax_expanders.insert(~"log_syntax", syntax_expanders.insert(~"log_syntax",
builtin_normal_tt( builtin_normal_tt(
ext::log_syntax::expand_syntax_ext)); ext::log_syntax::expand_syntax_ext));
...@@ -122,21 +109,29 @@ fn builtin_item_tt(f: syntax_expander_tt_item_) -> syntax_extension { ...@@ -122,21 +109,29 @@ fn builtin_item_tt(f: syntax_expander_tt_item_) -> syntax_extension {
builtin_normal_tt(ext::quote::expand_quote_stmt)); builtin_normal_tt(ext::quote::expand_quote_stmt));
syntax_expanders.insert(~"line", syntax_expanders.insert(~"line",
builtin(ext::source_util::expand_line)); builtin_normal_tt(
ext::source_util::expand_line));
syntax_expanders.insert(~"col", syntax_expanders.insert(~"col",
builtin(ext::source_util::expand_col)); builtin_normal_tt(
ext::source_util::expand_col));
syntax_expanders.insert(~"file", syntax_expanders.insert(~"file",
builtin(ext::source_util::expand_file)); builtin_normal_tt(
ext::source_util::expand_file));
syntax_expanders.insert(~"stringify", syntax_expanders.insert(~"stringify",
builtin(ext::source_util::expand_stringify)); builtin_normal_tt(
ext::source_util::expand_stringify));
syntax_expanders.insert(~"include", syntax_expanders.insert(~"include",
builtin(ext::source_util::expand_include)); builtin_normal_tt(
ext::source_util::expand_include));
syntax_expanders.insert(~"include_str", syntax_expanders.insert(~"include_str",
builtin(ext::source_util::expand_include_str)); builtin_normal_tt(
ext::source_util::expand_include_str));
syntax_expanders.insert(~"include_bin", syntax_expanders.insert(~"include_bin",
builtin(ext::source_util::expand_include_bin)); builtin_normal_tt(
ext::source_util::expand_include_bin));
syntax_expanders.insert(~"module_path", syntax_expanders.insert(~"module_path",
builtin(ext::source_util::expand_mod)); builtin_normal_tt(
ext::source_util::expand_mod));
syntax_expanders.insert(~"proto", syntax_expanders.insert(~"proto",
builtin_item_tt(ext::pipes::expand_proto)); builtin_item_tt(ext::pipes::expand_proto));
syntax_expanders.insert( syntax_expanders.insert(
...@@ -292,87 +287,39 @@ fn expr_to_ident(cx: ext_ctxt, ...@@ -292,87 +287,39 @@ fn expr_to_ident(cx: ext_ctxt,
} }
} }
fn get_mac_args_no_max(cx: ext_ctxt, sp: span, arg: ast::mac_arg, fn check_zero_tts(cx: ext_ctxt, sp: span, tts: &[ast::token_tree],
min: uint, name: ~str) -> ~[@ast::expr] { name: &str) {
return get_mac_args(cx, sp, arg, min, None, name); if tts.len() != 0 {
cx.span_fatal(sp, fmt!("%s takes no arguments", name));
}
} }
fn get_mac_args(cx: ext_ctxt, sp: span, arg: ast::mac_arg, fn get_single_str_from_tts(cx: ext_ctxt, sp: span, tts: &[ast::token_tree],
min: uint, max: Option<uint>, name: ~str) -> ~[@ast::expr] { name: &str) -> ~str {
match arg { if tts.len() != 1 {
Some(expr) => match expr.node { cx.span_fatal(sp, fmt!("%s takes 1 argument.", name));
ast::expr_vec(elts, _) => {
let elts_len = vec::len(elts);
match max {
Some(max) if ! (min <= elts_len && elts_len <= max) => {
cx.span_fatal(sp,
fmt!("%s! takes between %u and %u arguments.",
name, min, max));
}
None if ! (min <= elts_len) => {
cx.span_fatal(sp, fmt!("%s! needs at least %u arguments.",
name, min));
}
_ => return elts /* we are good */
}
}
_ => {
cx.span_fatal(sp, fmt!("%s!: malformed invocation", name))
}
},
None => cx.span_fatal(sp, fmt!("%s!: missing arguments", name))
} }
}
fn get_mac_body(cx: ext_ctxt, sp: span, args: ast::mac_body) match tts[0] {
-> ast::mac_body_ ast::tt_tok(_, token::LIT_STR(ident)) => cx.str_of(ident),
{ _ =>
match (args) { cx.span_fatal(sp, fmt!("%s requires a string.", name))
Some(body) => body,
None => cx.span_fatal(sp, ~"missing macro body")
} }
} }
// Massage syntactic form of new-style arguments to internal representation fn get_exprs_from_tts(cx: ext_ctxt, tts: ~[ast::token_tree])
// of old-style macro args, such that old-style macro can be run and invoked -> ~[@ast::expr] {
// using new syntax. This will be obsolete when #old_macros go away. let p = parse::new_parser_from_tts(cx.parse_sess(),
fn tt_args_to_original_flavor(cx: ext_ctxt, sp: span, arg: ~[ast::token_tree]) cx.cfg(),
-> ast::mac_arg { tts);
use ast::{matcher, matcher_, match_tok, match_seq, match_nonterminal}; let mut es = ~[];
use parse::lexer::{new_tt_reader, reader}; while p.token != token::EOF {
use tt::macro_parser::{parse_or_else, matched_seq, if es.len() != 0 {
matched_nonterminal}; p.eat(token::COMMA);
}
// these spans won't matter, anyways es.push(p.parse_expr());
fn ms(m: matcher_) -> matcher {
{node: m, span: dummy_sp()}
} }
let arg_nm = cx.parse_sess().interner.gensym(@~"arg"); es
let argument_gram = ~[ms(match_seq(~[
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_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"
};
return Some(@{id: parse::next_node_id(cx.parse_sess()),
callee_id: parse::next_node_id(cx.parse_sess()),
node: ast::expr_vec(args, ast::m_imm), span: sp});
} }
// //
......
...@@ -10,19 +10,32 @@ ...@@ -10,19 +10,32 @@
use base::*; use base::*;
fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg, fn expand_syntax_ext(cx: ext_ctxt, sp: span, tts: ~[ast::token_tree])
_body: ast::mac_body) -> @ast::expr { -> base::mac_result {
let args = get_mac_args_no_max(cx,sp,arg,1u,~"concat_idents");
let mut res_str = ~""; let mut res_str = ~"";
for args.each |e| { for tts.eachi |i, e| {
res_str += *cx.parse_sess().interner.get( if i & 1 == 1 {
expr_to_ident(cx, *e, ~"expected an ident")); match *e {
ast::tt_tok(_, token::COMMA) => (),
_ => cx.span_fatal(sp, ~"concat_idents! \
expecting comma.")
}
} else {
match *e {
ast::tt_tok(_, token::IDENT(ident,_)) =>
res_str += cx.str_of(ident),
_ => cx.span_fatal(sp, ~"concat_idents! \
requires ident args.")
}
}
} }
let res = cx.parse_sess().interner.intern(@res_str); let res = cx.parse_sess().interner.intern(@res_str);
return @{id: cx.next_id(), let e = @{id: cx.next_id(),
callee_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,
rp: None, types: ~[]}), idents: ~[res],
span: sp}; rp: None, types: ~[]}),
span: sp};
mr_expr(e)
} }
...@@ -18,18 +18,19 @@ ...@@ -18,18 +18,19 @@
use build::mk_uniq_str; use build::mk_uniq_str;
export expand_syntax_ext; export expand_syntax_ext;
fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg, fn expand_syntax_ext(cx: ext_ctxt, sp: span, tts: ~[ast::token_tree])
_body: ast::mac_body) -> @ast::expr { -> base::mac_result {
let args = get_mac_args(cx, sp, arg, 1u, option::Some(1u), ~"env");
let var = get_single_str_from_tts(cx, sp, tts, "env!");
// FIXME (#2248): if this was more thorough it would manufacture an // FIXME (#2248): if this was more thorough it would manufacture an
// Option<str> rather than just an maybe-empty string. // Option<str> rather than just an maybe-empty string.
let var = expr_to_str(cx, args[0], ~"env! requires a string"); let e = match os::getenv(var) {
match os::getenv(var) { option::None => mk_uniq_str(cx, sp, ~""),
option::None => return mk_uniq_str(cx, sp, ~""), option::Some(ref s) => mk_uniq_str(cx, sp, (*s))
option::Some(ref s) => return mk_uniq_str(cx, sp, (*s)) };
} mr_expr(e)
} }
// //
......
...@@ -62,21 +62,6 @@ fn expand_expr(exts: HashMap<~str, syntax_extension>, cx: ext_ctxt, ...@@ -62,21 +62,6 @@ fn expand_expr(exts: HashMap<~str, syntax_extension>, cx: ext_ctxt,
(fully_expanded, s) (fully_expanded, s)
} }
Some(normal({expander: exp, span: exp_sp})) => {
cx.bt_push(ExpandedFrom({call_site: s,
callie: {name: *extname, span: exp_sp}}));
//convert the new-style invoc for the old-style macro
let arg = base::tt_args_to_original_flavor(cx, pth.span,
(*tts));
let expanded = exp(cx, (*mac).span, arg, None);
//keep going, outside-in
let fully_expanded = fld.fold_expr(expanded).node;
cx.bt_pop();
(fully_expanded, s)
}
_ => { _ => {
cx.span_fatal(pth.span, cx.span_fatal(pth.span,
fmt!("'%s' is not a tt-style macro", fmt!("'%s' is not a tt-style macro",
...@@ -119,8 +104,7 @@ fn expand_mod_items(exts: HashMap<~str, syntax_extension>, cx: ext_ctxt, ...@@ -119,8 +104,7 @@ fn expand_mod_items(exts: HashMap<~str, syntax_extension>, cx: ext_ctxt,
ast::meta_list(ref n, _) => (*n) ast::meta_list(ref n, _) => (*n)
}; };
match exts.find(mname) { match exts.find(mname) {
None | Some(normal(_)) None | Some(normal_tt(_)) | Some(item_tt(*)) => items,
| Some(normal_tt(_)) | Some(item_tt(*)) => items,
Some(item_decorator(dec_fn)) => { Some(item_decorator(dec_fn)) => {
cx.bt_push(ExpandedFrom({call_site: attr.span, cx.bt_push(ExpandedFrom({call_site: attr.span,
callie: {name: copy mname, callie: {name: copy mname,
...@@ -262,23 +246,6 @@ fn expand_stmt(exts: HashMap<~str, syntax_extension>, cx: ext_ctxt, ...@@ -262,23 +246,6 @@ fn expand_stmt(exts: HashMap<~str, syntax_extension>, cx: ext_ctxt,
(fully_expanded, sp) (fully_expanded, sp)
} }
Some(normal({expander: exp, span: exp_sp})) => {
cx.bt_push(ExpandedFrom({call_site: sp,
callie: {name: *extname,
span: exp_sp}}));
//convert the new-style invoc for the old-style macro
let arg = base::tt_args_to_original_flavor(cx, pth.span, tts);
let exp_expr = exp(cx, mac.span, arg, None);
let expanded = @{node: stmt_expr(exp_expr, cx.next_id()),
span: exp_expr.span};
//keep going, outside-in
let fully_expanded = fld.fold_stmt(expanded).node;
cx.bt_pop();
(fully_expanded, sp)
}
_ => { _ => {
cx.span_fatal(pth.span, cx.span_fatal(pth.span,
fmt!("'%s' is not a tt-style macro", *extname)) fmt!("'%s' is not a tt-style macro", *extname))
......
...@@ -21,9 +21,12 @@ ...@@ -21,9 +21,12 @@
use ext::build::*; use ext::build::*;
export expand_syntax_ext; export expand_syntax_ext;
fn expand_syntax_ext(cx: ext_ctxt, sp: span, arg: ast::mac_arg, fn expand_syntax_ext(cx: ext_ctxt, sp: span, tts: ~[ast::token_tree])
_body: ast::mac_body) -> @ast::expr { -> base::mac_result {
let args = get_mac_args_no_max(cx, sp, arg, 1u, ~"fmt"); let args = get_exprs_from_tts(cx, copy tts);
if args.len() == 0 {
cx.span_fatal(sp, "fmt! takes at least 1 argument.");
}
let fmt = let fmt =
expr_to_str(cx, args[0], expr_to_str(cx, args[0],
~"first argument to fmt! must be a string literal."); ~"first argument to fmt! must be a string literal.");
...@@ -37,7 +40,7 @@ fn parse_fmt_err_(cx: ext_ctxt, sp: span, msg: &str) -> ! { ...@@ -37,7 +40,7 @@ fn parse_fmt_err_(cx: ext_ctxt, sp: span, msg: &str) -> ! {
parse_fmt_err_(cx, fmtspan, s) parse_fmt_err_(cx, fmtspan, s)
}; };
let pieces = parse_fmt_string(fmt, parse_fmt_err); let pieces = parse_fmt_string(fmt, parse_fmt_err);
return pieces_to_expr(cx, sp, pieces, args); mr_expr(pieces_to_expr(cx, sp, pieces, args))
} }
// FIXME (#2249): A lot of these functions for producing expressions can // FIXME (#2249): A lot of these functions for producing expressions can
......
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use base::*;
use build::mk_uniq_str;
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, *cx.parse_sess().interner.get(
expr_to_ident(cx, args[0u], ~"expected an ident")));
}
...@@ -23,63 +23,58 @@ ...@@ -23,63 +23,58 @@
export expand_include_bin; export expand_include_bin;
/* line!(): expands to the current line number */ /* line!(): expands to the current line number */
fn expand_line(cx: ext_ctxt, sp: span, arg: ast::mac_arg, fn expand_line(cx: ext_ctxt, sp: span, tts: ~[ast::token_tree])
_body: ast::mac_body) -> @ast::expr { -> base::mac_result {
get_mac_args(cx, sp, arg, 0u, option::Some(0u), ~"line"); base::check_zero_tts(cx, sp, tts, "line!");
let loc = cx.codemap().lookup_char_pos(sp.lo); let loc = cx.codemap().lookup_char_pos(sp.lo);
return mk_uint(cx, sp, loc.line); base::mr_expr(mk_uint(cx, sp, loc.line))
} }
/* col!(): expands to the current column number */ /* col!(): expands to the current column number */
fn expand_col(cx: ext_ctxt, sp: span, arg: ast::mac_arg, fn expand_col(cx: ext_ctxt, sp: span, tts: ~[ast::token_tree])
_body: ast::mac_body) -> @ast::expr { -> base::mac_result {
get_mac_args(cx, sp, arg, 0u, option::Some(0u), ~"col"); base::check_zero_tts(cx, sp, tts, "col!");
let loc = cx.codemap().lookup_char_pos(sp.lo); let loc = cx.codemap().lookup_char_pos(sp.lo);
return mk_uint(cx, sp, loc.col.to_uint()); base::mr_expr(mk_uint(cx, sp, loc.col.to_uint()))
} }
/* file!(): expands to the current filename */ /* file!(): expands to the current filename */
/* The filemap (`loc.file`) contains a bunch more information we could spit /* The filemap (`loc.file`) contains a bunch more information we could spit
* out if we wanted. */ * out if we wanted. */
fn expand_file(cx: ext_ctxt, sp: span, arg: ast::mac_arg, fn expand_file(cx: ext_ctxt, sp: span, tts: ~[ast::token_tree])
_body: ast::mac_body) -> @ast::expr { -> base::mac_result {
get_mac_args(cx, sp, arg, 0u, option::Some(0u), ~"file"); base::check_zero_tts(cx, sp, tts, "file!");
let Loc { file: @FileMap { name: filename, _ }, _ } = let Loc { file: @FileMap { name: filename, _ }, _ } =
cx.codemap().lookup_char_pos(sp.lo); cx.codemap().lookup_char_pos(sp.lo);
return mk_uniq_str(cx, sp, filename); base::mr_expr(mk_uniq_str(cx, sp, filename))
} }
fn expand_stringify(cx: ext_ctxt, sp: span, arg: ast::mac_arg, fn expand_stringify(cx: ext_ctxt, sp: span, tts: ~[ast::token_tree])
_body: ast::mac_body) -> @ast::expr { -> base::mac_result {
let args = get_mac_args(cx, sp, arg, 1u, option::Some(1u), ~"stringify"); let s = pprust::tts_to_str(tts, cx.parse_sess().interner);
let s = pprust::expr_to_str(args[0], cx.parse_sess().interner); base::mr_expr(mk_uniq_str(cx, sp, s))
return mk_uniq_str(cx, sp, s);
} }
fn expand_mod(cx: ext_ctxt, sp: span, arg: ast::mac_arg, _body: ast::mac_body) fn expand_mod(cx: ext_ctxt, sp: span, tts: ~[ast::token_tree])
-> @ast::expr { -> base::mac_result {
get_mac_args(cx, sp, arg, 0u, option::Some(0u), ~"file"); base::check_zero_tts(cx, sp, tts, "module_path!");
return mk_uniq_str(cx, sp, base::mr_expr(mk_uniq_str(cx, sp,
str::connect(cx.mod_path().map( str::connect(cx.mod_path().map(
|x| cx.str_of(*x)), ~"::")); |x| cx.str_of(*x)), ~"::")))
} }
fn expand_include(cx: ext_ctxt, sp: span, arg: ast::mac_arg, fn expand_include(cx: ext_ctxt, sp: span, tts: ~[ast::token_tree])
_body: ast::mac_body) -> @ast::expr { -> base::mac_result {
let args = get_mac_args(cx, sp, arg, 1u, option::Some(1u), ~"include"); let file = get_single_str_from_tts(cx, sp, tts, "include!");
let file = expr_to_str(cx, args[0], ~"include_str! requires a string");
let p = parse::new_sub_parser_from_file( let p = parse::new_sub_parser_from_file(
cx.parse_sess(), cx.cfg(), cx.parse_sess(), cx.cfg(),
&res_rel_file(cx, sp, &Path(file)), sp); &res_rel_file(cx, sp, &Path(file)), sp);
return p.parse_expr(); base::mr_expr(p.parse_expr())
} }
fn expand_include_str(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg, fn expand_include_str(cx: ext_ctxt, sp: span, tts: ~[ast::token_tree])
_body: ast::mac_body) -> @ast::expr { -> base::mac_result {
let args = get_mac_args(cx,sp,arg,1u,option::Some(1u),~"include_str"); let file = get_single_str_from_tts(cx, sp, tts, "include_str!");
let file = expr_to_str(cx, args[0], ~"include_str! requires a string");
let res = io::read_whole_file_str(&res_rel_file(cx, sp, &Path(file))); let res = io::read_whole_file_str(&res_rel_file(cx, sp, &Path(file)));
match res { match res {
result::Ok(_) => { /* Continue. */ } result::Ok(_) => { /* Continue. */ }
...@@ -88,21 +83,18 @@ fn expand_include_str(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg, ...@@ -88,21 +83,18 @@ fn expand_include_str(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg,
} }
} }
return mk_uniq_str(cx, sp, result::unwrap(res)); base::mr_expr(mk_uniq_str(cx, sp, result::unwrap(res)))
} }
fn expand_include_bin(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg, fn expand_include_bin(cx: ext_ctxt, sp: span, tts: ~[ast::token_tree])
_body: ast::mac_body) -> @ast::expr { -> base::mac_result {
let args = get_mac_args(cx,sp,arg,1u,option::Some(1u),~"include_bin"); let file = get_single_str_from_tts(cx, sp, tts, "include_bin!");
let file = expr_to_str(cx, args[0], ~"include_bin! requires a string");
match io::read_whole_file(&res_rel_file(cx, sp, &Path(file))) { match io::read_whole_file(&res_rel_file(cx, sp, &Path(file))) {
result::Ok(src) => { result::Ok(src) => {
let u8_exprs = vec::map(src, |char| { let u8_exprs = vec::map(src, |char| {
mk_u8(cx, sp, *char) mk_u8(cx, sp, *char)
}); });
return mk_base_vec_e(cx, sp, u8_exprs); base::mr_expr(mk_base_vec_e(cx, sp, u8_exprs))
} }
result::Err(ref e) => { result::Err(ref e) => {
cx.parse_sess().span_diagnostic.handler().fatal((*e)) cx.parse_sess().span_diagnostic.handler().fatal((*e))
......
...@@ -154,8 +154,7 @@ fn mk_printer(out: io::Writer, linewidth: uint) -> printer { ...@@ -154,8 +154,7 @@ fn mk_printer(out: io::Writer, linewidth: uint) -> printer {
mut top: 0, mut top: 0,
mut bottom: 0, mut bottom: 0,
print_stack: DVec(), print_stack: DVec(),
mut pending_indentation: 0, mut pending_indentation: 0 })
mut token_tree_last_was_ident: false})
} }
...@@ -261,7 +260,6 @@ fn mk_printer(out: io::Writer, linewidth: uint) -> printer { ...@@ -261,7 +260,6 @@ fn mk_printer(out: io::Writer, linewidth: uint) -> printer {
print_stack: DVec<print_stack_elt>, print_stack: DVec<print_stack_elt>,
// buffered indentation to avoid writing trailing whitespace // buffered indentation to avoid writing trailing whitespace
mut pending_indentation: int, mut pending_indentation: int,
mut token_tree_last_was_ident: bool
}; };
enum printer { enum printer {
......
...@@ -118,6 +118,10 @@ fn tt_to_str(tt: ast::token_tree, intr: @ident_interner) -> ~str { ...@@ -118,6 +118,10 @@ fn tt_to_str(tt: ast::token_tree, intr: @ident_interner) -> ~str {
to_str(tt, print_tt, intr) to_str(tt, print_tt, intr)
} }
fn tts_to_str(tts: &[ast::token_tree], intr: @ident_interner) -> ~str {
to_str(tts, print_tts, intr)
}
fn stmt_to_str(s: ast::stmt, intr: @ident_interner) -> ~str { fn stmt_to_str(s: ast::stmt, intr: @ident_interner) -> ~str {
to_str(s, print_stmt, intr) to_str(s, print_stmt, intr)
} }
...@@ -584,9 +588,7 @@ fn print_item(s: ps, &&item: @ast::item) { ...@@ -584,9 +588,7 @@ fn print_item(s: ps, &&item: @ast::item) {
print_ident(s, item.ident); print_ident(s, item.ident);
cbox(s, indent_unit); cbox(s, indent_unit);
popen(s); popen(s);
for (*tts).each |tt| { print_tts(s, *tts);
print_tt(s, *tt);
}
pclose(s); pclose(s);
end(s); end(s);
} }
...@@ -736,17 +738,9 @@ fn print_struct(s: ps, struct_def: @ast::struct_def, tps: ~[ast::ty_param], ...@@ -736,17 +738,9 @@ fn print_struct(s: ps, struct_def: @ast::struct_def, tps: ~[ast::ty_param],
/// expression arguments as expressions). It can be done! I think. /// expression arguments as expressions). It can be done! I think.
fn print_tt(s: ps, tt: ast::token_tree) { fn print_tt(s: ps, tt: ast::token_tree) {
match tt { match tt {
ast::tt_delim(ref tts) => ast::tt_delim(ref tts) => print_tts(s, *tts),
for (*tts).each() |tt_elt| { print_tt(s, *tt_elt); },
ast::tt_tok(_, ref tk) => { ast::tt_tok(_, ref tk) => {
match (*tk) { word(s.s, parse::token::to_str(s.intr, (*tk)));
parse::token::IDENT(*) => { // don't let idents run together
if s.s.token_tree_last_was_ident { word(s.s, ~" ") }
s.s.token_tree_last_was_ident = true;
}
_ => { s.s.token_tree_last_was_ident = false; }
}
word(s.s, parse::token::to_str(s.intr, (*tk)));
} }
ast::tt_seq(_, ref tts, ref sep, zerok) => { ast::tt_seq(_, ref tts, ref sep, zerok) => {
word(s.s, ~"$("); word(s.s, ~"$(");
...@@ -757,16 +751,25 @@ fn print_tt(s: ps, tt: ast::token_tree) { ...@@ -757,16 +751,25 @@ fn print_tt(s: ps, tt: ast::token_tree) {
None => () None => ()
} }
word(s.s, if zerok { ~"*" } else { ~"+" }); word(s.s, if zerok { ~"*" } else { ~"+" });
s.s.token_tree_last_was_ident = false;
} }
ast::tt_nonterminal(_, name) => { ast::tt_nonterminal(_, name) => {
word(s.s, ~"$"); word(s.s, ~"$");
print_ident(s, name); print_ident(s, name);
s.s.token_tree_last_was_ident = true;
} }
} }
} }
fn print_tts(s: ps, &&tts: &[ast::token_tree]) {
ibox(s, 0);
for tts.eachi |i, tt| {
if i != 0 {
space(s.s);
}
print_tt(s, *tt);
}
end(s);
}
fn print_variant(s: ps, v: ast::variant) { fn print_variant(s: ps, v: ast::variant) {
print_visibility(s, v.node.vis); print_visibility(s, v.node.vis);
match v.node.kind { match v.node.kind {
...@@ -1001,7 +1004,7 @@ fn print_mac(s: ps, m: ast::mac) { ...@@ -1001,7 +1004,7 @@ fn print_mac(s: ps, m: ast::mac) {
print_path(s, pth, false); print_path(s, pth, false);
word(s.s, ~"!"); word(s.s, ~"!");
popen(s); popen(s);
for (*tts).each() |tt| { print_tt(s, *tt); } print_tts(s, *tts);
pclose(s); pclose(s);
} }
} }
......
...@@ -109,9 +109,6 @@ mod ext { ...@@ -109,9 +109,6 @@ mod ext {
#[path = "ext/concat_idents.rs"] #[path = "ext/concat_idents.rs"]
mod concat_idents; mod concat_idents;
#[legacy_exports] #[legacy_exports]
#[path = "ext/ident_to_str.rs"]
mod ident_to_str;
#[legacy_exports]
#[path = "ext/log_syntax.rs"] #[path = "ext/log_syntax.rs"]
mod log_syntax; mod log_syntax;
#[legacy_exports] #[legacy_exports]
......
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:expected a syntax expander name
fn main() {
#();
}
...@@ -8,6 +8,6 @@ ...@@ -8,6 +8,6 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
// error-pattern: env! takes between 1 and 1 arguments // error-pattern: env! takes 1 argument
fn main() { env!(); } fn main() { env!(); }
...@@ -8,6 +8,6 @@ ...@@ -8,6 +8,6 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
// error-pattern: env! takes between 1 and 1 arguments // error-pattern: env! takes 1 argument
fn main() { env!("one", "two"); } fn main() { env!("one", "two"); }
...@@ -8,6 +8,6 @@ ...@@ -8,6 +8,6 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
// error-pattern:fmt! needs at least 1 arguments // error-pattern:fmt! takes at least 1 argument
fn main() { fmt!(); } fn main() { fmt!(); }
...@@ -16,7 +16,7 @@ struct cat { ...@@ -16,7 +16,7 @@ struct cat {
impl cat: Drop { impl cat: Drop {
#[cat_dropper] #[cat_dropper]
fn finalize(&self) { error!("%s landed on hir feet",self.name); } fn finalize(&self) { error!("%s landed on hir feet" , self . name); }
} }
......
...@@ -13,6 +13,6 @@ fn main() { ...@@ -13,6 +13,6 @@ fn main() {
let asdf_fdsa = ~"<.<"; let asdf_fdsa = ~"<.<";
assert (concat_idents!(asd, f_f, dsa) == ~"<.<"); assert (concat_idents!(asd, f_f, dsa) == ~"<.<");
assert (ident_to_str!(use_mention_distinction) == assert (stringify!(use_mention_distinction) ==
~"use_mention_distinction"); ~"use_mention_distinction");
} }
...@@ -24,7 +24,7 @@ fn main() { ...@@ -24,7 +24,7 @@ fn main() {
assert(line!() == 24); assert(line!() == 24);
assert(col!() == 11); assert(col!() == 11);
assert(file!().ends_with(~"syntax-extension-source-utils.rs")); assert(file!().ends_with(~"syntax-extension-source-utils.rs"));
assert(stringify!((2*3) + 5) == ~"(2 * 3) + 5"); assert(stringify!((2*3) + 5) == ~"( 2 * 3 ) + 5");
assert(include!("syntax-extension-source-utils-files/includeme.fragment") assert(include!("syntax-extension-source-utils-files/includeme.fragment")
== ~"victory robot 6"); == ~"victory robot 6");
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册