@@ -23,6 +23,7 @@ use ext::mtwt;
2323
2424use std:: collections:: HashMap ;
2525use std:: gc:: { Gc , GC } ;
26+ use std:: rc:: Rc ;
2627
2728// new-style macro! tt code:
2829//
@@ -104,9 +105,9 @@ pub type IdentMacroExpanderFn =
104105/// just into the compiler's internal macro table, for `make_def`).
105106pub trait MacResult {
106107 /// 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.
110111 fn make_def ( & self ) -> Option < MacroDef > {
111112 None
112113 }
@@ -314,7 +315,7 @@ impl BlockInfo {
314315
315316/// The base map of methods for expanding syntax extension
316317/// AST nodes into full ASTs
317- pub fn syntax_expander_table ( ) -> SyntaxEnv {
318+ fn initial_syntax_expander_table ( ) -> SyntaxEnv {
318319 // utility function to simplify creating NormalTT syntax extensions
319320 fn builtin_normal_expander ( f : MacroExpanderFn ) -> SyntaxExtension {
320321 NormalTT ( box BasicMacroExpander {
@@ -431,7 +432,9 @@ pub struct ExtCtxt<'a> {
431432
432433 pub mod_path : Vec < ast:: Ident > ,
433434 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 ,
435438}
436439
437440impl < ' a > ExtCtxt < ' a > {
@@ -445,6 +448,7 @@ impl<'a> ExtCtxt<'a> {
445448 ecfg : ecfg,
446449 trace_mac : false ,
447450 exported_macros : Vec :: new ( ) ,
451+ syntax_env : initial_syntax_expander_table ( ) ,
448452 }
449453 }
450454
@@ -453,7 +457,6 @@ impl<'a> ExtCtxt<'a> {
453457 match e. node {
454458 ast:: ExprMac ( ..) => {
455459 let mut expander = expand:: MacroExpander {
456- extsbox : syntax_expander_table ( ) ,
457460 cx : self ,
458461 } ;
459462 e = expand:: expand_expr ( e, & mut expander) ;
@@ -642,10 +645,13 @@ pub fn get_exprs_from_tts(cx: &mut ExtCtxt,
642645/// In order to have some notion of scoping for macros,
643646/// we want to implement the notion of a transformation
644647/// environment.
645-
648+ ///
646649/// This environment maps Names to SyntaxExtensions.
650+ pub struct SyntaxEnv {
651+ chain : Vec < MapChainFrame > ,
652+ }
647653
648- //impl question: how to implement it? Initially, the
654+ // impl question: how to implement it? Initially, the
649655// env will contain only macros, so it might be painful
650656// to add an empty frame for every context. Let's just
651657// get it working, first....
@@ -657,15 +663,11 @@ pub fn get_exprs_from_tts(cx: &mut ExtCtxt,
657663
658664struct MapChainFrame {
659665 info : BlockInfo ,
660- map : HashMap < Name , SyntaxExtension > ,
661- }
662-
663- pub struct SyntaxEnv {
664- chain : Vec < MapChainFrame > ,
666+ map : HashMap < Name , Rc < SyntaxExtension > > ,
665667}
666668
667669impl SyntaxEnv {
668- pub fn new ( ) -> SyntaxEnv {
670+ fn new ( ) -> SyntaxEnv {
669671 let mut map = SyntaxEnv { chain : Vec :: new ( ) } ;
670672 map. push_frame ( ) ;
671673 map
@@ -692,18 +694,18 @@ impl SyntaxEnv {
692694 unreachable ! ( )
693695 }
694696
695- pub fn find < ' a > ( & ' a self , k : & Name ) -> Option < & ' a SyntaxExtension > {
697+ pub fn find ( & self , k : & Name ) -> Option < Rc < SyntaxExtension > > {
696698 for frame in self . chain . iter ( ) . rev ( ) {
697699 match frame. map . find ( k) {
698- Some ( v) => return Some ( v) ,
700+ Some ( v) => return Some ( v. clone ( ) ) ,
699701 None => { }
700702 }
701703 }
702704 None
703705 }
704706
705707 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 ) ) ;
707709 }
708710
709711 pub fn info < ' a > ( & ' a mut self ) -> & ' a mut BlockInfo {
0 commit comments