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-17 16:17:05 -0700 |
| commit | f4ef0dc3d344bd704258ac4d395709f012b41bde (patch) | |
| tree | 1e8bec93f16ab6a7a4ebc2d5325ba5481e4cc2d9 /src | |
| parent | db020ab63cd51dd4a25cba2d00117f016128762b (diff) | |
Allow old-style syntax extensions to be called with new syntax.
Diffstat (limited to 'src')
| -rw-r--r-- | src/libsyntax/ext/base.rs | 37 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 13 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/earley_parser.rs | 10 |
3 files changed, 60 insertions, 0 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index f6b15ff19d9..79eb71969ff 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -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 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 152b92a4b53..aac2bb2ddf1 100644 --- a/src/libsyntax/ext/tt/earley_parser.rs +++ b/src/libsyntax/ext/tt/earley_parser.rs @@ -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 = ~[]; |
