Skip to content

Commit

Permalink
quote_* macros no longer need to be capturing
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jbclements committed Sep 6, 2013
1 parent 4664d33 commit 1ecc1e5
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 91 deletions.
13 changes: 7 additions & 6 deletions src/libsyntax/ext/base.rs
Expand Up @@ -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(
Expand Down
52 changes: 0 additions & 52 deletions src/libsyntax/ext/expand.rs
Expand Up @@ -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);}}))
Expand Down
45 changes: 12 additions & 33 deletions src/libsyntax/ext/quote.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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] {
Expand Down

0 comments on commit 1ecc1e5

Please sign in to comment.