1
1
use std:: map:: HashMap ;
2
2
3
3
use ast:: { crate , expr_, expr_mac, mac_invoc, mac_invoc_tt,
4
- tt_delim, tt_tok, item_mac} ;
4
+ tt_delim, tt_tok, item_mac, stmt_ , stmt_mac } ;
5
5
use fold:: * ;
6
6
use ext:: base:: * ;
7
7
use ext:: qquote:: { qq_helper} ;
@@ -20,9 +20,9 @@ fn expand_expr(exts: HashMap<~str, syntax_extension>, cx: ext_ctxt,
20
20
// entry-point for all syntax extensions.
21
21
expr_mac( mac) => {
22
22
23
- // Old-style macros, for compatibility, will erase this whole
24
- // block once we've transitioned.
25
23
match mac. node {
24
+ // Old-style macros. For compatibility, will erase this whole
25
+ // block once we've transitioned.
26
26
mac_invoc( pth, args, body) => {
27
27
assert ( vec:: len ( pth. idents ) > 0 u) ;
28
28
/* using idents and token::special_idents would make the
@@ -81,7 +81,7 @@ fn expand_expr(exts: HashMap<~str, syntax_extension>, cx: ext_ctxt,
81
81
Some ( normal_tt ( { expander : exp, span : exp_sp} ) ) => {
82
82
let expanded = match exp ( cx, mac. span , tts) {
83
83
mr_expr( e) => e,
84
- mr_expr_or_item ( expr_maker, _) => expr_maker ( ) ,
84
+ mr_any ( expr_maker, _ , _) => expr_maker ( ) ,
85
85
_ => cx. span_fatal (
86
86
pth. span , fmt ! ( "non-expr macro in expr pos: %s" ,
87
87
* extname) )
@@ -234,7 +234,7 @@ fn expand_item_mac(exts: HashMap<~str, syntax_extension>,
234
234
mr_expr( _) => cx. span_fatal ( pth. span ,
235
235
~"expr macro in item position: " +
236
236
*extname),
237
- mr_expr_or_item (_, item_maker) =>
237
+ mr_any (_, item_maker, _ ) =>
238
238
option::chain(item_maker(), |i| {fld.fold_item(i)}),
239
239
mr_def(mdef) => {
240
240
exts.insert(mdef.name, mdef.ext);
@@ -248,6 +248,59 @@ fn expand_item_mac(exts: HashMap<~str, syntax_extension>,
248
248
}
249
249
}
250
250
251
+ fn expand_stmt( exts: HashMap < ~str , syntax_extension > , cx: ext_ctxt,
252
+ & & s: stmt_, sp: span, fld: ast_fold,
253
+ orig: fn @( & & s: stmt_, span, ast_fold) -> ( stmt_, span) )
254
+ -> ( stmt_, span)
255
+ {
256
+ return match s {
257
+ stmt_mac( mac) => {
258
+ match mac. node {
259
+ mac_invoc_tt( pth, tts) => {
260
+ assert ( vec:: len ( pth. idents ) == 1 u) ;
261
+ let extname = cx. parse_sess ( ) . interner . get ( pth. idents [ 0 ] ) ;
262
+ match exts. find ( * extname) {
263
+ None => {
264
+ cx. span_fatal (
265
+ pth. span ,
266
+ fmt ! ( "macro undefined: '%s'" , * extname) )
267
+ }
268
+ Some ( normal_tt ( { expander : exp, span : exp_sp} ) ) => {
269
+ let expanded = match exp ( cx, mac. span , tts) {
270
+ mr_expr( e) =>
271
+ @{ node: ast:: stmt_expr ( e, cx. next_id ( ) ) ,
272
+ span: e. span } ,
273
+ mr_any( _, _, stmt_mkr) => stmt_mkr ( ) ,
274
+ _ => cx. span_fatal (
275
+ pth. span ,
276
+ fmt ! ( "non-stmt macro in stmt pos: %s" ,
277
+ * extname) )
278
+ } ;
279
+
280
+ cx. bt_push ( ExpandedFrom (
281
+ { call_site: sp,
282
+ callie : { name : * extname, span : exp_sp} } ) ) ;
283
+ //keep going, outside-in
284
+ let fully_expanded = fld. fold_stmt ( expanded) . node ;
285
+ cx. bt_pop ( ) ;
286
+
287
+ ( fully_expanded, sp)
288
+ }
289
+ _ => {
290
+ cx. span_fatal ( pth. span ,
291
+ fmt ! ( "'%s' is not a tt-style macro" ,
292
+ * extname) )
293
+ }
294
+ }
295
+ }
296
+ _ => cx. span_bug ( mac. span , ~"naked syntactic bit")
297
+ }
298
+ }
299
+ _ => orig ( s, sp, fld)
300
+ } ;
301
+ }
302
+
303
+
251
304
fn new_span ( cx : ext_ctxt , sp : span ) -> span {
252
305
/* this discards information in the case of macro-defining macros */
253
306
return span { lo : sp. lo , hi : sp. hi , expn_info : cx. backtrace ( ) } ;
@@ -298,7 +351,8 @@ fn expand_crate(parse_sess: parse::parse_sess,
298
351
@{ fold_expr: |a, b, c| expand_expr( exts, cx, a, b, c, afp. fold_expr) ,
299
352
fold_mod: |a, b| expand_mod_items( exts, cx, a, b, afp. fold_mod) ,
300
353
fold_item: |a, b| expand_item( exts, cx, a, b, afp. fold_item) ,
301
- new_span: |a|new_span(cx, a),
354
+ fold_stmt: |a, b, c| expand_stmt( exts, cx, a, b, c, afp. fold_stmt) ,
355
+ new_span: |a| new_span( cx, a) ,
302
356
.. * afp} ;
303
357
let f = make_fold( f_pre) ;
304
358
let cm = parse_expr_from_source_str( ~"<core-macros>",
0 commit comments