@@ -50,19 +50,19 @@ pub trait MacroExpander {
5050 ecx : & mut ExtCtxt ,
5151 span : Span ,
5252 token_tree : & [ ast:: TokenTree ] )
53- -> MacResult ;
53+ -> ~ MacResult ;
5454}
5555
5656pub type MacroExpanderFn =
5757 fn ( ecx : & mut ExtCtxt , span : codemap:: Span , token_tree : & [ ast:: TokenTree ] )
58- -> MacResult ;
58+ -> ~ MacResult ;
5959
6060impl MacroExpander for BasicMacroExpander {
6161 fn expand ( & self ,
6262 ecx : & mut ExtCtxt ,
6363 span : Span ,
6464 token_tree : & [ ast:: TokenTree ] )
65- -> MacResult {
65+ -> ~ MacResult {
6666 ( self . expander ) ( ecx, span, token_tree)
6767 }
6868}
@@ -78,7 +78,7 @@ pub trait IdentMacroExpander {
7878 sp : Span ,
7979 ident : ast:: Ident ,
8080 token_tree : Vec < ast:: TokenTree > )
81- -> MacResult ;
81+ -> ~ MacResult ;
8282}
8383
8484impl IdentMacroExpander for BasicIdentMacroExpander {
@@ -87,62 +87,130 @@ impl IdentMacroExpander for BasicIdentMacroExpander {
8787 sp : Span ,
8888 ident : ast:: Ident ,
8989 token_tree : Vec < ast:: TokenTree > )
90- -> MacResult {
90+ -> ~ MacResult {
9191 ( self . expander ) ( cx, sp, ident, token_tree)
9292 }
9393}
9494
9595pub type IdentMacroExpanderFn =
96- fn ( & mut ExtCtxt , Span , ast:: Ident , Vec < ast:: TokenTree > ) -> MacResult ;
96+ fn ( & mut ExtCtxt , Span , ast:: Ident , Vec < ast:: TokenTree > ) -> ~ MacResult ;
9797
9898pub type MacroCrateRegistrationFun =
9999 fn ( |ast:: Name , SyntaxExtension |) ;
100100
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+ }
105126}
106127
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+ }
107163
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
113169}
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 {
120191 @ast:: Expr {
121192 id : ast:: DUMMY_NODE_ID ,
122193 node : ast:: ExprLit ( @codemap:: respan ( sp, ast:: LitNil ) ) ,
123194 span : sp,
124195 }
125196 }
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
135197}
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 ) )
139202 }
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+ }
142209 }
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 ) ) )
146214 }
147215}
148216
0 commit comments