Skip to content

Commit e959963

Browse files
committed
libsyntax: Remove some more @fns from the macro expander
1 parent 6a8169d commit e959963

File tree

3 files changed

+300
-109
lines changed

3 files changed

+300
-109
lines changed

src/libsyntax/ext/base.rs

Lines changed: 159 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -33,62 +33,120 @@ pub struct MacroDef {
3333
ext: SyntaxExtension
3434
}
3535

36-
// No context arg for an Item Decorator macro, simply because
37-
// adding it would require adding a ctxt field to all items.
38-
// we could do this if it turns out to be useful.
39-
40-
pub type ItemDecoratorFun = @fn(@ExtCtxt,
41-
Span,
42-
@ast::MetaItem,
43-
~[@ast::item])
44-
-> ~[@ast::item];
45-
46-
pub type SyntaxExpanderTTFun = @fn(@ExtCtxt,
47-
Span,
48-
&[ast::token_tree],
49-
ast::SyntaxContext)
50-
-> MacResult;
51-
52-
pub type SyntaxExpanderTTItemFun = @fn(@ExtCtxt,
53-
Span,
54-
ast::Ident,
55-
~[ast::token_tree],
56-
ast::SyntaxContext)
57-
-> MacResult;
58-
59-
// oog... in order to make the presentation of builtin_normal_tt_no_ctxt
60-
// and builtin_ident_tt_no_ctxt palatable, we need one-off types for
61-
// functions that don't consume a ctxt:
62-
63-
pub type SyntaxExpanderTTFunNoCtxt = @fn(@ExtCtxt,
64-
Span,
65-
&[ast::token_tree])
66-
-> MacResult;
67-
68-
pub type SyntaxExpanderTTItemFunNoCtxt = @fn(@ExtCtxt,
69-
Span,
70-
ast::Ident,
71-
~[ast::token_tree])
72-
-> MacResult;
36+
pub type ItemDecorator = extern "Rust" fn(@ExtCtxt,
37+
Span,
38+
@ast::MetaItem,
39+
~[@ast::item])
40+
-> ~[@ast::item];
41+
42+
pub struct SyntaxExpanderTT {
43+
expander: SyntaxExpanderTTExpander,
44+
span: Option<Span>
45+
}
46+
47+
pub trait SyntaxExpanderTTTrait {
48+
fn expand(&self,
49+
ecx: @ExtCtxt,
50+
span: Span,
51+
token_tree: &[ast::token_tree],
52+
context: ast::SyntaxContext)
53+
-> MacResult;
54+
}
55+
56+
pub type SyntaxExpanderTTFunNoCtxt =
57+
extern "Rust" fn(ecx: @ExtCtxt,
58+
span: codemap::Span,
59+
token_tree: &[ast::token_tree])
60+
-> MacResult;
61+
62+
enum SyntaxExpanderTTExpander {
63+
SyntaxExpanderTTExpanderWithoutContext(SyntaxExpanderTTFunNoCtxt),
64+
}
65+
66+
impl SyntaxExpanderTTTrait for SyntaxExpanderTT {
67+
fn expand(&self,
68+
ecx: @ExtCtxt,
69+
span: Span,
70+
token_tree: &[ast::token_tree],
71+
_: ast::SyntaxContext)
72+
-> MacResult {
73+
match self.expander {
74+
SyntaxExpanderTTExpanderWithoutContext(f) => {
75+
f(ecx, span, token_tree)
76+
}
77+
}
78+
}
79+
}
7380

81+
enum SyntaxExpanderTTItemExpander {
82+
SyntaxExpanderTTItemExpanderWithContext(SyntaxExpanderTTItemFun),
83+
SyntaxExpanderTTItemExpanderWithoutContext(SyntaxExpanderTTItemFunNoCtxt),
84+
}
7485

86+
pub struct SyntaxExpanderTTItem {
87+
expander: SyntaxExpanderTTItemExpander,
88+
span: Option<Span>
89+
}
90+
91+
pub trait SyntaxExpanderTTItemTrait {
92+
fn expand(&self,
93+
cx: @ExtCtxt,
94+
sp: Span,
95+
ident: ast::Ident,
96+
token_tree: ~[ast::token_tree],
97+
context: ast::SyntaxContext)
98+
-> MacResult;
99+
}
100+
101+
impl SyntaxExpanderTTItemTrait for SyntaxExpanderTTItem {
102+
fn expand(&self,
103+
cx: @ExtCtxt,
104+
sp: Span,
105+
ident: ast::Ident,
106+
token_tree: ~[ast::token_tree],
107+
context: ast::SyntaxContext)
108+
-> MacResult {
109+
match self.expander {
110+
SyntaxExpanderTTItemExpanderWithContext(fun) => {
111+
fun(cx, sp, ident, token_tree, context)
112+
}
113+
SyntaxExpanderTTItemExpanderWithoutContext(fun) => {
114+
fun(cx, sp, ident, token_tree)
115+
}
116+
}
117+
}
118+
}
119+
120+
pub type SyntaxExpanderTTItemFun = extern "Rust" fn(@ExtCtxt,
121+
Span,
122+
ast::Ident,
123+
~[ast::token_tree],
124+
ast::SyntaxContext)
125+
-> MacResult;
126+
127+
pub type SyntaxExpanderTTItemFunNoCtxt =
128+
extern "Rust" fn(@ExtCtxt, Span, ast::Ident, ~[ast::token_tree])
129+
-> MacResult;
130+
131+
pub trait AnyMacro {
132+
fn make_expr(&self) -> @ast::Expr;
133+
fn make_item(&self) -> Option<@ast::item>;
134+
fn make_stmt(&self) -> @ast::Stmt;
135+
}
75136

