@@ -50,19 +50,19 @@ pub trait MacroExpander {
50
50
ecx : & mut ExtCtxt ,
51
51
span : Span ,
52
52
token_tree : & [ ast:: TokenTree ] )
53
- -> MacResult ;
53
+ -> ~ MacResult ;
54
54
}
55
55
56
56
pub type MacroExpanderFn =
57
57
fn ( ecx : & mut ExtCtxt , span : codemap:: Span , token_tree : & [ ast:: TokenTree ] )
58
- -> MacResult ;
58
+ -> ~ MacResult ;
59
59
60
60
impl MacroExpander for BasicMacroExpander {
61
61
fn expand ( & self ,
62
62
ecx : & mut ExtCtxt ,
63
63
span : Span ,
64
64
token_tree : & [ ast:: TokenTree ] )
65
- -> MacResult {
65
+ -> ~ MacResult {
66
66
( self . expander ) ( ecx, span, token_tree)
67
67
}
68
68
}
@@ -78,7 +78,7 @@ pub trait IdentMacroExpander {
78
78
sp : Span ,
79
79
ident : ast:: Ident ,
80
80
token_tree : Vec < ast:: TokenTree > )
81
- -> MacResult ;
81
+ -> ~ MacResult ;
82
82
}
83
83
84
84
impl IdentMacroExpander for BasicIdentMacroExpander {
@@ -87,62 +87,130 @@ impl IdentMacroExpander for BasicIdentMacroExpander {
87
87
sp : Span ,
88
88
ident : ast:: Ident ,
89
89
token_tree : Vec < ast:: TokenTree > )
90
- -> MacResult {
90
+ -> ~ MacResult {
91
91
( self . expander ) ( cx, sp, ident, token_tree)
92
92
}
93
93
}
94
94
95
95
pub type IdentMacroExpanderFn =
96
- fn ( & mut ExtCtxt , Span , ast:: Ident , Vec < ast:: TokenTree > ) -> MacResult ;
96
+ fn ( & mut ExtCtxt , Span , ast:: Ident , Vec < ast:: TokenTree > ) -> ~ MacResult ;
97
97
98
98
pub type MacroCrateRegistrationFun =
99
99
fn ( |ast:: Name , SyntaxExtension |) ;
100
100
101
- pub trait AnyMacro {
102
- fn make_expr ( & self ) -> @ast:: Expr ;
103
- fn make_items ( & self ) -> SmallVector < @ast:: Item > ;
104
- fn make_stmt ( & self ) -> @ast:: Stmt ;
101
+ /// The result of a macro expansion. The return values of the various
102
+ /// methods are spliced into the AST at the callsite of the macro (or
103
+ /// just into the compiler's internal macro table, for `make_def`).
104
+ pub trait MacResult {
105
+ /// Define a new macro.
106
+ fn make_def ( & self ) -> Option < MacroDef > {
107
+ None
108
+ }
109
+ /// Create an expression.
110
+ fn make_expr ( & self ) -> Option < @ast:: Expr > {
111
+ None
112
+ }
113
+ /// Create zero or more items.
114
+ fn make_items ( & self ) -> Option < SmallVector < @ast:: Item > > {
115
+ None
116
+ }
117
+
118
+ /// Create a statement.
119
+ ///
120
+ /// By default this attempts to create an expression statement,
121
+ /// returning None if that fails.
122
+ fn make_stmt ( & self ) -> Option < @ast:: Stmt > {
123
+ self . make_expr ( )
124
+ . map ( |e| @codemap:: respan ( e. span , ast:: StmtExpr ( e, ast:: DUMMY_NODE_ID ) ) )
125
+ }
105
126
}
106
127
128
+ /// A convenience type for macros that return a single expression.
129
+ pub struct MacExpr {
130
+ e : @ast:: Expr
131
+ }
132
+ impl MacExpr {
133
+ pub fn new ( e : @ast:: Expr ) -> ~MacResult {
134
+ ~MacExpr { e : e } as ~MacResult
135
+ }
136
+ }
137
+ impl MacResult for MacExpr {
138
+ fn make_expr ( & self ) -> Option < @ast:: Expr > {
139
+ Some ( self . e )
140
+ }
141
+ }
142
+ /// A convenience type for macros that return a single item.
143
+ pub struct MacItem {
144
+ i : @ast:: Item
145
+ }
146
+ impl MacItem {
147
+ pub fn new ( i : @ast:: Item ) -> ~MacResult {
148
+ ~MacItem { i : i } as ~MacResult
149
+ }
150
+ }
151
+ impl MacResult for MacItem {
152
+ fn make_items ( & self ) -> Option < SmallVector < @ast:: Item > > {
153
+ Some ( SmallVector :: one ( self . i ) )
154
+ }
155
+ fn make_stmt ( & self ) -> Option < @ast:: Stmt > {
156
+ Some ( @codemap:: respan (
157
+ self . i . span ,
158
+ ast:: StmtDecl (
159
+ @codemap:: respan ( self . i . span , ast:: DeclItem ( self . i ) ) ,
160
+ ast:: DUMMY_NODE_ID ) ) )
161
+ }
162
+ }
107
163
108
- pub enum MacResult {
109
- MRExpr ( @ast :: Expr ) ,
110
- MRItem ( @ast :: Item ) ,
111
- MRAny ( ~ AnyMacro : ) ,
112
- MRDef ( MacroDef ) ,
164
+ /// Fill-in macro expansion result, to allow compilation to continue
165
+ /// after hitting errors.
166
+ pub struct DummyResult {
167
+ expr_only : bool ,
168
+ span : Span
113
169
}
114
- impl MacResult {
115
- /// Create an empty expression MacResult; useful for satisfying
116
- /// type signatures after emitting a non-fatal error (which stop
117
- /// compilation well before the validity (or otherwise)) of the
118
- /// expression are checked.
119
- pub fn raw_dummy_expr ( sp : codemap:: Span ) -> @ast:: Expr {
170
+
171
+ impl DummyResult {
172
+ /// Create a default MacResult that can be anything.
173
+ ///
174
+ /// Use this as a return value after hitting any errors and
175
+ /// calling `span_err`.
176
+ pub fn any ( sp : Span ) -> ~MacResult {
177
+ ~DummyResult { expr_only : false , span : sp } as ~MacResult
178
+ }
179
+
180
+ /// Create a default MacResult that can only be an expression.
181
+ ///
182
+ /// Use this for macros that must expand to an expression, so even
183
+ /// if an error is encountered internally, the user will recieve
184
+ /// an error that they also used it in the wrong place.
185
+ pub fn expr ( sp : Span ) -> ~MacResult {
186
+ ~DummyResult { expr_only : true , span : sp } as ~MacResult
187
+ }
188
+
189
+ /// A plain dummy expression.
190
+ pub fn raw_expr ( sp : Span ) -> @ast:: Expr {
120
191
@ast:: Expr {
121
192
id : ast:: DUMMY_NODE_ID ,
122
193
node : ast:: ExprLit ( @codemap:: respan ( sp, ast:: LitNil ) ) ,
123
194
span : sp,
124
195
}
125
196
}
126
- pub fn dummy_expr ( sp : codemap:: Span ) -> MacResult {
127
- MRExpr ( MacResult :: raw_dummy_expr ( sp) )
128
- }
129
- pub fn dummy_any ( sp : codemap:: Span ) -> MacResult {
130
- MRAny ( ~DummyMacResult { sp : sp } )
131
- }
132
- }
133
- struct DummyMacResult {
134
- sp : codemap:: Span
135
197
}
136
- impl AnyMacro for DummyMacResult {
137
- fn make_expr ( & self ) -> @ast:: Expr {
138
- MacResult :: raw_dummy_expr ( self . sp )
198
+
199
+ impl MacResult for DummyResult {
200
+ fn make_expr ( & self ) -> Option < @ast:: Expr > {
201
+ Some ( DummyResult :: raw_expr ( self . span ) )
139
202
}
140
- fn make_items ( & self ) -> SmallVector < @ast:: Item > {
141
- SmallVector :: zero ( )
203
+ fn make_items ( & self ) -> Option < SmallVector < @ast:: Item > > {
204
+ if self . expr_only {
205
+ None
206
+ } else {
207
+ Some ( SmallVector :: zero ( ) )
208
+ }
142
209
}
143
- fn make_stmt ( & self ) -> @ast:: Stmt {
144
- @codemap:: respan ( self . sp ,
145
- ast:: StmtExpr ( MacResult :: raw_dummy_expr ( self . sp ) , ast:: DUMMY_NODE_ID ) )
210
+ fn make_stmt ( & self ) -> Option < @ast:: Stmt > {
211
+ Some ( @codemap:: respan ( self . span ,
212
+ ast:: StmtExpr ( DummyResult :: raw_expr ( self . span ) ,
213
+ ast:: DUMMY_NODE_ID ) ) )
146
214
}
147
215
}
148
216
0 commit comments