using visitor for rendering ast
This commit is contained in:
parent
4e59e02178
commit
f6fc83ce02
102
src/ast2/mod.rs
102
src/ast2/mod.rs
|
@ -2162,7 +2162,60 @@ pub mod ast_visitor {
|
||||||
where
|
where
|
||||||
AstT: AstExt,
|
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 self,
|
||||||
mut cb: F,
|
mut cb: F,
|
||||||
) {
|
) {
|
||||||
|
@ -2186,6 +2239,7 @@ pub mod ast_visitor {
|
||||||
match tag {
|
match tag {
|
||||||
Tag::File
|
Tag::File
|
||||||
| Tag::FunctionDecl
|
| Tag::FunctionDecl
|
||||||
|
| Tag::GlobalDecl
|
||||||
| Tag::Block
|
| Tag::Block
|
||||||
| Tag::BlockTrailingExpr => {
|
| Tag::BlockTrailingExpr => {
|
||||||
self.scopes.push(i);
|
self.scopes.push(i);
|
||||||
|
@ -2196,11 +2250,13 @@ pub mod ast_visitor {
|
||||||
A::PopSelf(i) => {
|
A::PopSelf(i) => {
|
||||||
// already popped.
|
// already popped.
|
||||||
let (tag, data) = self.ast.get_node_tag_and_data(i);
|
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 {
|
match tag {
|
||||||
Tag::File
|
Tag::File
|
||||||
| Tag::FunctionDecl
|
| Tag::FunctionDecl
|
||||||
|
| Tag::GlobalDecl
|
||||||
| Tag::Block
|
| Tag::Block
|
||||||
| Tag::BlockTrailingExpr => {
|
| Tag::BlockTrailingExpr => {
|
||||||
self.scopes.pop();
|
self.scopes.pop();
|
||||||
|
@ -2272,37 +2328,21 @@ impl<'a> AstRenderer<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_node<W: core::fmt::Write>(
|
fn render<W: core::fmt::Write>(&mut self, w: &mut W) -> core::fmt::Result {
|
||||||
&mut self,
|
self.ast.visitor().visit_pre(|ast, scopes, node, tag, _| {
|
||||||
w: &mut W,
|
let loc = ast.source_locs[node.index()];
|
||||||
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 children = Children(ast.get_node_children(node));
|
||||||
let ty = self.ast.get_type_of_node(self.ip, &mut self.cache, node);
|
let ty = self.ast.get_type_of_node(self.ip, &mut self.cache, node);
|
||||||
let is_comptime = self
|
let is_comptime =
|
||||||
.ast
|
ast.is_node_comptime_evaluable(&mut self.comptime_cache, node);
|
||||||
.is_node_comptime_evaluable(&mut self.comptime_cache, node);
|
_ = writeln_indented!(
|
||||||
writeln_indented!(
|
scopes.len() as u32 * 2,
|
||||||
indent * 2,
|
|
||||||
w,
|
w,
|
||||||
"{node} {}({ty}) = ({loc}) {tag:?} {children}",
|
"{node} {}({ty}) = ({loc}) {tag:?} {children}",
|
||||||
if is_comptime { "CONST " } else { "" }
|
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)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -2490,7 +2530,7 @@ pub mod ast_gen {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn intern_types(&mut self) {
|
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 {
|
match tag {
|
||||||
Tag::ArrayType => {
|
Tag::ArrayType => {
|
||||||
let (length, pointee) = data.as_two_indices();
|
let (length, pointee) = data.as_two_indices();
|
||||||
|
@ -2619,7 +2659,9 @@ pub mod ast_gen {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve_decl_refs(&mut self) {
|
pub fn resolve_decl_refs(&mut self) {
|
||||||
self.ast.visitor_rev_mut().visit(|ast, node, tag, _data| {
|
self.ast
|
||||||
|
.visitor_rev_mut()
|
||||||
|
.visit_post(|ast, _, node, tag, _| {
|
||||||
match tag {
|
match tag {
|
||||||
Tag::TypeDeclRefUnresolved => {
|
Tag::TypeDeclRefUnresolved => {
|
||||||
let (scope, name) =
|
let (scope, name) =
|
||||||
|
|
Loading…
Reference in a new issue