@@ -23,6 +23,7 @@ use ext::mtwt;
23
23
24
24
use std:: collections:: HashMap ;
25
25
use std:: gc:: { Gc , GC } ;
26
+ use std:: rc:: Rc ;
26
27
27
28
// new-style macro! tt code:
28
29
//
@@ -104,9 +105,9 @@ pub type IdentMacroExpanderFn =
104
105
/// just into the compiler's internal macro table, for `make_def`).
105
106
pub trait MacResult {
106
107
/// Define a new macro.
107
- // this particular flavor should go away; the idea that a macro might
108
- // expand into either a macro definition or an expression, depending
109
- // on what the context wants, is kind of silly.
108
+ // this should go away; the idea that a macro might expand into
109
+ // either a macro definition or an expression, depending on what
110
+ // the context wants, is kind of silly.
110
111
fn make_def ( & self ) -> Option < MacroDef > {
111
112
None
112
113
}
@@ -314,7 +315,7 @@ impl BlockInfo {
314
315
315
316
/// The base map of methods for expanding syntax extension
316
317
/// AST nodes into full ASTs
317
- pub fn syntax_expander_table ( ) -> SyntaxEnv {
318
+ fn initial_syntax_expander_table ( ) -> SyntaxEnv {
318
319
// utility function to simplify creating NormalTT syntax extensions
319
320
fn builtin_normal_expander ( f : MacroExpanderFn ) -> SyntaxExtension {
320
321
NormalTT ( box BasicMacroExpander {
@@ -431,7 +432,9 @@ pub struct ExtCtxt<'a> {
431
432
432
433
pub mod_path : Vec < ast:: Ident > ,
433
434
pub trace_mac : bool ,
434
- pub exported_macros : Vec < Gc < ast:: Item > >
435
+ pub exported_macros : Vec < Gc < ast:: Item > > ,
436
+
437
+ pub syntax_env : SyntaxEnv ,
435
438
}
436
439
437
440
impl < ' a > ExtCtxt < ' a > {
@@ -445,6 +448,7 @@ impl<'a> ExtCtxt<'a> {
445
448
ecfg : ecfg,
446
449
trace_mac : false ,
447
450
exported_macros : Vec :: new ( ) ,
451
+ syntax_env : initial_syntax_expander_table ( ) ,
448
452
}
449
453
}
450
454
@@ -453,7 +457,6 @@ impl<'a> ExtCtxt<'a> {
453
457
match e. node {
454
458
ast:: ExprMac ( ..) => {
455
459
let mut expander = expand:: MacroExpander {
456
- extsbox : syntax_expander_table ( ) ,
457
460
cx : self ,
458
461
} ;
459
462
e = expand:: expand_expr ( e, & mut expander) ;
@@ -642,10 +645,13 @@ pub fn get_exprs_from_tts(cx: &mut ExtCtxt,
642
645
/// In order to have some notion of scoping for macros,
643
646
/// we want to implement the notion of a transformation
644
647
/// environment.
645
-
648
+ ///
646
649
/// This environment maps Names to SyntaxExtensions.
650
+ pub struct SyntaxEnv {
651
+ chain : Vec < MapChainFrame > ,
652
+ }
647
653
648
- //impl question: how to implement it? Initially, the
654
+ // impl question: how to implement it? Initially, the
649
655
// env will contain only macros, so it might be painful
650
656
// to add an empty frame for every context. Let's just
651
657
// get it working, first....
@@ -657,15 +663,11 @@ pub fn get_exprs_from_tts(cx: &mut ExtCtxt,
657
663
658
664
struct MapChainFrame {
659
665
info : BlockInfo ,
660
- map : HashMap < Name , SyntaxExtension > ,
661
- }
662
-
663
- pub struct SyntaxEnv {
664
- chain : Vec < MapChainFrame > ,
666
+ map : HashMap < Name , Rc < SyntaxExtension > > ,
665
667
}
666
668
667
669
impl SyntaxEnv {
668
- pub fn new ( ) -> SyntaxEnv {
670
+ fn new ( ) -> SyntaxEnv {
669
671
let mut map = SyntaxEnv { chain : Vec :: new ( ) } ;
670
672
map. push_frame ( ) ;
671
673
map
@@ -692,18 +694,18 @@ impl SyntaxEnv {
692
694
unreachable ! ( )
693
695
}
694
696
695
- pub fn find < ' a > ( & ' a self , k : & Name ) -> Option < & ' a SyntaxExtension > {
697
+ pub fn find ( & self , k : & Name ) -> Option < Rc < SyntaxExtension > > {
696
698
for frame in self . chain . iter ( ) . rev ( ) {
697
699
match frame. map . find ( k) {
698
- Some ( v) => return Some ( v) ,
700
+ Some ( v) => return Some ( v. clone ( ) ) ,
699
701
None => { }
700
702
}
701
703
}
702
704
None
703
705
}
704
706
705
707
pub fn insert ( & mut self , k : Name , v : SyntaxExtension ) {
706
- self . find_escape_frame ( ) . map . insert ( k, v ) ;
708
+ self . find_escape_frame ( ) . map . insert ( k, Rc :: new ( v ) ) ;
707
709
}
708
710
709
711
pub fn info < ' a > ( & ' a mut self ) -> & ' a mut BlockInfo {
0 commit comments