76137
pub enum MacResult {
77138
MRExpr(@ast::Expr),
78139
MRItem(@ast::item),
79-
MRAny(@fn() -> @ast::Expr,
80-
@fn() -> Option<@ast::item>,
81-
@fn() -> @ast::Stmt),
82-
MRDef(MacroDef)
140+
MRAny(@AnyMacro),
141+
MRDef(MacroDef),
83142
}
84143

85144
pub enum SyntaxExtension {
86-
87145
// #[auto_encode] and such
88-
ItemDecorator(ItemDecoratorFun),
146+
ItemDecorator(ItemDecorator),
89147

90148
// Token-tree expanders
91-
NormalTT(SyntaxExpanderTTFun, Option<Span>),
149+
NormalTT(@SyntaxExpanderTTTrait, Option<Span>),
92150

93151
// An IdentTT is a macro that has an
94152
// identifier in between the name of the
@@ -98,7 +156,7 @@ pub enum SyntaxExtension {
98156

99157
// perhaps macro_rules! will lose its odd special identifier argument,
100158
// and this can go away also
101-
IdentTT(SyntaxExpanderTTItemFun, Option<Span>),
159+
IdentTT(@SyntaxExpanderTTItemTrait, Option<Span>),
102160
}
103161

104162

@@ -133,16 +191,22 @@ type RenameList = ~[(ast::Ident,Name)];
133191
// AST nodes into full ASTs
134192
pub fn syntax_expander_table() -> SyntaxEnv {
135193
// utility function to simplify creating NormalTT syntax extensions
136-
// that ignore their contexts
137-
fn builtin_normal_tt_no_ctxt(f: SyntaxExpanderTTFunNoCtxt) -> @Transformer {
138-
let wrapped_expander : SyntaxExpanderTTFun = |a,b,c,_d|{f(a,b,c)};
139-
@SE(NormalTT(wrapped_expander, None))
194+
fn builtin_normal_tt_no_ctxt(f: SyntaxExpanderTTFunNoCtxt)
195+
-> @Transformer {
196+
@SE(NormalTT(@SyntaxExpanderTT{
197+
expander: SyntaxExpanderTTExpanderWithoutContext(f),
198+
span: None,
199+
} as @SyntaxExpanderTTTrait,
200+
None))
140201
}
141202
// utility function to simplify creating IdentTT syntax extensions
142203
// that ignore their contexts
143204
fn builtin_item_tt_no_ctxt(f: SyntaxExpanderTTItemFunNoCtxt) -> @Transformer {
144-
let wrapped_expander : SyntaxExpanderTTItemFun = |a,b,c,d,_e|{f(a,b,c,d)};
145-
@SE(IdentTT(wrapped_expander, None))
205+
@SE(IdentTT(@SyntaxExpanderTTItem {
206+
expander: SyntaxExpanderTTItemExpanderWithoutContext(f),
207+
span: None,
208+
} as @SyntaxExpanderTTItemTrait,
209+
None))
146210
}
147211
let mut syntax_expanders = HashMap::new();
148212
// NB identifier starts with space, and can't conflict with legal idents
@@ -152,79 +216,95 @@ pub fn syntax_expander_table() -> SyntaxEnv {
152216
pending_renames : @mut ~[]
153217
}));
154218
syntax_expanders.insert(intern(&"macro_rules"),
155-
@SE(IdentTT(ext::tt::macro_rules::add_new_extension, None)));
219+
@SE(IdentTT(@SyntaxExpanderTTItem {
220+
expander: SyntaxExpanderTTItemExpanderWithContext(ext::tt::macro_rules::add_new_extension),
221+
span: None,
222+
} as @SyntaxExpanderTTItemTrait,
223+
None)));
156224
syntax_expanders.insert(intern(&"fmt"),
157-
builtin_normal_tt_no_ctxt(ext::fmt::expand_syntax_ext));
225+
builtin_normal_tt_no_ctxt(
226+
ext::fmt::expand_syntax_ext));
158227
syntax_expanders.insert(intern(&"format_args"),
159-
builtin_normal_tt_no_ctxt(ext::format::expand_args));
228+
builtin_normal_tt_no_ctxt(
229+
ext::format::expand_args));
160230
syntax_expanders.insert(
161231
intern(&"auto_encode"),
162232
@SE(ItemDecorator(ext::auto_encode::expand_auto_encode)));
163233
syntax_expanders.insert(
164234
intern(&"auto_decode"),
165235
@SE(ItemDecorator(ext::auto_encode::expand_auto_decode)));
166236
syntax_expanders.insert(intern(&"env"),
167-
builtin_normal_tt_no_ctxt(ext::env::expand_env));
237+
builtin_normal_tt_no_ctxt(
238+
ext::env::expand_env));
168239
syntax_expanders.insert(intern(&"option_env"),
169-
builtin_normal_tt_no_ctxt(ext::env::expand_option_env));
240+
builtin_normal_tt_no_ctxt(
241+
ext::env::expand_option_env));
170242
syntax_expanders.insert(intern("bytes"),
171-
builtin_normal_tt_no_ctxt(ext::bytes::expand_syntax_ext));
243+
builtin_normal_tt_no_ctxt(
244+
ext::bytes::expand_syntax_ext));
172245
syntax_expanders.insert(intern("concat_idents"),
173246
builtin_normal_tt_no_ctxt(
174-
ext::concat_idents::expand_syntax_ext));
247+
ext::concat_idents::expand_syntax_ext));
175248
syntax_expanders.insert(intern(&"log_syntax"),
176249
builtin_normal_tt_no_ctxt(
177-
ext::log_syntax::expand_syntax_ext));
250+
ext::log_syntax::expand_syntax_ext));
178251
syntax_expanders.insert(intern(&"deriving"),
179252
@SE(ItemDecorator(
180253
ext::deriving::expand_meta_deriving)));
181254

