Skip to content

Commit

Permalink
move RenameList to mtwt, add new_renames abstraction
Browse files Browse the repository at this point in the history
  • Loading branch information
jbclements committed Jul 4, 2014
1 parent f126eac commit 9fdaa94
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 23 deletions.
6 changes: 2 additions & 4 deletions src/libsyntax/ext/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down
7 changes: 2 additions & 5 deletions src/libsyntax/ext/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
}
}
}
Expand Down
50 changes: 36 additions & 14 deletions src/libsyntax/ext/mtwt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>)
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);
}
}

0 comments on commit 9fdaa94

Please sign in to comment.