@@ -16,33 +16,54 @@ use token::*;
1616*
1717*/
1818
19- pub fn expand_quote ( cx : ext_ctxt ,
20- sp : span ,
21- tts : ~[ ast:: token_tree ] ) -> base:: mac_result
22- {
19+ pub mod rt {
20+ pub use ast:: * ;
21+ pub use parse:: token:: * ;
22+ pub use parse:: new_parser_from_tt;
23+ }
2324
24- // NB: It appears that the main parser loses its mind if we consider
25- // $foo as a tt_nonterminal during the main parse, so we have to re-parse
26- // under quote_depth > 0. This is silly and should go away; the _guess_ is
27- // it has to do with transition away from supporting old-style macros, so
28- // try removing it when enough of them are gone.
29- let p = parse:: new_parser_from_tt ( cx. parse_sess ( ) , cx. cfg ( ) , tts) ;
30- p. quote_depth += 1 u;
31- let tq = dvec:: DVec ( ) ;
32- while p. token != token:: EOF {
33- tq. push ( p. parse_token_tree ( ) ) ;
34- }
35- let tts = tq. get ( ) ;
25+ pub fn expand_quote_tokens ( cx : ext_ctxt ,
26+ sp : span ,
27+ tts : ~[ ast:: token_tree ] ) -> base:: mac_result {
28+ base:: mr_expr ( expand_tt ( cx, sp, tts) )
29+ }
3630
37- // We want to emit a block expression that does a sequence of 'use's to
38- // import the AST and token constructors, followed by a tt expression.
39- let uses = ~[ build:: mk_glob_use ( cx, sp, ids_ext ( cx, ~[ ~"syntax",
40- ~"ast"] ) ) ,
41- build:: mk_glob_use ( cx, sp, ids_ext ( cx, ~[ ~"syntax",
42- ~"parse",
43- ~"token"] ) ) ] ;
44- base:: mr_expr ( build:: mk_block ( cx, sp, uses, ~[ ] ,
45- Some ( mk_tt ( cx, sp, & ast:: tt_delim ( tts) ) ) ) )
31+ pub fn expand_quote_expr ( cx : ext_ctxt ,
32+ sp : span ,
33+ tts : ~[ ast:: token_tree ] ) -> base:: mac_result {
34+ base:: mr_expr ( expand_parse_call ( cx, sp, ~"parse_expr", ~[ ] , tts) )
35+ }
36+
37+ pub fn expand_quote_item ( cx : ext_ctxt ,
38+ sp : span ,
39+ tts : ~[ ast:: token_tree ] ) -> base:: mac_result {
40+ let e_attrs = build:: mk_uniq_vec_e ( cx, sp, ~[ ] ) ;
41+ base:: mr_expr ( expand_parse_call ( cx, sp, ~"parse_item",
42+ ~[ e_attrs] , tts) )
43+ }
44+
45+ pub fn expand_quote_pat ( cx : ext_ctxt ,
46+ sp : span ,
47+ tts : ~[ ast:: token_tree ] ) -> base:: mac_result {
48+ let e_refutable = build:: mk_lit ( cx, sp, ast:: lit_bool ( true ) ) ;
49+ base:: mr_expr ( expand_parse_call ( cx, sp, ~"parse_pat",
50+ ~[ e_refutable] , tts) )
51+ }
52+
53+ pub fn expand_quote_type ( cx : ext_ctxt ,
54+ sp : span ,
55+ tts : ~[ ast:: token_tree ] ) -> base:: mac_result {
56+ let e_param_colons = build:: mk_lit ( cx, sp, ast:: lit_bool ( false ) ) ;
57+ base:: mr_expr ( expand_parse_call ( cx, sp, ~"parse_type",
58+ ~[ e_param_colons] , tts) )
59+ }
60+
61+ pub fn expand_quote_stmt ( cx : ext_ctxt ,
62+ sp : span ,
63+ tts : ~[ ast:: token_tree ] ) -> base:: mac_result {
64+ let e_attrs = build:: mk_uniq_vec_e ( cx, sp, ~[ ] ) ;
65+ base:: mr_expr ( expand_parse_call ( cx, sp, ~"parse_stmt",
66+ ~[ e_attrs] , tts) )
4667}
4768
4869fn ids_ext ( cx : ext_ctxt , strs : ~[ ~str ] ) -> ~[ ast:: ident ] {
@@ -304,4 +325,64 @@ fn mk_tt(cx: ext_ctxt, sp: span, tt: &ast::token_tree) -> @ast::expr {
304325 ast::tt_nonterminal(sp, ident) =>
305326 build::mk_copy(cx, sp, build::mk_path(cx, sp, ~[ident]))
306327 }
307- }
328+ }
329+
330+
331+ fn expand_tt(cx: ext_ctxt,
332+ sp: span,
333+ tts: ~[ast::token_tree]) -> @ast::expr {
334+ // NB: It appears that the main parser loses its mind if we consider
335+ // $foo as a tt_nonterminal during the main parse, so we have to re-parse
336+ // under quote_depth > 0. This is silly and should go away; the _guess_ is
337+ // it has to do with transition away from supporting old-style macros, so
338+ // try removing it when enough of them are gone.
339+ let p = parse::new_parser_from_tt(cx.parse_sess(), cx.cfg(), tts);
340+ p.quote_depth += 1u;
341+ let tq = dvec::DVec();
342+ while p.token != token::EOF {
343+ tq.push(p.parse_token_tree());
344+ }
345+ let tts = tq.get();
346+
347+ // We want to emit a block expression that does a sequence of 'use's to
348+ // import the runtime module, followed by a tt expression.
349+ let uses = ~[ build::mk_glob_use(cx, sp, ids_ext(cx, ~[~" syntax",
350+ ~"ext",
351+ ~"quote",
352+ ~"rt"] ) ) ] ;
353+ build:: mk_block( cx, sp, uses, ~[ ] ,
354+ Some ( mk_tt( cx, sp, & ast:: tt_delim( tts) ) ) )
355+ }
356+
357+ fn expand_parse_call( cx: ext_ctxt,
358+ sp: span,
359+ parse_method: ~str ,
360+ arg_exprs: ~[ @ast:: expr] ,
361+ tts: ~[ ast:: token_tree] ) -> @ast:: expr {
362+ let tt_expr = expand_tt( cx, sp, tts) ;
363+
364+ let cfg_call = || build:: mk_call_(
365+ cx, sp, build:: mk_access( cx, sp, ids_ext( cx, ~[ ~"ext_cx"] ) ,
366+ id_ext( cx, ~"cfg") ) , ~[ ] ) ;
367+
368+ let parse_sess_call = || build:: mk_call_(
369+ cx, sp, build:: mk_access( cx, sp, ids_ext( cx, ~[ ~"ext_cx"] ) ,
370+ id_ext( cx, ~"parse_sess") ) , ~[ ] ) ;
371+
372+ let new_parser_call =
373+ build:: mk_call( cx, sp,
374+ ids_ext( cx, ~[ ~"syntax",
375+ ~"ext",
376+ ~"quote",
377+ ~"rt",
378+ ~"new_parser_from_tt"] ) ,
379+ ~[ parse_sess_call( ) ,
380+ cfg_call( ) ,
381+ build:: mk_uniq_vec_e( cx, sp, ~[ tt_expr] ) ] ) ;
382+
383+ build:: mk_call_( cx, sp,
384+ build:: mk_access_( cx, sp, new_parser_call,
385+ id_ext( cx, parse_method) ) ,
386+ arg_exprs)
387+ }
388+
0 commit comments