using visitor for rendering ast
This commit is contained in:
parent
4e59e02178
commit
f6fc83ce02
164
src/ast2/mod.rs
164
src/ast2/mod.rs
|
@ -2162,7 +2162,60 @@ pub mod ast_visitor {
|
|||
where
|
||||
AstT: AstExt,
|
||||
{
|
||||
pub fn visit<F: FnMut(&mut AstT, Index, Tag, Data)>(
|
||||
pub fn visit_pre<F: FnMut(&mut AstT, &[Index], Index, Tag, Data)>(
|
||||
&mut self,
|
||||
mut cb: F,
|
||||
) {
|
||||
while let Some(node) = self.nodes.pop() {
|
||||
match node {
|
||||
A::PushChildren(i) => {
|
||||
self.nodes.push(A::PopSelf(i));
|
||||
let children_iter = self
|
||||
.ast
|
||||
.get_node_children(i)
|
||||
.into_iter()
|
||||
.map(|i| A::PushChildren(i));
|
||||
// inverse because we are popping from the end
|
||||
if !self.rev {
|
||||
self.nodes.extend(children_iter.rev())
|
||||
} else {
|
||||
self.nodes.extend(children_iter)
|
||||
};
|
||||
|
||||
let (tag, data) = self.ast.get_node_tag_and_data(i);
|
||||
|
||||
let _ = cb(&mut self.ast, &self.scopes, i, tag, data);
|
||||
|
||||
match tag {
|
||||
Tag::File
|
||||
| Tag::FunctionDecl
|
||||
| Tag::GlobalDecl
|
||||
| Tag::Block
|
||||
| Tag::BlockTrailingExpr => {
|
||||
self.scopes.push(i);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
A::PopSelf(i) => {
|
||||
// already popped.
|
||||
let (tag, _data) = self.ast.get_node_tag_and_data(i);
|
||||
|
||||
match tag {
|
||||
Tag::File
|
||||
| Tag::FunctionDecl
|
||||
| Tag::GlobalDecl
|
||||
| Tag::Block
|
||||
| Tag::BlockTrailingExpr => {
|
||||
self.scopes.pop();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn visit_post<F: FnMut(&mut AstT, &[Index], Index, Tag, Data)>(
|
||||
&mut self,
|
||||
mut cb: F,
|
||||
) {
|
||||
|
@ -2186,6 +2239,7 @@ pub mod ast_visitor {
|
|||
match tag {
|
||||
Tag::File
|
||||
| Tag::FunctionDecl
|
||||
| Tag::GlobalDecl
|
||||
| Tag::Block
|
||||
| Tag::BlockTrailingExpr => {
|
||||
self.scopes.push(i);
|
||||
|
@ -2196,11 +2250,13 @@ pub mod ast_visitor {
|
|||
A::PopSelf(i) => {
|
||||
// already popped.
|
||||
let (tag, data) = self.ast.get_node_tag_and_data(i);
|
||||
let _ = cb(&mut self.ast, i, tag, data);
|
||||
|
||||
let _ = cb(&mut self.ast, &self.scopes, i, tag, data);
|
||||
|
||||
match tag {
|
||||
Tag::File
|
||||
| Tag::FunctionDecl
|
||||
| Tag::GlobalDecl
|
||||
| Tag::Block
|
||||
| Tag::BlockTrailingExpr => {
|
||||
self.scopes.pop();
|
||||
|
@ -2272,37 +2328,21 @@ impl<'a> AstRenderer<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn render_node<W: core::fmt::Write>(
|
||||
&mut self,
|
||||
w: &mut W,
|
||||
indent: u32,
|
||||
node: Index,
|
||||
) -> core::fmt::Result {
|
||||
let tag = self.ast.tags[node.index()];
|
||||
let loc = self.ast.source_locs[node.index()];
|
||||
|
||||
let children = Children(self.ast.get_node_children(node));
|
||||
let ty = self.ast.get_type_of_node(self.ip, &mut self.cache, node);
|
||||
let is_comptime = self
|
||||
.ast
|
||||
.is_node_comptime_evaluable(&mut self.comptime_cache, node);
|
||||
writeln_indented!(
|
||||
indent * 2,
|
||||
w,
|
||||
"{node} {}({ty}) = ({loc}) {tag:?} {children}",
|
||||
if is_comptime { "CONST " } else { "" }
|
||||
)?;
|
||||
|
||||
for child in children.0 {
|
||||
self.render_node(w, indent + 1, child)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
fn render<W: core::fmt::Write>(&mut self, w: &mut W) -> core::fmt::Result {
|
||||
for file in self.ast.get_root_file_indices() {
|
||||
self.render_node(w, 0, file)?;
|
||||
}
|
||||
self.ast.visitor().visit_pre(|ast, scopes, node, tag, _| {
|
||||
let loc = ast.source_locs[node.index()];
|
||||
|
||||
let children = Children(ast.get_node_children(node));
|
||||
let ty = self.ast.get_type_of_node(self.ip, &mut self.cache, node);
|
||||
let is_comptime =
|
||||
ast.is_node_comptime_evaluable(&mut self.comptime_cache, node);
|
||||
_ = writeln_indented!(
|
||||
scopes.len() as u32 * 2,
|
||||
w,
|
||||
"{node} {}({ty}) = ({loc}) {tag:?} {children}",
|
||||
if is_comptime { "CONST " } else { "" }
|
||||
);
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -2490,7 +2530,7 @@ pub mod ast_gen {
|
|||
}
|
||||
|
||||
pub fn intern_types(&mut self) {
|
||||
self.ast.visitor_mut().visit(|ast, i, tag, data| {
|
||||
self.ast.visitor_mut().visit_post(|ast, _, i, tag, data| {
|
||||
match tag {
|
||||
Tag::ArrayType => {
|
||||
let (length, pointee) = data.as_two_indices();
|
||||
|
@ -2619,36 +2659,38 @@ pub mod ast_gen {
|
|||
}
|
||||
|
||||
pub fn resolve_decl_refs(&mut self) {
|
||||
self.ast.visitor_rev_mut().visit(|ast, node, tag, _data| {
|
||||
match tag {
|
||||
Tag::TypeDeclRefUnresolved => {
|
||||
let (scope, name) =
|
||||
ast.datas[node.index()].as_index_intern();
|
||||
// look in my_scope
|
||||
if let Some(decl) = self.syms.find_type_symbol(
|
||||
scope,
|
||||
name,
|
||||
ast.source_locs[node.index()],
|
||||
) {
|
||||
ast.resolve_type_ref(node, decl)
|
||||
};
|
||||
}
|
||||
Tag::DeclRefUnresolved => {
|
||||
let (scope, name) =
|
||||
ast.datas[node.index()].as_index_intern();
|
||||
self.ast
|
||||
.visitor_rev_mut()
|
||||
.visit_post(|ast, _, node, tag, _| {
|
||||
match tag {
|
||||
Tag::TypeDeclRefUnresolved => {
|
||||
let (scope, name) =
|
||||
ast.datas[node.index()].as_index_intern();
|
||||
// look in my_scope
|
||||
if let Some(decl) = self.syms.find_type_symbol(
|
||||
scope,
|
||||
name,
|
||||
ast.source_locs[node.index()],
|
||||
) {
|
||||
ast.resolve_type_ref(node, decl)
|
||||
};
|
||||
}
|
||||
Tag::DeclRefUnresolved => {
|
||||
let (scope, name) =
|
||||
ast.datas[node.index()].as_index_intern();
|
||||
|
||||
// look in my_scope
|
||||
if let Some(decl) = self.syms.find_symbol(
|
||||
scope,
|
||||
name,
|
||||
ast.source_locs[node.index()],
|
||||
) {
|
||||
ast.resolve_decl_ref(node, decl)
|
||||
};
|
||||
// look in my_scope
|
||||
if let Some(decl) = self.syms.find_symbol(
|
||||
scope,
|
||||
name,
|
||||
ast.source_locs[node.index()],
|
||||
) {
|
||||
ast.resolve_decl_ref(node, decl)
|
||||
};
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
fn current_scope(&self) -> Index {
|
||||
|
|
Loading…
Reference in a new issue