diff options
| author | John Clements <clements@racket-lang.org> | 2014-07-02 22:38:30 -0700 |
|---|---|---|
| committer | John Clements <clements@racket-lang.org> | 2014-07-04 12:07:51 -0700 |
| commit | 9fdaa948c03a33e703eb5830dbed82ee2afe5101 (patch) | |
| tree | 7afe9dce992f6e05534894182ea0b6cd7e55802b /src/libsyntax | |
| parent | f126eacd115415b0814ceb4a1c71380a0b2eb752 (diff) | |
| download | rust-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.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 7 | ||||
| -rw-r--r-- | src/libsyntax/ext/mtwt.rs | 50 |
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); + } } |
