Allow old-style syntax extensions to be called with new syntax.
This commit is contained in:
parent
db020ab63c
commit
f4ef0dc3d3
3 changed files with 60 additions and 0 deletions
|
@ -244,6 +244,43 @@ fn get_mac_body(cx: ext_ctxt, sp: span, args: ast::mac_body)
|
|||
}
|
||||
}
|
||||
|
||||
fn tt_args_to_original_flavor(cx: ext_ctxt, sp: span, arg: ~[ast::token_tree])
|
||||
-> ast::mac_arg {
|
||||
import ast::{matcher, matcher_, mtc_tok, mtc_rep, mtc_bb};
|
||||
import parse::lexer::{new_tt_reader, tt_reader_as_reader, reader};
|
||||
import tt::earley_parser::{parse_or_else, seq, leaf};
|
||||
|
||||
// these spans won't matter, anyways
|
||||
fn ms(m: matcher_) -> matcher {
|
||||
{node: m, span: {lo: 0u, hi: 0u, expn_info: none}}
|
||||
}
|
||||
|
||||
let argument_gram = ~[ms(mtc_rep(~[
|
||||
ms(mtc_bb(@"arg",@"expr", 0u))
|
||||
], some(parse::token::COMMA), true))];
|
||||
|
||||
let arg_reader = new_tt_reader(cx.parse_sess().span_diagnostic,
|
||||
cx.parse_sess().interner, none, arg);
|
||||
let args =
|
||||
alt parse_or_else(cx.parse_sess(), cx.cfg(), arg_reader as reader,
|
||||
argument_gram).get(@"arg") {
|
||||
@seq(s, _) {
|
||||
do s.map() |lf| {
|
||||
alt lf {
|
||||
@leaf(parse::token::w_expr(arg)) {
|
||||
arg /* whew! list of exprs, here we come! */
|
||||
}
|
||||
_ { fail "badly-structured parse result"; }
|
||||
}
|
||||
}
|
||||
}
|
||||
_ { fail "badly-structured parse result"; }
|
||||
};
|
||||
|
||||
ret some(@{id: parse::next_node_id(cx.parse_sess()),
|
||||
node: ast::expr_vec(args, ast::m_imm), span: sp});
|
||||
}
|
||||
|
||||
//
|
||||
// Local Variables:
|
||||
// mode: rust
|
||||
|
|
|
@ -81,7 +81,20 @@ fn expand_expr(exts: hashmap<~str, syntax_extension>, cx: ext_ctxt,
|
|||
cx.bt_pop();
|
||||
|
||||
(fully_expanded, s)
|
||||
}
|
||||
some(normal({expander: exp, 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);
|
||||
|
||||
cx.bt_push(expanded_from({call_site: s,
|
||||
callie: {name: *extname, span: exp_sp}}));
|
||||
//keep going, outside-in
|
||||
let fully_expanded = fld.fold_expr(expanded).node;
|
||||
cx.bt_pop();
|
||||
|
||||
(fully_expanded, s)
|
||||
}
|
||||
_ {
|
||||
cx.span_fatal(pth.span,
|
||||
|
|
|
@ -101,6 +101,16 @@ enum parse_result {
|
|||
failure(codemap::span, ~str)
|
||||
}
|
||||
|
||||
fn parse_or_else(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader,
|
||||
ms: ~[matcher]) -> hashmap<ident, @arb_depth> {
|
||||
alt parse(sess, cfg, rdr, ms) {
|
||||
success(m) { m }
|
||||
failure(sp, str) {
|
||||
sess.span_diagnostic.span_fatal(sp, str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
|
||||
-> parse_result {
|
||||
let mut cur_eis = ~[];
|
||||
|
|
Loading…
Reference in a new issue