about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorJohn Clements <clements@racket-lang.org>2014-07-02 22:38:30 -0700
committerJohn Clements <clements@racket-lang.org>2014-07-04 12:07:51 -0700
commit9fdaa948c03a33e703eb5830dbed82ee2afe5101 (patch)
tree7afe9dce992f6e05534894182ea0b6cd7e55802b /src/libsyntax
parentf126eacd115415b0814ceb4a1c71380a0b2eb752 (diff)
downloadrust-9fdaa948c03a33e703eb5830dbed82ee2afe5101.tar.gz
rust-9fdaa948c03a33e703eb5830dbed82ee2afe5101.zip
move RenameList to mtwt, add new_renames abstraction
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ext/base.rs6
-rw-r--r--src/libsyntax/ext/expand.rs7
-rw-r--r--src/libsyntax/ext/mtwt.rs50
3 files changed, 40 insertions, 23 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index d2e69204d33..cf69277594f 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -19,6 +19,7 @@ use parse::parser;
 use parse::token;
 use parse::token::{InternedString, intern, str_to_ident};
 use util::small_vector::SmallVector;
+use ext::mtwt;
 
 use std::collections::HashMap;
 use std::gc::{Gc, GC};
@@ -273,7 +274,7 @@ pub struct BlockInfo {
     // should macros escape from this scope?
     pub macros_escape: bool,
     // what are the pending renames?
-    pub pending_renames: RenameList,
+    pub pending_renames: mtwt::RenameList,
 }
 
 impl BlockInfo {
@@ -285,9 +286,6 @@ impl BlockInfo {
     }
 }
 
-// a list of ident->name renamings
-pub type RenameList = Vec<(ast::Ident, Name)>;
-
 // The base map of methods for expanding syntax extension
 // AST nodes into full ASTs
 pub fn syntax_expander_table() -> SyntaxEnv {
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index a4d32a1c020..11152a6f1da 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -844,17 +844,14 @@ fn expand_pat(p: Gc<ast::Pat>, fld: &mut MacroExpander) -> Gc<ast::Pat> {
 // to every identifier, including both bindings and varrefs
 // (and lots of things that will turn out to be neither)
 pub struct IdentRenamer<'a> {
-    renames: &'a mut RenameList,
+    renames: &'a mtwt::RenameList,
 }
 
 impl<'a> Folder for IdentRenamer<'a> {
     fn fold_ident(&mut self, id: Ident) -> Ident {
-        let new_ctxt = self.renames.iter().fold(id.ctxt, |ctxt, &(from, to)| {
-            mtwt::new_rename(from, to, ctxt)
-        });
         Ident {
             name: id.name,
-            ctxt: new_ctxt,
+            ctxt: mtwt::new_renames(self.renames, id.ctxt),
         }
     }
 }
diff --git a/src/libsyntax/ext/mtwt.rs b/src/libsyntax/ext/mtwt.rs
index 48895d34022..f40b251ca72 100644
--- a/src/libsyntax/ext/mtwt.rs
+++ b/src/libsyntax/ext/mtwt.rs
@@ -54,38 +54,51 @@ pub enum SyntaxContext_ {
     IllegalCtxt
 }
 
+/// A list of ident->name renamings
+pub type RenameList = Vec<(Ident, Name)>;
+
 /// Extend a syntax context with a given mark
-pub fn new_mark(m: Mrk, tail: SyntaxContext) -> SyntaxContext {
-    with_sctable(|table| new_mark_internal(m, tail, table))
+pub fn new_mark(m: Mrk, ctxt: SyntaxContext) -> SyntaxContext {
+    with_sctable(|table| new_mark_internal(m, ctxt, table))
 }
 
-// Extend a syntax context with a given mark and table
-fn new_mark_internal(m: Mrk, tail: SyntaxContext, table: &SCTable) -> SyntaxContext {
-    let key = (tail, m);
+// Extend a syntax context with a given mark and sctable (explicit memoization)
+fn new_mark_internal(m: Mrk, ctxt: SyntaxContext, table: &SCTable) -> SyntaxContext {
+    let key = (ctxt, m);
     let new_ctxt = |_: &(SyntaxContext, Mrk)|
-                   idx_push(&mut *table.table.borrow_mut(), Mark(m, tail));
+                   idx_push(&mut *table.table.borrow_mut(), Mark(m, ctxt));
 
     *table.mark_memo.borrow_mut().find_or_insert_with(key, new_ctxt)
 }
 
 /// Extend a syntax context with a given rename
 pub fn new_rename(id: Ident, to:Name,
-                  tail: SyntaxContext) -> SyntaxContext {
-    with_sctable(|table| new_rename_internal(id, to, tail, table))
+                  ctxt: SyntaxContext) -> SyntaxContext {
+    with_sctable(|table| new_rename_internal(id, to, ctxt, table))
 }
 
-// Extend a syntax context with a given rename and sctable
+// Extend a syntax context with a given rename and sctable (explicit memoization)
 fn new_rename_internal(id: Ident,
                        to: Name,
-                       tail: SyntaxContext,
+                       ctxt: SyntaxContext,
                        table: &SCTable) -> SyntaxContext {
-    let key = (tail,id,to);
+    let key = (ctxt,id,to);
     let new_ctxt = |_: &(SyntaxContext, Ident, Mrk)|
-                   idx_push(&mut *table.table.borrow_mut(), Rename(id, to, tail));
+                   idx_push(&mut *table.table.borrow_mut(), Rename(id, to, ctxt));
 
     *table.rename_memo.borrow_mut().find_or_insert_with(key, new_ctxt)
 }
 
+/// Apply a list of renamings to a context
+// if these rename lists get long, it would make sense
+// to consider memoizing this fold. This may come up
+// when we add hygiene to item names.
+pub fn new_renames(renames: &RenameList, ctxt: SyntaxContext) -> SyntaxContext {
+    renames.iter().fold(ctxt, |ctxt, &(from, to)| {
+            new_rename(from, to, ctxt)
+        })
+}
+
 /// Fetch the SCTable from TLS, create one if it doesn't yet exist.
 pub fn with_sctable<T>(op: |&SCTable| -> T) -> T {
     local_data_key!(sctable_key: Rc<SCTable>)
@@ -263,9 +276,9 @@ fn xor_push(marks: &mut Vec<Mrk>, mark: Mrk) {
 
 #[cfg(test)]
 mod tests {
-    use ast::*;
+    use ast::{EMPTY_CTXT, Ident, Mrk, Name, SyntaxContext};
     use super::{resolve, xor_push, new_mark_internal, new_sctable_internal};
-    use super::{new_rename_internal, marksof_internal, resolve_internal};
+    use super::{new_rename_internal, new_renames, marksof_internal, resolve_internal};
     use super::{SCTable, EmptyCtxt, Mark, Rename, IllegalCtxt};
     use std::collections::HashMap;
 
@@ -480,4 +493,13 @@ mod tests {
         resolve_internal(id(30,EMPTY_CTXT),&mut t, &mut rt);
         assert_eq!(rt.len(),2);
     }
+
+    #[test]
+    fn new_resolves_test() {
+        let renames = vec!((Ident{name:23,ctxt:EMPTY_CTXT},24),
+                           (Ident{name:29,ctxt:EMPTY_CTXT},29));
+        let new_ctxt1 = new_renames(&renames,EMPTY_CTXT);
+        assert_eq!(resolve(Ident{name:23,ctxt:new_ctxt1}),24);
+        assert_eq!(resolve(Ident{name:29,ctxt:new_ctxt1}),29);
+    }
 }