182255
// Quasi-quoting expanders
183256
syntax_expanders.insert(intern(&"quote_tokens"),
184-
builtin_normal_tt_no_ctxt(
185-
ext::quote::expand_quote_tokens));
257+
builtin_normal_tt_no_ctxt(
258+
ext::quote::expand_quote_tokens));
186259
syntax_expanders.insert(intern(&"quote_expr"),
187-
builtin_normal_tt_no_ctxt(ext::quote::expand_quote_expr));
260+
builtin_normal_tt_no_ctxt(
261+
ext::quote::expand_quote_expr));
188262
syntax_expanders.insert(intern(&"quote_ty"),
189-
builtin_normal_tt_no_ctxt(ext::quote::expand_quote_ty));
263+
builtin_normal_tt_no_ctxt(
264+
ext::quote::expand_quote_ty));
190265
syntax_expanders.insert(intern(&"quote_item"),
191-
builtin_normal_tt_no_ctxt(ext::quote::expand_quote_item));
266+
builtin_normal_tt_no_ctxt(
267+
ext::quote::expand_quote_item));
192268
syntax_expanders.insert(intern(&"quote_pat"),
193-
builtin_normal_tt_no_ctxt(ext::quote::expand_quote_pat));
269+
builtin_normal_tt_no_ctxt(
270+
ext::quote::expand_quote_pat));
194271
syntax_expanders.insert(intern(&"quote_stmt"),
195-
builtin_normal_tt_no_ctxt(ext::quote::expand_quote_stmt));
272+
builtin_normal_tt_no_ctxt(
273+
ext::quote::expand_quote_stmt));
196274

