1
Fork 0

quote_* macros no longer need to be capturing

This is actually almost a problem, because those were my poster-child
macros for "here's how to implement a capturing macro." Following this
change, there will be no macros that use capturing; this will probably
make life unpleasant for the first person that wants to implement a
capturing macro. I should probably create a dummy_capturing macro,
just to show how it works.
This commit is contained in:
John Clements 2013-09-05 10:30:23 -07:00
parent 4664d3320d
commit 1ecc1e51c0
3 changed files with 19 additions and 91 deletions

View file

@ -185,17 +185,18 @@ pub fn syntax_expander_table() -> SyntaxEnv {
// Quasi-quoting expanders
syntax_expanders.insert(intern(&"quote_tokens"),
@SE(NormalTT(ext::quote::expand_quote_tokens, None)));
builtin_normal_tt_no_ctxt(
ext::quote::expand_quote_tokens));
syntax_expanders.insert(intern(&"quote_expr"),
@SE(NormalTT(ext::quote::expand_quote_expr, None)));
builtin_normal_tt_no_ctxt(ext::quote::expand_quote_expr));
syntax_expanders.insert(intern(&"quote_ty"),
@SE(NormalTT(ext::quote::expand_quote_ty, None)));
builtin_normal_tt_no_ctxt(ext::quote::expand_quote_ty));
syntax_expanders.insert(intern(&"quote_item"),
@SE(NormalTT(ext::quote::expand_quote_item, None)));
builtin_normal_tt_no_ctxt(ext::quote::expand_quote_item));
syntax_expanders.insert(intern(&"quote_pat"),
@SE(NormalTT(ext::quote::expand_quote_pat, None)));
builtin_normal_tt_no_ctxt(ext::quote::expand_quote_pat));
syntax_expanders.insert(intern(&"quote_stmt"),
@SE(NormalTT(ext::quote::expand_quote_stmt, None)));
builtin_normal_tt_no_ctxt(ext::quote::expand_quote_stmt));
syntax_expanders.insert(intern(&"line"),
builtin_normal_tt_no_ctxt(

View file

@ -1856,58 +1856,6 @@ mod test {
}
}
#[test] fn quote_expr_test() {
quote_ext_cx_test(@"fn main(){let ext_cx = 13; quote_expr!(dontcare);}");
}
#[test] fn quote_item_test() {
quote_ext_cx_test(@"fn main(){let ext_cx = 13; quote_item!(dontcare);}");
}
#[test] fn quote_pat_test() {
quote_ext_cx_test(@"fn main(){let ext_cx = 13; quote_pat!(dontcare);}");
}
#[test] fn quote_ty_test() {
quote_ext_cx_test(@"fn main(){let ext_cx = 13; quote_ty!(dontcare);}");
}
#[test] fn quote_tokens_test() {
quote_ext_cx_test(@"fn main(){let ext_cx = 13; quote_tokens!(dontcare);}");
}
fn quote_ext_cx_test(crate_str : @str) {
let crate = expand_crate_str(crate_str);
// find the ext_cx binding
let bindings = @mut ~[];
visit::walk_crate(&mut new_name_finder(bindings), crate, ());
let cxbinds : ~[&ast::Ident] =
bindings.iter().filter(|b|{@"ext_cx" == (ident_to_str(*b))}).collect();
let cxbind = match cxbinds {
[b] => b,
_ => fail!("expected just one binding for ext_cx")
};
let resolved_binding = mtwt_resolve(*cxbind);
// find all the ext_cx varrefs:
let varrefs = @mut ~[];
visit::walk_crate(&mut new_path_finder(varrefs), crate, ());
// the ext_cx binding should bind all of the ext_cx varrefs:
for (idx,v) in varrefs.iter().filter(|p|{ p.segments.len() == 1
&& (@"ext_cx" == (ident_to_str(&p.segments[0].identifier)))
}).enumerate() {
if (mtwt_resolve(v.segments[0].identifier) != resolved_binding) {
std::io::println("uh oh, ext_cx binding didn't match ext_cx varref:");
std::io::println(fmt!("this is varref # %?",idx));
std::io::println(fmt!("binding: %?",cxbind));
std::io::println(fmt!("resolves to: %?",resolved_binding));
std::io::println(fmt!("varref: %?",v.segments[0]));
std::io::println(fmt!("resolves to: %?",mtwt_resolve(v.segments[0].identifier)));
let table = get_sctable();
std::io::println("SC table:");
for (idx,val) in table.table.iter().enumerate() {
std::io::println(fmt!("%4u : %?",idx,val));
}
}
assert_eq!(mtwt_resolve(v.segments[0].identifier),resolved_binding);
};
}
#[test] fn fmt_in_macro_used_inside_module_macro() {
let crate_str = @"macro_rules! fmt_wrap(($b:expr)=>(fmt!(\"left: %?\", $b)))
macro_rules! foo_module (() => (mod generated { fn a() { let xx = 147; fmt_wrap!(xx);}}))

