Stop passing duplicate parameters in expand

This commit is contained in:
Steven Fackler 2013-12-27 17:43:01 -07:00
parent 711d5106bc
commit 933def408c
2 changed files with 92 additions and 128 deletions

View File

@ -324,12 +324,11 @@ impl ExtCtxt {
loop {
match e.node {
ast::ExprMac(..) => {
let extsbox = @mut syntax_expander_table();
let expander = expand::MacroExpander {
extsbox: extsbox,
extsbox: @mut syntax_expander_table(),
cx: self,
};
e = expand::expand_expr(extsbox, self, e, &expander);
e = expand::expand_expr(e, &expander);
}
_ => return e
}

View File

@ -31,11 +31,7 @@ use util::small_vector::SmallVector;
use std::vec;
pub fn expand_expr(extsbox: @mut SyntaxEnv,
cx: &ExtCtxt,
e: @ast::Expr,
fld: &MacroExpander)
-> @ast::Expr {
pub fn expand_expr(e: @ast::Expr, fld: &MacroExpander) -> @ast::Expr {
match e.node {
// expr_mac should really be expr_ext or something; it's the
// entry-point for all syntax extensions.
@ -49,7 +45,7 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv,
// Token-tree macros:
mac_invoc_tt(ref pth, ref tts, ctxt) => {
if (pth.segments.len() > 1u) {
cx.span_fatal(
fld.cx.span_fatal(
pth.span,
format!("expected macro name without module \
separators"));
@ -57,14 +53,14 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv,
let extname = &pth.segments[0].identifier;
let extnamestr = ident_to_str(extname);
// leaving explicit deref here to highlight unbox op:
match (*extsbox).find(&extname.name) {
match (*fld.extsbox).find(&extname.name) {
None => {
cx.span_fatal(
fld.cx.span_fatal(
pth.span,
format!("macro undefined: '{}'", extnamestr))
}
Some(@SE(NormalTT(expandfun, exp_span))) => {
cx.bt_push(ExpnInfo {
fld.cx.bt_push(ExpnInfo {
call_site: e.span,
callee: NameAndSpan {
name: extnamestr,
@ -81,17 +77,17 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv,
// be the root of the call stack. That's the most
// relevant span and it's the actual invocation of
// the macro.
let mac_span = original_span(cx);
let mac_span = original_span(fld.cx);
let expanded =
match expandfun.expand(cx,
match expandfun.expand(fld.cx,
mac_span.call_site,
marked_before,
marked_ctxt) {
MRExpr(e) => e,
MRAny(any_macro) => any_macro.make_expr(),
_ => {
cx.span_fatal(
fld.cx.span_fatal(
pth.span,
format!(
"non-expr macro in expr pos: {}",
@ -109,7 +105,7 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv,
// node here?
let fully_expanded =
fld.fold_expr(marked_after).node.clone();
cx.bt_pop();
fld.cx.bt_pop();
@ast::Expr {
id: ast::DUMMY_NODE_ID,
@ -118,7 +114,7 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv,
}
}
_ => {
cx.span_fatal(
fld.cx.span_fatal(
pth.span,
format!("'{}' is not a tt-style macro", extnamestr)
)
@ -152,46 +148,47 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv,
// }
let local_ident = token::gensym_ident("i");
let next_ident = cx.ident_of("next");
let none_ident = cx.ident_of("None");
let next_ident = fld.cx.ident_of("next");
let none_ident = fld.cx.ident_of("None");
let local_path = cx.path_ident(span, local_ident);
let some_path = cx.path_ident(span, cx.ident_of("Some"));
let local_path = fld.cx.path_ident(span, local_ident);
let some_path = fld.cx.path_ident(span, fld.cx.ident_of("Some"));
// `let i = &mut <src_expr>`
let iter_decl_stmt = cx.stmt_let(span, false, local_ident,
cx.expr_mut_addr_of(span, src_expr));
let iter_decl_stmt = fld.cx.stmt_let(span, false, local_ident,
fld.cx.expr_mut_addr_of(span, src_expr));
// `None => break ['<ident>];`
let none_arm = {
// FIXME #6993: this map goes away:
let break_expr = cx.expr(span, ast::ExprBreak(opt_ident.map(|x| x.name)));
let none_pat = cx.pat_ident(span, none_ident);
cx.arm(span, ~[none_pat], break_expr)
let break_expr = fld.cx.expr(span, ast::ExprBreak(opt_ident.map(|x| x.name)));
let none_pat = fld.cx.pat_ident(span, none_ident);
fld.cx.arm(span, ~[none_pat], break_expr)
};
// `Some(<src_pat>) => <src_loop_block>`
let some_arm =
cx.arm(span,
~[cx.pat_enum(span, some_path, ~[src_pat])],
cx.expr_block(src_loop_block));
fld.cx.arm(span,
~[fld.cx.pat_enum(span, some_path, ~[src_pat])],
fld.cx.expr_block(src_loop_block));
// `match i.next() { ... }`
let match_expr = {
let next_call_expr =
cx.expr_method_call(span, cx.expr_path(local_path), next_ident, ~[]);
fld.cx.expr_method_call(span, fld.cx.expr_path(local_path), next_ident, ~[]);
cx.expr_match(span, next_call_expr, ~[none_arm, some_arm])
fld.cx.expr_match(span, next_call_expr, ~[none_arm, some_arm])
};
// ['ident:] loop { ... }
let loop_expr = cx.expr(span,
ast::ExprLoop(cx.block_expr(match_expr), opt_ident));
let loop_expr = fld.cx.expr(span,
ast::ExprLoop(fld.cx.block_expr(match_expr),
opt_ident));
// `{ let ... ; loop { ... } }`
let block = cx.block(span,
~[iter_decl_stmt],
Some(loop_expr));
let block = fld.cx.block(span,
~[iter_decl_stmt],
Some(loop_expr));
@ast::Expr {
id: ast::DUMMY_NODE_ID,
@ -213,11 +210,7 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv,
//
// NB: there is some redundancy between this and expand_item, below, and
// they might benefit from some amount of semantic and language-UI merger.
pub fn expand_mod_items(extsbox: @mut SyntaxEnv,
cx: &ExtCtxt,
module_: &ast::_mod,
fld: &MacroExpander)
-> ast::_mod {
pub fn expand_mod_items(module_: &ast::_mod, fld: &MacroExpander) -> ast::_mod {
// Fold the contents first:
let module_ = noop_fold_mod(module_, fld);
@ -228,9 +221,9 @@ pub fn expand_mod_items(extsbox: @mut SyntaxEnv,
item.attrs.rev_iter().fold(~[*item], |items, attr| {
let mname = attr.name();
match (*extsbox).find(&intern(mname)) {
match (*fld.extsbox).find(&intern(mname)) {
Some(@SE(ItemDecorator(dec_fn))) => {
cx.bt_push(ExpnInfo {
fld.cx.bt_push(ExpnInfo {
call_site: attr.span,
callee: NameAndSpan {
name: mname,
@ -238,8 +231,8 @@ pub fn expand_mod_items(extsbox: @mut SyntaxEnv,
span: None
}
});
let r = dec_fn(cx, attr.span, attr.node.value, items);
cx.bt_pop();
let r = dec_fn(fld.cx, attr.span, attr.node.value, items);
fld.cx.bt_pop();
r
},
_ => items,
@ -270,20 +263,16 @@ macro_rules! with_exts_frame (
static special_block_name : &'static str = " block";
// When we enter a module, record it, for the sake of `module!`
pub fn expand_item(extsbox: @mut SyntaxEnv,
cx: &ExtCtxt,
it: @ast::item,
fld: &MacroExpander)
-> SmallVector<@ast::item> {
pub fn expand_item(it: @ast::item, fld: &MacroExpander) -> SmallVector<@ast::item> {
match it.node {
ast::item_mac(..) => expand_item_mac(extsbox, cx, it, fld),
ast::item_mac(..) => expand_item_mac(it, fld),
ast::item_mod(_) | ast::item_foreign_mod(_) => {
cx.mod_push(it.ident);
fld.cx.mod_push(it.ident);
let macro_escape = contains_macro_escape(it.attrs);
let result = with_exts_frame!(extsbox,
let result = with_exts_frame!(fld.extsbox,
macro_escape,
noop_fold_item(it, fld));
cx.mod_pop();
fld.cx.mod_pop();
result
},
_ => noop_fold_item(it, fld)
@ -297,10 +286,7 @@ pub fn contains_macro_escape(attrs: &[ast::Attribute]) -> bool {
// Support for item-position macro invocations, exactly the same
// logic as for expression-position macro invocations.
pub fn expand_item_mac(extsbox: @mut SyntaxEnv,
cx: &ExtCtxt,
it: @ast::item,
fld: &MacroExpander)
pub fn expand_item_mac(it: @ast::item, fld: &MacroExpander)
-> SmallVector<@ast::item> {
let (pth, tts, ctxt) = match it.node {
item_mac(codemap::Spanned {
@ -309,24 +295,24 @@ pub fn expand_item_mac(extsbox: @mut SyntaxEnv,
}) => {
(pth, (*tts).clone(), ctxt)
}
_ => cx.span_bug(it.span, "invalid item macro invocation")
_ => fld.cx.span_bug(it.span, "invalid item macro invocation")
};
let extname = &pth.segments[0].identifier;
let extnamestr = ident_to_str(extname);
let fm = fresh_mark();
let expanded = match (*extsbox).find(&extname.name) {
None => cx.span_fatal(pth.span,
format!("macro undefined: '{}!'", extnamestr)),
let expanded = match (*fld.extsbox).find(&extname.name) {
None => fld.cx.span_fatal(pth.span,
format!("macro undefined: '{}!'", extnamestr)),
Some(@SE(NormalTT(expander, span))) => {
if it.ident.name != parse::token::special_idents::invalid.name {
cx.span_fatal(pth.span,
format!("macro {}! expects no ident argument, \
given '{}'", extnamestr,
ident_to_str(&it.ident)));
fld.cx.span_fatal(pth.span,
format!("macro {}! expects no ident argument, \
given '{}'", extnamestr,
ident_to_str(&it.ident)));
}
cx.bt_push(ExpnInfo {
fld.cx.bt_push(ExpnInfo {
call_site: it.span,
callee: NameAndSpan {
name: extnamestr,
@ -337,15 +323,15 @@ pub fn expand_item_mac(extsbox: @mut SyntaxEnv,
// mark before expansion:
let marked_before = mark_tts(tts,fm);
let marked_ctxt = new_mark(fm,ctxt);
expander.expand(cx, it.span, marked_before, marked_ctxt)
expander.expand(fld.cx, it.span, marked_before, marked_ctxt)
}
Some(@SE(IdentTT(expander, span))) => {
if it.ident.name == parse::token::special_idents::invalid.name {
cx.span_fatal(pth.span,
format!("macro {}! expects an ident argument",
extnamestr));
fld.cx.span_fatal(pth.span,
format!("macro {}! expects an ident argument",
extnamestr));
}
cx.bt_push(ExpnInfo {
fld.cx.bt_push(ExpnInfo {
call_site: it.span,
callee: NameAndSpan {
name: extnamestr,
@ -356,10 +342,11 @@ pub fn expand_item_mac(extsbox: @mut SyntaxEnv,
// mark before expansion:
let marked_tts = mark_tts(tts,fm);
let marked_ctxt = new_mark(fm,ctxt);
expander.expand(cx, it.span, it.ident, marked_tts, marked_ctxt)
expander.expand(fld.cx, it.span, it.ident, marked_tts, marked_ctxt)
}
_ => cx.span_fatal(
it.span, format!("{}! is not legal in item position", extnamestr))
_ => fld.cx.span_fatal(it.span,
format!("{}! is not legal in item position",
extnamestr))
};
let items = match expanded {
@ -369,7 +356,8 @@ pub fn expand_item_mac(extsbox: @mut SyntaxEnv,
.collect()
}
MRExpr(_) => {
cx.span_fatal(pth.span, format!("expr macro in item position: {}", extnamestr))
fld.cx.span_fatal(pth.span, format!("expr macro in item position: {}",
extnamestr))
}
MRAny(any_macro) => {
any_macro.make_items().move_iter()
@ -380,11 +368,11 @@ pub fn expand_item_mac(extsbox: @mut SyntaxEnv,
MRDef(ref mdef) => {
// yikes... no idea how to apply the mark to this. I'm afraid
// we're going to have to wait-and-see on this one.
insert_macro(*extsbox,intern(mdef.name), @SE((*mdef).ext));
insert_macro(*fld.extsbox,intern(mdef.name), @SE((*mdef).ext));
SmallVector::zero()
}
};
cx.bt_pop();
fld.cx.bt_pop();
return items;
}
@ -406,11 +394,7 @@ fn insert_macro(exts: SyntaxEnv, name: ast::Name, transformer: @Transformer) {
}
// expand a stmt
pub fn expand_stmt(extsbox: @mut SyntaxEnv,
cx: &ExtCtxt,
s: &Stmt,
fld: &MacroExpander)
-> SmallVector<@Stmt> {
pub fn expand_stmt(s: &Stmt, fld: &MacroExpander) -> SmallVector<@Stmt> {
// why the copying here and not in expand_expr?
// looks like classic changed-in-only-one-place
let (pth, tts, semi, ctxt) = match s.node {
@ -421,21 +405,21 @@ pub fn expand_stmt(extsbox: @mut SyntaxEnv,
}
}
}
_ => return expand_non_macro_stmt(*extsbox, s, fld)
_ => return expand_non_macro_stmt(s, fld)
};
if (pth.segments.len() > 1u) {
cx.span_fatal(pth.span,
"expected macro name without module separators");
fld.cx.span_fatal(pth.span,
"expected macro name without module separators");
}
let extname = &pth.segments[0].identifier;
let extnamestr = ident_to_str(extname);
let fully_expanded: SmallVector<@Stmt> = match (*extsbox).find(&extname.name) {
let fully_expanded: SmallVector<@Stmt> = match (*fld.extsbox).find(&extname.name) {
None => {
cx.span_fatal(pth.span, format!("macro undefined: '{}'", extnamestr))
fld.cx.span_fatal(pth.span, format!("macro undefined: '{}'", extnamestr))
}
Some(@SE(NormalTT(expandfun, exp_span))) => {
cx.bt_push(ExpnInfo {
fld.cx.bt_push(ExpnInfo {
call_site: s.span,
callee: NameAndSpan {
name: extnamestr,
@ -450,9 +434,9 @@ pub fn expand_stmt(extsbox: @mut SyntaxEnv,
// See the comment in expand_expr for why we want the original span,
// not the current mac.span.
let mac_span = original_span(cx);
let mac_span = original_span(fld.cx);
let expanded = match expandfun.expand(cx,
let expanded = match expandfun.expand(fld.cx,
mac_span.call_site,
marked_tts,
marked_ctxt) {
@ -463,7 +447,7 @@ pub fn expand_stmt(extsbox: @mut SyntaxEnv,
}
}
MRAny(any_macro) => any_macro.make_stmt(),
_ => cx.span_fatal(
_ => fld.cx.span_fatal(
pth.span,
format!("non-stmt macro in stmt pos: {}", extnamestr))
};
@ -472,18 +456,19 @@ pub fn expand_stmt(extsbox: @mut SyntaxEnv,
// Keep going, outside-in.
let fully_expanded = fld.fold_stmt(marked_after);
if fully_expanded.is_empty() {
cx.span_fatal(pth.span,
fld.cx.span_fatal(pth.span,
"macro didn't expand to a statement");
}
cx.bt_pop();
fld.cx.bt_pop();
fully_expanded.move_iter()
.map(|s| @Spanned { span: s.span, node: s.node.clone() })
.collect()
}
_ => {
cx.span_fatal(pth.span,
format!("'{}' is not a tt-style macro", extnamestr))
fld.cx.span_fatal(pth.span,
format!("'{}' is not a tt-style macro",
extnamestr))
}
};
@ -502,7 +487,7 @@ pub fn expand_stmt(extsbox: @mut SyntaxEnv,
// expand a non-macro stmt. this is essentially the fallthrough for
// expand_stmt, above.
fn expand_non_macro_stmt(exts: SyntaxEnv, s: &Stmt, fld: &MacroExpander)
fn expand_non_macro_stmt(s: &Stmt, fld: &MacroExpander)
-> SmallVector<@Stmt> {
// is it a let?
match s.node {
@ -511,7 +496,7 @@ fn expand_non_macro_stmt(exts: SyntaxEnv, s: &Stmt, fld: &MacroExpander)
span: stmt_span
},
node_id) => {
let block_info = get_block_info(exts);
let block_info = get_block_info(*fld.extsbox);
let pending_renames = block_info.pending_renames;
// take it apart:
@ -624,20 +609,15 @@ pub fn new_name_finder(idents: ~[ast::Ident]) -> NewNameFinderContext {
}
// expand a block. pushes a new exts_frame, then calls expand_block_elts
pub fn expand_block(extsbox: @mut SyntaxEnv,
_: &ExtCtxt,
blk: &Block,
fld: &MacroExpander)
-> P<Block> {
pub fn expand_block(blk: &Block, fld: &MacroExpander) -> P<Block> {
// see note below about treatment of exts table
with_exts_frame!(extsbox,false,
expand_block_elts(*extsbox, blk, fld))
with_exts_frame!(fld.extsbox,false,
expand_block_elts(blk, fld))
}
// expand the elements of a block.
pub fn expand_block_elts(exts: SyntaxEnv, b: &Block, fld: &MacroExpander)
-> P<Block> {
let block_info = get_block_info(exts);
pub fn expand_block_elts(b: &Block, fld: &MacroExpander) -> P<Block> {
let block_info = get_block_info(*fld.extsbox);
let pending_renames = block_info.pending_renames;
let rename_fld = renames_to_fold(pending_renames);
let new_view_items = b.view_items.map(|x| fld.fold_view_item(x));
@ -956,38 +936,23 @@ pub struct MacroExpander<'a> {
impl<'a> ast_fold for MacroExpander<'a> {
fn fold_expr(&self, expr: @ast::Expr) -> @ast::Expr {
expand_expr(self.extsbox,
self.cx,
expr,
self)
expand_expr(expr, self)
}
fn fold_mod(&self, module: &ast::_mod) -> ast::_mod {
expand_mod_items(self.extsbox,
self.cx,
module,
self)
expand_mod_items(module, self)
}
fn fold_item(&self, item: @ast::item) -> SmallVector<@ast::item> {
expand_item(self.extsbox,
self.cx,
item,
self)
expand_item(item, self)
}
fn fold_stmt(&self, stmt: &ast::Stmt) -> SmallVector<@ast::Stmt> {
expand_stmt(self.extsbox,
self.cx,
stmt,
self)
expand_stmt(stmt, self)
}
fn fold_block(&self, block: P<Block>) -> P<Block> {
expand_block(self.extsbox,
self.cx,
block,
self)
expand_block(block, self)
}
fn new_span(&self, span: Span) -> Span {