197275
syntax_expanders.insert(intern(&"line"),
198276
builtin_normal_tt_no_ctxt(
199-
ext::source_util::expand_line));
277+
ext::source_util::expand_line));
200278
syntax_expanders.insert(intern(&"col"),
201279
builtin_normal_tt_no_ctxt(
202-
ext::source_util::expand_col));
280+
ext::source_util::expand_col));
203281
syntax_expanders.insert(intern(&"file"),
204282
builtin_normal_tt_no_ctxt(
205-
ext::source_util::expand_file));
283+
ext::source_util::expand_file));
206284
syntax_expanders.insert(intern(&"stringify"),
207285
builtin_normal_tt_no_ctxt(
208-
ext::source_util::expand_stringify));
286+
ext::source_util::expand_stringify));
209287
syntax_expanders.insert(intern(&"include"),
210288
builtin_normal_tt_no_ctxt(
211-
ext::source_util::expand_include));
289+
ext::source_util::expand_include));
212290
syntax_expanders.insert(intern(&"include_str"),
213291
builtin_normal_tt_no_ctxt(
214-
ext::source_util::expand_include_str));
292+
ext::source_util::expand_include_str));
215293
syntax_expanders.insert(intern(&"include_bin"),
216294
builtin_normal_tt_no_ctxt(
217-
ext::source_util::expand_include_bin));
295+
ext::source_util::expand_include_bin));
218296
syntax_expanders.insert(intern(&"module_path"),
219297
builtin_normal_tt_no_ctxt(
220-
ext::source_util::expand_mod));
298+
ext::source_util::expand_mod));
221299
syntax_expanders.insert(intern(&"asm"),
222-
builtin_normal_tt_no_ctxt(ext::asm::expand_asm));
300+
builtin_normal_tt_no_ctxt(
301+
ext::asm::expand_asm));
223302
syntax_expanders.insert(intern(&"cfg"),
224-
builtin_normal_tt_no_ctxt(ext::cfg::expand_cfg));
225-
syntax_expanders.insert(
226-
intern(&"trace_macros"),
227-
builtin_normal_tt_no_ctxt(ext::trace_macros::expand_trace_macros));
303+
builtin_normal_tt_no_ctxt(
304+
ext::cfg::expand_cfg));
305+
syntax_expanders.insert(intern(&"trace_macros"),
306+
builtin_normal_tt_no_ctxt(
307+
ext::trace_macros::expand_trace_macros));
228308
MapChain::new(~syntax_expanders)
229309
}
230310

src/libsyntax/ext/expand.rs

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,12 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv,
8383
let mac_span = original_span(cx);
8484

8585
let expanded =
86-
match expandfun(cx, mac_span.call_site,
87-
marked_before, marked_ctxt) {
86+
match expandfun.expand(cx,
87+
mac_span.call_site,
88+
marked_before,
89+
marked_ctxt) {
8890
MRExpr(e) => e,
89-
MRAny(expr_maker,_,_) => expr_maker(),
91+
MRAny(any_macro) => any_macro.make_expr(),
9092
_ => {
9193
cx.span_fatal(
9294
pth.span,
@@ -370,7 +372,7 @@ pub fn expand_item_mac(extsbox: @mut SyntaxEnv,
370372
// mark before expansion:
371373
let marked_before = mark_tts(tts,fm);
372374
let marked_ctxt = new_mark(fm,ctxt);
373-
expander(cx, it.span, marked_before, marked_ctxt)
375+
expander.expand(cx, it.span, marked_before, marked_ctxt)
374376
}
375377
Some(@SE(IdentTT(expander, span))) => {
376378
if it.ident.name == parse::token::special_idents::invalid.name {
@@ -388,7 +390,7 @@ pub fn expand_item_mac(extsbox: @mut SyntaxEnv,
388390
// mark before expansion:
389391
let marked_tts = mark_tts(tts,fm);
390392
let marked_ctxt = new_mark(fm,ctxt);
391-
expander(cx, it.span, it.ident, marked_tts, marked_ctxt)
393+
expander.expand(cx, it.span, it.ident, marked_tts, marked_ctxt)
392394
}
393395
_ => cx.span_fatal(
394396
it.span, fmt!("%s! is not legal in item position", extnamestr))
@@ -402,10 +404,10 @@ pub fn expand_item_mac(extsbox: @mut SyntaxEnv,
402404
MRExpr(_) => {
403405
cx.span_fatal(pth.span, fmt!("expr macro in item position: %s", extnamestr))
404406
}
405-
MRAny(_, item_maker, _) => {
406-
item_maker()
407-
.and_then(|i| mark_item(i,fm))
408-
.and_then(|i| fld.fold_item(i))
407+
MRAny(any_macro) => {
408+
any_macro.make_item()
409+
.and_then(|i| mark_item(i,fm))
410+
.and_then(|i| fld.fold_item(i))
409411
}
410412
MRDef(ref mdef) => {
411413
// yikes... no idea how to apply the mark to this. I'm afraid
@@ -481,17 +483,17 @@ pub fn expand_stmt(extsbox: @mut SyntaxEnv,
481483
// not the current mac.span.
482484
let mac_span = original_span(cx);
483485

484-
let expanded = match expandfun(cx,
485-
mac_span.call_site,
486-
marked_tts,
487-
marked_ctxt) {
486+
let expanded = match expandfun.expand(cx,
487+
mac_span.call_site,
488+
marked_tts,
489+
marked_ctxt) {
488490
MRExpr(e) => {
489491
@codemap::Spanned {
490492
node: StmtExpr(e, ast::DUMMY_NODE_ID),
491493
span: e.span,
492494
}
493495
}
494-
MRAny(_,_,stmt_mkr) => stmt_mkr(),
496+
MRAny(any_macro) => any_macro.make_stmt(),
495497
_ => cx.span_fatal(
496498
pth.span,
497499
fmt!("non-stmt macro in stmt pos: %s", extnamestr))

0 commit comments

Comments
 (0)