about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJohn Clements <clements@racket-lang.org>2013-05-21 16:57:21 -0700
committerJohn Clements <clements@racket-lang.org>2013-06-05 12:01:40 -0700
commit91b652695b97c5aef51fdc37c0111b0453ee584e (patch)
tree5c06d1eb75ce662dc4bd971e3c22eb8e80020eb5
parentfe6baa9023cf599a7747e13c67d9adebc3161c59 (diff)
downloadrust-91b652695b97c5aef51fdc37c0111b0453ee584e.tar.gz
rust-91b652695b97c5aef51fdc37c0111b0453ee584e.zip
moved TLS of sctable to ast_util, hid parameter in hygiene calls
-rw-r--r--src/libsyntax/ast_util.rs112
-rw-r--r--src/libsyntax/ext/expand.rs72
2 files changed, 103 insertions, 81 deletions
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 588968365b1..d99363d7ee5 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -14,6 +14,8 @@ use ast::*;
 use ast;
 use ast_util;
 use codemap::{span, spanned};
+use core::cast;
+use core::local_data;
 use opt_vec;
 use parse::token;
 use visit;
@@ -623,12 +625,18 @@ pub enum Privacy {
 pub fn new_ident(name: Name) -> ident { ident {name: name, ctxt: 0}}
 
 /// Extend a syntax context with a given mark
-pub fn new_mark (m:Mrk, tail:SyntaxContext,table:&mut SCTable)
+pub fn new_mark(m:Mrk, tail:SyntaxContext) -> SyntaxContext {
+    new_mark_internal(m,tail,get_sctable())
+}
+
+// Extend a syntax context with a given mark and table
+// FIXME #4536 : currently pub to allow testing
+pub fn new_mark_internal(m:Mrk, tail:SyntaxContext,table:&mut SCTable)
     -> SyntaxContext {
     let key = (tail,m);
     // FIXME #5074 : can't use more natural style because we're missing
     // flow-sensitivity. Results in two lookups on a hash table hit.
-    // also applies to new_rename, below.
+    // also applies to new_rename_internal, below.
     // let try_lookup = table.mark_memo.find(&key);
     match table.mark_memo.contains_key(&key) {
         false => {
@@ -646,7 +654,13 @@ pub fn new_mark (m:Mrk, tail:SyntaxContext,table:&mut SCTable)
 }
 
 /// Extend a syntax context with a given rename
-pub fn new_rename (id:ident, to:Name, tail:SyntaxContext, table: &mut SCTable)
+pub fn new_rename(id:ident, to:Name, tail:SyntaxContext) -> SyntaxContext {
+    new_rename_internal(id, to, tail, get_sctable())
+}
+
+// Extend a syntax context with a given rename and sctable
+// FIXME #4536 : currently pub to allow testing
+pub fn new_rename_internal(id:ident, to:Name, tail:SyntaxContext, table: &mut SCTable)
     -> SyntaxContext {
     let key = (tail,id,to);
     // FIXME #5074
@@ -668,7 +682,8 @@ pub fn new_rename (id:ident, to:Name, tail:SyntaxContext, table: &mut SCTable)
 
 /// Make a fresh syntax context table with EmptyCtxt in slot zero
 /// and IllegalCtxt in slot one.
-pub fn new_sctable() -> SCTable {
+// FIXME #4536 : currently pub to allow testing
+pub fn new_sctable_internal() -> SCTable {
     SCTable {
         table: ~[EmptyCtxt,IllegalCtxt],
         mark_memo: HashMap::new(),
@@ -676,6 +691,23 @@ pub fn new_sctable() -> SCTable {
     }
 }
 
+// fetch the SCTable from TLS, create one if it doesn't yet exist.
+pub fn get_sctable() -> @mut SCTable {
+    unsafe {
+        let sctable_key = (cast::transmute::<(uint, uint),
+                           &fn(v: @@mut SCTable)>(
+                               (-4 as uint, 0u)));
+        match local_data::local_data_get(sctable_key) {
+            None => {
+                let new_table = @@mut new_sctable_internal();
+                local_data::local_data_set(sctable_key,new_table);
+                *new_table
+            },
+            Some(intr) => *intr
+        }
+    }
+}
+
 /// Add a value to the end of a vec, return its index
 fn idx_push<T>(vec: &mut ~[T], val: T) -> uint {
     vec.push(val);
@@ -683,19 +715,25 @@ fn idx_push<T>(vec: &mut ~[T], val: T) -> uint {
 }
 
 /// Resolve a syntax object to a name, per MTWT.
-pub fn resolve (id : ident, table : &mut SCTable) -> Name {
+pub fn resolve(id : ident) -> Name {
+    resolve_internal(id, get_sctable())
+}
+
+// Resolve a syntax object to a name, per MTWT.
+// FIXME #4536 : currently pub to allow testing
+pub fn resolve_internal(id : ident, table : &mut SCTable) -> Name {
     match table.table[id.ctxt] {
         EmptyCtxt => id.name,
         // ignore marks here:
-        Mark(_,subctxt) => resolve (ident{name:id.name, ctxt: subctxt},table),
+        Mark(_,subctxt) => resolve_internal(ident{name:id.name, ctxt: subctxt},table),
         // do the rename if necessary:
         Rename(ident{name,ctxt},toname,subctxt) => {
             // this could be cached or computed eagerly:
-            let resolvedfrom = resolve(ident{name:name,ctxt:ctxt},table);
-            let resolvedthis = resolve(ident{name:id.name,ctxt:subctxt},table);
+            let resolvedfrom = resolve_internal(ident{name:name,ctxt:ctxt},table);
+            let resolvedthis = resolve_internal(ident{name:id.name,ctxt:subctxt},table);
             if ((resolvedthis == resolvedfrom)
-                && (marksof (ctxt,resolvedthis,table)
-                    == marksof (subctxt,resolvedthis,table))) {
+                && (marksof(ctxt,resolvedthis,table)
+                    == marksof(subctxt,resolvedthis,table))) {
                 toname
             } else {
                 resolvedthis
@@ -797,8 +835,8 @@ mod test {
         -> SyntaxContext {
         tscs.foldr(tail, |tsc : &TestSC,tail : SyntaxContext|
                   {match *tsc {
-                      M(mrk) => new_mark(mrk,tail,table),
-                      R(ident,name) => new_rename(ident,name,tail,table)}})
+                      M(mrk) => new_mark_internal(mrk,tail,table),
+                      R(ident,name) => new_rename_internal(ident,name,tail,table)}})
     }
 
     // gather a SyntaxContext back into a vector of TestSCs
@@ -823,7 +861,7 @@ mod test {
     }
 
     #[test] fn test_unfold_refold(){
-        let mut t = new_sctable();
+        let mut t = new_sctable_internal();
 
         let test_sc = ~[M(3),R(id(101,0),14),M(9)];
         assert_eq!(unfold_test_sc(copy test_sc,empty_ctxt,&mut t),4);
@@ -837,11 +875,11 @@ mod test {
     // in a vector. v[0] will be the outermost mark.
     fn unfold_marks(mrks:~[Mrk],tail:SyntaxContext,table: &mut SCTable) -> SyntaxContext {
         mrks.foldr(tail, |mrk:&Mrk,tail:SyntaxContext|
-                   {new_mark(*mrk,tail,table)})
+                   {new_mark_internal(*mrk,tail,table)})
     }
 
     #[test] fn unfold_marks_test() {
-        let mut t = new_sctable();
+        let mut t = new_sctable_internal();
 
         assert_eq!(unfold_marks(~[3,7],empty_ctxt,&mut t),3);
         assert_eq!(t.table[2],Mark(7,0));
@@ -851,7 +889,7 @@ mod test {
     #[test] fn test_marksof () {
         let stopname = 242;
         let name1 = 243;
-        let mut t = new_sctable();
+        let mut t = new_sctable_internal();
         assert_eq!(marksof (empty_ctxt,stopname,&t),~[]);
         // FIXME #5074: ANF'd to dodge nested calls
         { let ans = unfold_marks(~[4,98],empty_ctxt,&mut t);
@@ -865,13 +903,13 @@ mod test {
         // rename where stop doesn't match:
         { let chain = ~[M(9),
                         R(id(name1,
-                             new_mark (4, empty_ctxt,&mut t)),
+                             new_mark_internal (4, empty_ctxt,&mut t)),
                           100101102),
                         M(14)];
          let ans = unfold_test_sc(chain,empty_ctxt,&mut t);
          assert_eq! (marksof (ans, stopname, &t), ~[9,14]);}
         // rename where stop does match
-        { let name1sc = new_mark(4, empty_ctxt, &mut t);
+        { let name1sc = new_mark_internal(4, empty_ctxt, &mut t);
          let chain = ~[M(9),
                        R(id(name1, name1sc),
                          stopname),
@@ -883,30 +921,30 @@ mod test {
 
     #[test] fn resolve_tests () {
         let a = 40;
-        let mut t = new_sctable();
+        let mut t = new_sctable_internal();
         // - ctxt is MT
-        assert_eq!(resolve(id(a,empty_ctxt),&mut t),a);
+        assert_eq!(resolve_internal(id(a,empty_ctxt),&mut t),a);
         // - simple ignored marks
         { let sc = unfold_marks(~[1,2,3],empty_ctxt,&mut t);
-         assert_eq!(resolve(id(a,sc),&mut t),a);}
+         assert_eq!(resolve_internal(id(a,sc),&mut t),a);}
         // - orthogonal rename where names don't match
         { let sc = unfold_test_sc(~[R(id(50,empty_ctxt),51),M(12)],empty_ctxt,&mut t);
-         assert_eq!(resolve(id(a,sc),&mut t),a);}
+         assert_eq!(resolve_internal(id(a,sc),&mut t),a);}
         // - rename where names do match, but marks don't
-        { let sc1 = new_mark(1,empty_ctxt,&mut t);
+        { let sc1 = new_mark_internal(1,empty_ctxt,&mut t);
          let sc = unfold_test_sc(~[R(id(a,sc1),50),
                                    M(1),
                                    M(2)],
                                  empty_ctxt,&mut t);
-        assert_eq!(resolve(id(a,sc),&mut t), a);}
+        assert_eq!(resolve_internal(id(a,sc),&mut t), a);}
         // - rename where names and marks match
         { let sc1 = unfold_test_sc(~[M(1),M(2)],empty_ctxt,&mut t);
          let sc = unfold_test_sc(~[R(id(a,sc1),50),M(1),M(2)],empty_ctxt,&mut t);
-         assert_eq!(resolve(id(a,sc),&mut t), 50); }
+         assert_eq!(resolve_internal(id(a,sc),&mut t), 50); }
         // - rename where names and marks match by literal sharing
         { let sc1 = unfold_test_sc(~[M(1),M(2)],empty_ctxt,&mut t);
          let sc = unfold_test_sc(~[R(id(a,sc1),50)],sc1,&mut t);
-         assert_eq!(resolve(id(a,sc),&mut t), 50); }
+         assert_eq!(resolve_internal(id(a,sc),&mut t), 50); }
         // - two renames of the same var.. can only happen if you use
         // local-expand to prevent the inner binding from being renamed
         // during the rename-pass caused by the first:
@@ -914,28 +952,28 @@ mod test {
         { let sc = unfold_test_sc(~[R(id(a,empty_ctxt),50),
                                     R(id(a,empty_ctxt),51)],
                                   empty_ctxt,&mut t);
-         assert_eq!(resolve(id(a,sc),&mut t), 51); }
+         assert_eq!(resolve_internal(id(a,sc),&mut t), 51); }
         // the simplest double-rename:
-        { let a_to_a50 = new_rename(id(a,empty_ctxt),50,empty_ctxt,&mut t);
-         let a50_to_a51 = new_rename(id(a,a_to_a50),51,a_to_a50,&mut t);
-         assert_eq!(resolve(id(a,a50_to_a51),&mut t),51);
+        { let a_to_a50 = new_rename_internal(id(a,empty_ctxt),50,empty_ctxt,&mut t);
+         let a50_to_a51 = new_rename_internal(id(a,a_to_a50),51,a_to_a50,&mut t);
+         assert_eq!(resolve_internal(id(a,a50_to_a51),&mut t),51);
          // mark on the outside doesn't stop rename:
-         let sc = new_mark(9,a50_to_a51,&mut t);
-         assert_eq!(resolve(id(a,sc),&mut t),51);
+         let sc = new_mark_internal(9,a50_to_a51,&mut t);
+         assert_eq!(resolve_internal(id(a,sc),&mut t),51);
          // but mark on the inside does:
          let a50_to_a51_b = unfold_test_sc(~[R(id(a,a_to_a50),51),
                                               M(9)],
                                            a_to_a50,
                                            &mut t);
-         assert_eq!(resolve(id(a,a50_to_a51_b),&mut t),50);}
+         assert_eq!(resolve_internal(id(a,a50_to_a51_b),&mut t),50);}
     }
 
     #[test] fn hashing_tests () {
-        let mut t = new_sctable();
-        assert_eq!(new_mark(12,empty_ctxt,&mut t),2);
-        assert_eq!(new_mark(13,empty_ctxt,&mut t),3);
+        let mut t = new_sctable_internal();
+        assert_eq!(new_mark_internal(12,empty_ctxt,&mut t),2);
+        assert_eq!(new_mark_internal(13,empty_ctxt,&mut t),3);
         // using the same one again should result in the same index:
-        assert_eq!(new_mark(12,empty_ctxt,&mut t),2);
+        assert_eq!(new_mark_internal(12,empty_ctxt,&mut t),2);
         // I'm assuming that the rename table will behave the same....
     }
 
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index f5edc50377e..96a0461de1e 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -15,17 +15,15 @@ use ast::{crate, decl_local, expr_, expr_mac, mac_invoc_tt};
 use ast::{item_mac, local_, stmt_, stmt_decl, stmt_mac, stmt_expr, stmt_semi};
 use ast::{SCTable, illegal_ctxt};
 use ast;
-use ast_util::{new_rename, new_mark, resolve, new_sctable};
+use ast_util::{new_rename, new_mark, resolve, get_sctable};
 use attr;
 use codemap;
 use codemap::{span, CallInfo, ExpandedFrom, NameAndSpan, spanned};
-use core::cast;
-use core::local_data;
 use ext::base::*;
 use fold::*;
 use parse;
 use parse::{parse_item_from_source_str};
-use parse::token::{ident_to_str, intern};
+use parse::token::{ident_to_str, intern, fresh_name};
 use visit;
 use visit::{Visitor,mk_vt};
 
@@ -369,7 +367,7 @@ pub fn expand_stmt(extsbox: @mut SyntaxEnv,
 
 // return a visitor that extracts the pat_ident paths
 // from a given pattern and puts them in a mutable
-// array (passed in to the traversal
+// array (passed in to the traversal)
 pub fn new_name_finder() -> @Visitor<@mut ~[ast::ident]> {
     let default_visitor = visit::default_visitor();
     @Visitor{
@@ -395,8 +393,6 @@ pub fn new_name_finder() -> @Visitor<@mut ~[ast::ident]> {
     }
 }
 
-
-
 pub fn expand_block(extsbox: @mut SyntaxEnv,
                     cx: @ExtCtxt,
                     blk: &blk_,
@@ -422,14 +418,13 @@ fn get_block_info(exts : SyntaxEnv) -> BlockInfo {
 // given a mutable list of renames, return a tree-folder that applies those
 // renames.
 fn renames_to_fold(renames : @mut ~[(ast::ident,ast::Name)]) -> @ast_fold {
-    let table = local_sctable_get();
     let afp = default_ast_fold();
     let f_pre = @AstFoldFns {
         fold_ident: |id,_| {
             // the individual elements are memoized... it would
             // also be possible to memoize on the whole list at once.
             let new_ctxt = renames.foldl(id.ctxt,|ctxt,&(from,to)| {
-                new_rename(from,to,*ctxt,table)
+                new_rename(from,to,*ctxt)
             });
             ast::ident{name:id.name,ctxt:new_ctxt}
         },
@@ -446,22 +441,6 @@ fn apply_pending_renames(folder : @ast_fold, stmt : ast::stmt) -> @ast::stmt {
     }
 }
 
-// fetch the SCTable from TLS, create one if it doesn't yet exist.
-fn local_sctable_get() -> @mut SCTable {
-    unsafe {
-        let sctable_key = (cast::transmute::<(uint, uint),
-                           &fn(v: @@mut SCTable)>(
-                               (-4 as uint, 0u)));
-        match local_data::local_data_get(sctable_key) {
-            None => {
-                let new_table = @@mut new_sctable();
-                local_data::local_data_set(sctable_key,new_table);
-                *new_table
-            },
-            Some(intr) => *intr
-        }
-    }
-}
 
 
 pub fn new_span(cx: @ExtCtxt, sp: span) -> span {
@@ -732,35 +711,33 @@ pub fn fun_to_ident_folder(f: @fn(ast::ident)->ast::ident) -> @ast_fold{
 
 // update the ctxts in a path to get a rename node
 pub fn new_ident_renamer(from: ast::ident,
-                      to: ast::Name,
-                      table: @mut SCTable) ->
+                      to: ast::Name) ->
     @fn(ast::ident)->ast::ident {
     |id : ast::ident|
     ast::ident{
         name: id.name,
-        ctxt: new_rename(from,to,id.ctxt,table)
+        ctxt: new_rename(from,to,id.ctxt)
     }
 }
 
 
 // update the ctxts in a path to get a mark node
-pub fn new_ident_marker(mark: uint,
-                        table: @mut SCTable) ->
+pub fn new_ident_marker(mark: uint) ->
     @fn(ast::ident)->ast::ident {
     |id : ast::ident|
     ast::ident{
         name: id.name,
-        ctxt: new_mark(mark,id.ctxt,table)
+        ctxt: new_mark(mark,id.ctxt)
     }
 }
 
 // perform resolution (in the MTWT sense) on all of the
 // idents in the tree. This is the final step in expansion.
-pub fn new_ident_resolver(table: @mut SCTable) ->
+pub fn new_ident_resolver() ->
     @fn(ast::ident)->ast::ident {
     |id : ast::ident|
     ast::ident {
-        name : resolve(id,table),
+        name : resolve(id),
         ctxt : illegal_ctxt
     }
 }
@@ -771,16 +748,18 @@ mod test {
     use super::*;
     use ast;
     use ast::{attribute_, attr_outer, meta_word, empty_ctxt};
-    use ast_util::{new_sctable};
+    use ast_util::{get_sctable};
     use codemap;
     use codemap::spanned;
     use parse;
-    use parse::token::{gensym};
-    use core::io;
-    use core::option::{None, Some};
+    use parse::token::{gensym, intern, get_ident_interner};
+    use print::pprust;
     use util::parser_testing::{string_to_item, string_to_pat, strs_to_idents};
     use visit::{mk_vt,Visitor};
 
+    use core::io;
+    use core::option::{None, Some};
+
     // make sure that fail! is present
     #[test] fn fail_exists_test () {
         let src = ~"fn main() { fail!(\"something appropriately gloomy\");}";
@@ -883,22 +862,27 @@ mod test {
 
     #[test]
     fn renaming () {
-        let maybe_item_ast = string_to_item(@~"fn a() -> int { let b = 13; b} ");
+        let maybe_item_ast = string_to_item(@~"fn a() -> int { let b = 13; b }");
         let item_ast = match maybe_item_ast {
             Some(x) => x,
             None => fail!("test case fail")
         };
-        let table = @mut new_sctable();
-        let a_name = 100; // enforced by testing_interner
-        let a2_name = gensym("a2");
+        let a_name = intern("a");
+        let a2_name = intern("a2");
         let renamer = new_ident_renamer(ast::ident{name:a_name,ctxt:empty_ctxt},
-                                        a2_name,table);
+                                        a2_name);
         let renamed_ast = fun_to_ident_folder(renamer).fold_item(item_ast).get();
-        let resolver = new_ident_resolver(table);
+        let resolver = new_ident_resolver();
         let resolved_ast = fun_to_ident_folder(resolver).fold_item(renamed_ast).get();
-        io::print(fmt!("ast: %?\n",resolved_ast))
+        let resolved_as_str = pprust::item_to_str(resolved_ast,
+                                                  get_ident_interner());
+        assert_eq!(resolved_as_str,~"fn a2() -> int { let b = 13; b }");
+
+
     }
 
+    // sigh... it looks like I have two different renaming mechanisms, now...
+
     #[test]
     fn pat_idents(){
         let pat = string_to_pat(@~"(a,Foo{x:c @ (b,9),y:Bar(4,d)})");