View file

@ -12,7 +12,6 @@ use ast;
use codemap::{BytePos, Pos, Span};
use ext::base::ExtCtxt;
use ext::base;
use ext::expand;
use ext::build::AstBuilder;
use parse::token::*;
use parse::token;
@ -292,73 +291,53 @@ pub mod rt {
pub fn expand_quote_tokens(cx: @ExtCtxt,
sp: Span,
tts: &[ast::token_tree],
ctxt: ast::SyntaxContext) -> base::MacResult {
tts: &[ast::token_tree]) -> base::MacResult {
let (cx_expr, expr) = expand_tts(cx, sp, tts);
let expanded = expand_wrapper(cx, sp, cx_expr, expr);
// repaint the expanded code so it's as though it was the original text.
let repainted = expand::replace_ctxts(expanded,ctxt);
base::MRExpr(repainted)
base::MRExpr(expanded)
}
pub fn expand_quote_expr(cx: @ExtCtxt,
sp: Span,
tts: &[ast::token_tree],
ctxt: ast::SyntaxContext) -> base::MacResult {
tts: &[ast::token_tree]) -> base::MacResult {
let expanded = expand_parse_call(cx, sp, "parse_expr", ~[], tts);
// repaint the expanded code so it's as though it was the original text.
let repainted = expand::replace_ctxts(expanded,ctxt);
base::MRExpr(repainted)
base::MRExpr(expanded)
}
// these probably need to be capturing, too...
pub fn expand_quote_item(cx: @ExtCtxt,
sp: Span,
tts: &[ast::token_tree],
ctxt: ast::SyntaxContext) -> base::MacResult {
tts: &[ast::token_tree]) -> base::MacResult {
let e_attrs = cx.expr_vec_uniq(sp, ~[]);
let expanded = expand_parse_call(cx, sp, "parse_item",
~[e_attrs], tts);
// repaint the expanded code so it's as though it was the original text.
let repainted = expand::replace_ctxts(expanded,ctxt);
base::MRExpr(repainted)
base::MRExpr(expanded)
}
pub fn expand_quote_pat(cx: @ExtCtxt,
sp: Span,
tts: &[ast::token_tree],
ctxt: ast::SyntaxContext) -> base::MacResult {
tts: &[ast::token_tree]) -> base::MacResult {
let e_refutable = cx.expr_lit(sp, ast::lit_bool(true));
let expanded = expand_parse_call(cx, sp, "parse_pat",
~[e_refutable], tts);
// repaint the expanded code so it's as though it was the original text.
let repainted = expand::replace_ctxts(expanded,ctxt);
base::MRExpr(repainted)
base::MRExpr(expanded)
}
pub fn expand_quote_ty(cx: @ExtCtxt,
sp: Span,
tts: &[ast::token_tree],
ctxt: ast::SyntaxContext) -> base::MacResult {
tts: &[ast::token_tree]) -> base::MacResult {
let e_param_colons = cx.expr_lit(sp, ast::lit_bool(false));
let expanded = expand_parse_call(cx, sp, "parse_ty",
~[e_param_colons], tts);
// repaint the expanded code so it's as though it was the original text.
let repainted = expand::replace_ctxts(expanded,ctxt);
base::MRExpr(repainted)
base::MRExpr(expanded)
}
pub fn expand_quote_stmt(cx: @ExtCtxt,
sp: Span,
tts: &[ast::token_tree],
ctxt: ast::SyntaxContext) -> base::MacResult {
tts: &[ast::token_tree]) -> base::MacResult {
let e_attrs = cx.expr_vec_uniq(sp, ~[]);
let expanded = expand_parse_call(cx, sp, "parse_stmt",
~[e_attrs], tts);
// repaint the expanded code so it's as though it was the original text.
let repainted = expand::replace_ctxts(expanded,ctxt);
base::MRExpr(repainted)
base::MRExpr(expanded)
}
fn ids_ext(strs: ~[~str]) -> ~[ast::Ident] {