@@ -2,7 +2,7 @@ import driver::session;
2
2
3
3
import option :: { none, some} ;
4
4
5
- import syntax:: ast:: { crate, expr_, expr_mac , mac_invoc,
5
+ import syntax:: ast:: { crate, expr_, mac_invoc,
6
6
mac_qq, mac_aq, mac_var} ;
7
7
import syntax:: fold:: * ;
8
8
import syntax:: visit:: * ;
@@ -17,68 +17,98 @@ import std::io::*;
17
17
import codemap:: span;
18
18
19
19
type aq_ctxt = @{ lo : uint ,
20
- mutable gather: [ { lo : uint , hi : uint , e : @ast:: expr } ] } ;
20
+ mutable gather: [ { lo : uint , hi : uint ,
21
+ e : @ast:: expr , constr : str } ] } ;
22
+ enum fragment {
23
+ from_expr( @ast:: expr ) ,
24
+ from_ty( @ast:: ty )
25
+ }
21
26
22
27
iface qq_helper {
23
28
fn span( ) -> span;
24
29
fn visit ( aq_ctxt , vt < aq_ctxt > ) ;
30
+ fn extract_mac ( ) -> option < ast:: mac_ > ;
25
31
fn mk_parse_fn ( ext_ctxt , span ) -> @ast:: expr ;
26
32
}
27
33
impl of qq_helper for @ast:: expr {
28
34
fn span ( ) -> span { self . span }
29
35
fn visit ( cx : aq_ctxt , v : vt < aq_ctxt > ) { visit_expr ( self , cx, v) ; }
36
+ fn extract_mac ( ) -> option < ast:: mac_ > {
37
+ alt ( self . node ) {
38
+ ast:: expr_mac ( { node: mac, _} ) { some ( mac) }
39
+ _ { none}
40
+ }
41
+ }
30
42
fn mk_parse_fn ( cx : ext_ctxt , sp : span ) -> @ast:: expr {
31
43
mk_path ( cx, sp, [ "syntax" , "parse" , "parser" , "parse_expr" ] )
32
44
}
33
45
}
34
46
impl of qq_helper for @ast:: ty {
35
47
fn span ( ) -> span { self . span }
36
48
fn visit ( cx : aq_ctxt , v : vt < aq_ctxt > ) { visit_ty ( self , cx, v) ; }
49
+ fn extract_mac ( ) -> option < ast:: mac_ > {
50
+ alt ( self . node ) {
51
+ ast:: ty_mac ( { node: mac, _} ) { some ( mac) }
52
+ _ { none}
53
+ }
54
+ }
37
55
fn mk_parse_fn ( cx : ext_ctxt , sp : span ) -> @ast:: expr {
38
56
mk_path ( cx, sp, [ "syntax" , "ext" , "qquote" , "parse_ty" ] )
39
57
}
40
58
}
41
59
impl of qq_helper for @ast:: item {
42
60
fn span ( ) -> span { self . span }
43
61
fn visit ( cx : aq_ctxt , v : vt < aq_ctxt > ) { visit_item ( self , cx, v) ; }
62
+ fn extract_mac ( ) -> option < ast:: mac_ > { fail}
44
63
fn mk_parse_fn ( cx : ext_ctxt , sp : span ) -> @ast:: expr {
45
64
mk_path ( cx, sp, [ "syntax" , "ext" , "qquote" , "parse_item" ] )
46
65
}
47
66
}
48
67
impl of qq_helper for @ast:: stmt {
49
68
fn span ( ) -> span { self . span }
50
69
fn visit ( cx : aq_ctxt , v : vt < aq_ctxt > ) { visit_stmt ( self , cx, v) ; }
70
+ fn extract_mac ( ) -> option < ast:: mac_ > { fail}
51
71
fn mk_parse_fn ( cx : ext_ctxt , sp : span ) -> @ast:: expr {
52
72
mk_path ( cx, sp, [ "syntax" , "ext" , "qquote" , "parse_stmt" ] )
53
73
}
54
74
}
55
75
impl of qq_helper for @ast:: pat {
56
76
fn span ( ) -> span { self . span }
57
77
fn visit ( cx : aq_ctxt , v : vt < aq_ctxt > ) { visit_pat ( self , cx, v) ; }
78
+ fn extract_mac ( ) -> option < ast:: mac_ > { fail}
58
79
fn mk_parse_fn ( cx : ext_ctxt , sp : span ) -> @ast:: expr {
59
80
mk_path ( cx, sp, [ "syntax" , "parse" , "parser" , "parse_pat" ] )
60
81
}
61
82
}
62
83
63
84
fn gather_anti_quotes < N : qq_helper > ( lo : uint , node : N ) -> aq_ctxt
64
85
{
65
- let v = @{ visit_expr: visit_expr_aq
86
+ let v = @{ visit_expr: visit_aq_expr,
87
+ visit_ty: visit_aq_ty
66
88
with * default_visitor ( ) } ;
67
89
let cx = @{ lo: lo, mutable gather: [ ] } ;
68
90
node. visit ( cx, mk_vt ( v) ) ;
69
91
ret cx;
70
92
}
71
93
72
- fn visit_expr_aq ( expr : @ast :: expr , & & cx: aq_ctxt , v : vt < aq_ctxt > )
94
+ fn visit_aq < T : qq_helper > ( node : T , constr : str , & & cx: aq_ctxt , v : vt < aq_ctxt > )
73
95
{
74
- alt ( expr . node ) {
75
- expr_mac ( { node : mac_aq ( sp, e) , _ } ) {
96
+ alt ( node. extract_mac ( ) ) {
97
+ some ( mac_aq ( sp, e) ) {
76
98
cx. gather += [ { lo: sp. lo - cx. lo , hi: sp. hi - cx. lo ,
77
- e: e} ] ;
99
+ e: e, constr : constr } ] ;
78
100
}
79
- _ { visit_expr ( expr , cx, v) ; }
101
+ _ { node . visit ( cx, v) ; }
80
102
}
81
103
}
104
+ // FIXME: these are only here because I (kevina) couldn't figure out how to
105
+ // get bind to work in gather_anti_quotes
106
+ fn visit_aq_expr ( node : @ast:: expr , & & cx: aq_ctxt , v : vt < aq_ctxt > ) {
107
+ visit_aq ( node, "from_expr" , cx, v) ;
108
+ }
109
+ fn visit_aq_ty ( node : @ast:: ty , & & cx: aq_ctxt , v : vt < aq_ctxt > ) {
110
+ visit_aq ( node, "from_ty" , cx, v) ;
111
+ }
82
112
83
113
fn is_space ( c : char ) -> bool {
84
114
syntax:: parse:: lexer:: is_whitespace ( c)
@@ -211,28 +241,51 @@ fn expand_qquote<N: qq_helper>
211
241
rcall = mk_call ( cx, sp,
212
242
[ "syntax" , "ext" , "qquote" , "replace" ] ,
213
243
[ pcall,
214
- mk_vec_e ( cx, sp, vec:: map ( qcx. gather , { |g| g. e } ) ) ] ) ;
244
+ mk_vec_e ( cx, sp, vec:: map ( qcx. gather ) { |g|
245
+ mk_call ( cx, sp,
246
+ [ "syntax" , "ext" , "qquote" , g. constr ] ,
247
+ [ g. e ] )
248
+ } ) ] ) ;
215
249
}
216
250
217
251
ret rcall;
218
252
}
219
253
220
- fn replace ( e : @ast:: expr , repls : [ @ast :: expr ] ) -> @ast:: expr {
254
+ fn replace ( e : @ast:: expr , repls : [ fragment ] ) -> @ast:: expr {
221
255
let aft = default_ast_fold ( ) ;
222
256
let f_pre = { fold_expr: bind replace_expr ( repls, _, _, _,
223
- aft. fold_expr )
257
+ aft. fold_expr ) ,
258
+ fold_ty: bind replace_ty ( repls, _, _, _,
259
+ aft. fold_ty )
224
260
with * aft} ;
225
261
let f = make_fold ( f_pre) ;
226
262
ret f. fold_expr ( e) ;
227
263
}
228
264
229
- fn replace_expr ( repls : [ @ast :: expr ] ,
265
+ fn replace_expr ( repls : [ fragment ] ,
230
266
e : ast:: expr_ , s : span , fld : ast_fold ,
231
267
orig : fn @( ast:: expr_ , span , ast_fold ) ->( ast:: expr_ , span ) )
232
268
-> ( ast:: expr_ , span )
233
269
{
234
270
alt e {
235
- expr_mac( { node : mac_var ( i) , _} ) { let r = repls[ i] ; ( r. node , r. span ) }
271
+ ast : : expr_mac( { node: mac_var ( i) , _} ) {
272
+ alt ( repls[ i] ) {
273
+ from_expr ( r) { ( r. node , r. span ) }
274
+ _ { fail /* fixme error message */ } } }
275
+ _ { orig( e, s, fld) }
276
+ }
277
+ }
278
+
279
+ fn replace_ty ( repls : [ fragment ] ,
280
+ e : ast:: ty_ , s : span , fld : ast_fold ,
281
+ orig : fn @( ast:: ty_ , span , ast_fold ) ->( ast:: ty_ , span ) )
282
+ -> ( ast:: ty_ , span )
283
+ {
284
+ alt e {
285
+ ast : : ty_mac( { node: mac_var ( i) , _} ) {
286
+ alt ( repls[ i] ) {
287
+ from_ty ( r) { ( r. node , r. span ) }
288
+ _ { fail /* fixme error message */ } } }
236
289
_ { orig( e, s, fld) }
237
290
}
238
291
}
0 commit comments