diff options
| author | Paul Stansifer <paul.stansifer@gmail.com> | 2012-07-12 17:59:59 -0700 |
|---|---|---|
| committer | Paul Stansifer <paul.stansifer@gmail.com> | 2012-07-26 09:52:21 -0700 |
| commit | 7f5fbd4f9d2f9f60240d80a103d00595328042cd (patch) | |
| tree | cf83cd174f626026d37dae6a0f2f4ebed9f7e2f4 /src/libsyntax | |
| parent | 60d682b57759a4fd3b6f666963e40ba457c2e4fc (diff) | |
| download | rust-7f5fbd4f9d2f9f60240d80a103d00595328042cd.tar.gz rust-7f5fbd4f9d2f9f60240d80a103d00595328042cd.zip | |
Allow old-style syntax extensions to be called with new syntax.
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ext/base.rs | 38 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 13 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/earley_parser.rs | 10 |
3 files changed, 61 insertions, 0 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index f6b15ff19d9..544b1316354 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -244,6 +244,44 @@ 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, 0u, 1u))]; + + 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()), + callee_id: parse::next_node_id(cx.parse_sess()), + node: ast::expr_vec(args, ast::m_imm), span: sp}); +} + // // Local Variables: // mode: rust diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 2a41afc9743..c470daaf022 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -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, diff --git a/src/libsyntax/ext/tt/earley_parser.rs b/src/libsyntax/ext/tt/earley_parser.rs index 4a710e7d04f..54e5a1b5867 100644 --- a/src/libsyntax/ext/tt/earley_parser.rs +++ b/src/libsyntax/ext/tt/earley_parser.rs @@ -110,6 +110,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 = ~[]; |
