@@ -16,33 +16,54 @@ use token::*;
16
16
*
17
17
*/
18
18
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
+ }
23
24
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
+ }
36
30
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) )
46
67
}
47
68
48
69
fn 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 {
304
325
ast::tt_nonterminal(sp, ident) =>
305
326
build::mk_copy(cx, sp, build::mk_path(cx, sp, ~[ident]))
306
327
}
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