提交 2d759046 编写于 作者: J Jeffrey Seyfried

Implement stackless placeholder expansion.

上级 d76bf3ed
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
use tokenstream::TokenTree; use tokenstream::TokenTree;
use util::small_vector::SmallVector; use util::small_vector::SmallVector;
use std::collections::HashMap;
use std::mem; use std::mem;
use std::path::PathBuf; use std::path::PathBuf;
use std::rc::Rc; use std::rc::Rc;
...@@ -182,10 +181,11 @@ fn expand_crate(&mut self, mut krate: ast::Crate) -> ast::Crate { ...@@ -182,10 +181,11 @@ fn expand_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
// Fully expand all the invocations in `expansion`. // Fully expand all the invocations in `expansion`.
fn expand(&mut self, expansion: Expansion) -> Expansion { fn expand(&mut self, expansion: Expansion) -> Expansion {
self.cx.recursion_count = 0;
let (expansion, mut invocations) = self.collect_invocations(expansion); let (expansion, mut invocations) = self.collect_invocations(expansion);
invocations.reverse(); invocations.reverse();
let mut expansions = HashMap::new(); let mut expansions = vec![vec![(0, expansion)]];
while let Some(invoc) = invocations.pop() { while let Some(invoc) = invocations.pop() {
let Invocation { mark, module, depth, backtrace, .. } = invoc; let Invocation { mark, module, depth, backtrace, .. } = invoc;
self.cx.syntax_env.current_module = module; self.cx.syntax_env.current_module = module;
...@@ -198,13 +198,24 @@ fn expand(&mut self, expansion: Expansion) -> Expansion { ...@@ -198,13 +198,24 @@ fn expand(&mut self, expansion: Expansion) -> Expansion {
self.cx.recursion_count = depth + 1; self.cx.recursion_count = depth + 1;
let (expansion, new_invocations) = self.collect_invocations(expansion); let (expansion, new_invocations) = self.collect_invocations(expansion);
expansions.insert(mark.as_u32(), expansion); if expansions.len() == depth {
expansions.push(Vec::new());
}
expansions[depth].push((mark.as_u32(), expansion));
if !self.single_step { if !self.single_step {
invocations.extend(new_invocations.into_iter().rev()); invocations.extend(new_invocations.into_iter().rev());
} }
} }
expansion.fold_with(&mut PlaceholderExpander::new(expansions)) let mut placeholder_expander = PlaceholderExpander::new();
while let Some(expansions) = expansions.pop() {
for (mark, expansion) in expansions.into_iter().rev() {
let expansion = expansion.fold_with(&mut placeholder_expander);
placeholder_expander.add(mark, expansion);
}
}
placeholder_expander.remove(0)
} }
fn collect_invocations(&mut self, expansion: Expansion) -> (Expansion, Vec<Invocation>) { fn collect_invocations(&mut self, expansion: Expansion) -> (Expansion, Vec<Invocation>) {
......
...@@ -74,15 +74,18 @@ pub struct PlaceholderExpander { ...@@ -74,15 +74,18 @@ pub struct PlaceholderExpander {
} }
impl PlaceholderExpander { impl PlaceholderExpander {
pub fn new(expansions: HashMap<ast::NodeId, Expansion>) -> Self { pub fn new() -> Self {
PlaceholderExpander { PlaceholderExpander {
expansions: expansions, expansions: HashMap::new(),
} }
} }
pub fn add(&mut self, id: ast::NodeId, expansion: Expansion) {
self.expansions.insert(id, expansion);
}
pub fn remove(&mut self, id: ast::NodeId) -> Expansion { pub fn remove(&mut self, id: ast::NodeId) -> Expansion {
let expansion = self.expansions.remove(&id).unwrap(); self.expansions.remove(&id).unwrap()
expansion.fold_with(self)
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册