提交 9fdaa948 编写于 作者: J John Clements

move RenameList to mtwt, add new_renames abstraction

上级 f126eacd
......@@ -19,6 +19,7 @@
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 @@ pub fn new() -> 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 {
......
......@@ -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),
}
}
}
......
......@@ -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 @@ fn resolve_table_hashing_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);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册