using the new visitor for debug rendering

This commit is contained in:
Janis 2025-03-06 12:41:39 +01:00
parent f30b7827b8
commit d6450b5f32
7 changed files with 318 additions and 263 deletions

159
src/ast2/debug.rs Normal file
View file

@ -0,0 +1,159 @@
use std::fmt::Display;
use crate::{lexer::SourceLocation, writeln_indented};
use super::{
intern::{self, InternPoolWrapper as InternPool},
visitor::AstVisitorTrait,
Ast, Children, ComptimeCache, Index, Tag, TypeCache,
};
struct AstRenderVisitor<'a, W: core::fmt::Write> {
syms: &'a crate::symbol_table::syms2::Symbols,
ip: &'a InternPool,
cache: TypeCache,
comptime_cache: ComptimeCache,
scopes: Vec<Index>,
w: &'a mut W,
}
impl<'a, W: core::fmt::Write> AstVisitorTrait<&'a Ast> for AstRenderVisitor<'_, W> {
type Error = core::fmt::Error;
type Value = ();
const UNIMPL: Self::Error = core::fmt::Error;
fn visit_any(&mut self, ast: &'a Ast, idx: Index) -> Result<Self::Value, Self::Error> {
let display = NodeDisplay::new(ast, self.ip, idx).with_indent(self.scopes.len() as u32 * 2);
match display.tag {
Tag::File
| Tag::FunctionDecl
| Tag::GlobalDecl
| Tag::Block
| Tag::BlockTrailingExpr => {
self.scopes.push(idx);
}
_ => {}
}
write!(self.w, "{display}")?;
for child in display.children.0 {
self.visit_any(ast, child)?;
}
match display.tag {
Tag::File
| Tag::FunctionDecl
| Tag::GlobalDecl
| Tag::Block
| Tag::BlockTrailingExpr => {
self.scopes.pop();
}
_ => {}
}
Ok(())
}
}
pub struct AstRenderer<'a> {
ast: &'a Ast,
#[allow(dead_code)]
syms: &'a crate::symbol_table::syms2::Symbols,
ip: &'a InternPool,
cache: TypeCache,
comptime_cache: ComptimeCache,
}
pub struct NodeDisplay {
node: Index,
tag: Tag,
loc: SourceLocation,
children: Children,
is_comptime: bool,
ty: intern::Index,
indent: u32,
}
impl NodeDisplay {
pub fn new(ast: &Ast, ip: &InternPool, node: Index) -> NodeDisplay {
let tag = ast.tags[node];
let loc = ast.source_locs[node];
let children = Children(ast.get_node_children(node));
let ty = ast.get_type_of_node(ip, &mut TypeCache::new(), node);
let is_comptime = ast.is_node_comptime_evaluable(&mut ComptimeCache::default(), node);
Self {
node,
tag,
loc,
children,
is_comptime,
ty,
indent: 0,
}
}
fn with_indent(self, indent: u32) -> Self {
Self { indent, ..self }
}
}
impl Display for NodeDisplay {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self {
node,
tag,
loc,
children,
is_comptime,
ty,
indent,
} = self;
writeln_indented!(
*indent,
f,
"{node} {}({ty}) = ({loc}) {tag:?} {children}",
if *is_comptime { "CONST " } else { "" }
)?;
Ok(())
}
}
impl<'a> AstRenderer<'a> {
pub fn new(
ast: &'a Ast,
ip: &'a InternPool,
syms: &'a crate::symbol_table::syms2::Symbols,
) -> Self {
Self {
ast,
syms,
ip,
cache: TypeCache::new(),
comptime_cache: ComptimeCache::default(),
}
}
pub(crate) fn render<W: core::fmt::Write>(&mut self, w: &mut W) -> core::fmt::Result {
let mut visitor = AstRenderVisitor {
syms: self.syms,
ip: self.ip,
cache: TypeCache::new(),
comptime_cache: ComptimeCache::default(),
scopes: Vec::new(),
w,
};
for idx in self.ast.get_root_file_indices() {
visitor.visit_any(self.ast, idx)?;
}
Ok(())
}
}

View file

@ -36,14 +36,14 @@ struct IrFunctionBuilder<'a> {
function: Function, function: Function,
} }
impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> { impl<'b, 'a> AstVisitorTrait<&'a mut super::Ast> for IrFunctionBuilder<'b> {
type Error = Error; type Error = Error;
type Value = Option<u32>; type Value = Option<u32>;
const UNIMPL: Self::Error = Error::Unimplemented; const UNIMPL: Self::Error = Error::Unimplemented;
fn visit_block( fn visit_block(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: super::Index, idx: super::Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
let data = ast.expect_node_data_for_tag(idx, super::Tag::Block); let data = ast.expect_node_data_for_tag(idx, super::Tag::Block);
@ -61,7 +61,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> {
fn visit_place_to_value_conversion( fn visit_place_to_value_conversion(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
let data = ast.expect_node_data_for_tag(idx, super::Tag::PlaceToValueConversion); let data = ast.expect_node_data_for_tag(idx, super::Tag::PlaceToValueConversion);
@ -78,7 +78,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> {
fn visit_value_to_place_conversion( fn visit_value_to_place_conversion(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
let data = ast.expect_node_data_for_tag(idx, super::Tag::ValueToPlaceConversion); let data = ast.expect_node_data_for_tag(idx, super::Tag::ValueToPlaceConversion);
@ -105,7 +105,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> {
fn visit_decl_ref( fn visit_decl_ref(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
let data = ast.expect_node_data_for_tag(idx, super::Tag::DeclRef); let data = ast.expect_node_data_for_tag(idx, super::Tag::DeclRef);
@ -118,7 +118,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> {
fn visit_var_decl( fn visit_var_decl(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
self.visit_var_decl_common(ast, idx) self.visit_var_decl_common(ast, idx)
@ -126,7 +126,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> {
fn visit_mut_var_decl( fn visit_mut_var_decl(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
self.visit_var_decl_common(ast, idx) self.visit_var_decl_common(ast, idx)
@ -134,7 +134,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> {
fn visit_var_assign_decl( fn visit_var_assign_decl(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
self.visit_var_decl_common(ast, idx) self.visit_var_decl_common(ast, idx)
@ -142,7 +142,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> {
fn visit_mut_var_assign_decl( fn visit_mut_var_assign_decl(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
self.visit_var_decl_common(ast, idx) self.visit_var_decl_common(ast, idx)
@ -150,7 +150,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> {
fn visit_return( fn visit_return(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
@ -160,7 +160,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> {
} }
fn visit_return_expr( fn visit_return_expr(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
let data = ast.expect_node_data_for_tag(idx, super::Tag::ReturnExprStmt); let data = ast.expect_node_data_for_tag(idx, super::Tag::ReturnExprStmt);
@ -177,7 +177,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> {
fn visit_constant( fn visit_constant(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
let data = ast.expect_node_data_for_tag(idx, super::Tag::Constant); let data = ast.expect_node_data_for_tag(idx, super::Tag::Constant);
@ -191,7 +191,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> {
fn visit_subscript_expr( fn visit_subscript_expr(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
let data = ast.expect_node_data_for_tag(idx, super::Tag::SubscriptExpr); let data = ast.expect_node_data_for_tag(idx, super::Tag::SubscriptExpr);
@ -214,7 +214,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> {
fn visit_call_expr( fn visit_call_expr(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
let data = ast.expect_node_data_for_tag(idx, super::Tag::CallExpr); let data = ast.expect_node_data_for_tag(idx, super::Tag::CallExpr);
@ -236,7 +236,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> {
fn visit_argument( fn visit_argument(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
let data = ast.expect_node_data_for_tag(idx, super::Tag::Argument); let data = ast.expect_node_data_for_tag(idx, super::Tag::Argument);
@ -252,7 +252,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> {
// fn visit_named_argument( // fn visit_named_argument(
// &mut self, // &mut self,
// ast: &mut super::Ast, // ast: &'a mut super::Ast,
// idx: Index, // idx: Index,
// ) -> Result<Self::Value, Self::Error> { // ) -> Result<Self::Value, Self::Error> {
// todo!() // todo!()
@ -260,7 +260,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> {
fn visit_argument_list( fn visit_argument_list(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
let data = ast.expect_node_data_for_tag(idx, super::Tag::ArgumentList); let data = ast.expect_node_data_for_tag(idx, super::Tag::ArgumentList);
@ -289,7 +289,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> {
fn visit_block_trailing_expr( fn visit_block_trailing_expr(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
let data = ast.expect_node_data_for_tag(idx, super::Tag::BlockTrailingExpr); let data = ast.expect_node_data_for_tag(idx, super::Tag::BlockTrailingExpr);
@ -309,7 +309,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> {
fn visit_function_proto( fn visit_function_proto(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: super::Index, idx: super::Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
let data = ast.expect_node_data_for_tag(idx, super::Tag::FunctionProto); let data = ast.expect_node_data_for_tag(idx, super::Tag::FunctionProto);
@ -327,7 +327,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> {
fn visit_parameter_list( fn visit_parameter_list(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
let data = ast.expect_node_data_for_tag(idx, super::Tag::ParameterList); let data = ast.expect_node_data_for_tag(idx, super::Tag::ParameterList);
@ -345,7 +345,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> {
fn visit_parameter( fn visit_parameter(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
let data = ast.expect_node_data_for_tag(idx, super::Tag::Parameter); let data = ast.expect_node_data_for_tag(idx, super::Tag::Parameter);
@ -364,7 +364,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> {
fn visit_address_of_expr( fn visit_address_of_expr(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
let data = ast.expect_node_data_for_tag(idx, super::Tag::AddressOf); let data = ast.expect_node_data_for_tag(idx, super::Tag::AddressOf);
@ -381,7 +381,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> {
fn visit_assign( fn visit_assign(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
let data = ast.expect_node_data_for_tag(idx, super::Tag::Assign); let data = ast.expect_node_data_for_tag(idx, super::Tag::Assign);
@ -400,7 +400,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> {
fn visit_explicit_cast_expr( fn visit_explicit_cast_expr(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
let data = ast.expect_node_data_for_tag(idx, super::Tag::ExplicitCast); let data = ast.expect_node_data_for_tag(idx, super::Tag::ExplicitCast);
@ -421,7 +421,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> {
fn visit_if_expr( fn visit_if_expr(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
let data = ast.expect_node_data_for_tag(idx, super::Tag::IfExpr); let data = ast.expect_node_data_for_tag(idx, super::Tag::IfExpr);
@ -447,7 +447,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> {
fn visit_if_else_expr( fn visit_if_else_expr(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
let data = ast.expect_node_data_for_tag(idx, super::Tag::IfElseExpr); let data = ast.expect_node_data_for_tag(idx, super::Tag::IfElseExpr);
@ -492,7 +492,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> {
fn visit_deref_expr( fn visit_deref_expr(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
let data = ast.expect_node_data_for_tag(idx, super::Tag::Not); let data = ast.expect_node_data_for_tag(idx, super::Tag::Not);
@ -507,7 +507,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> {
fn visit_not_expr( fn visit_not_expr(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
let data = ast.expect_node_data_for_tag(idx, super::Tag::Not); let data = ast.expect_node_data_for_tag(idx, super::Tag::Not);
@ -522,7 +522,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> {
fn visit_negate_expr( fn visit_negate_expr(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
let data = ast.expect_node_data_for_tag(idx, super::Tag::Negate); let data = ast.expect_node_data_for_tag(idx, super::Tag::Negate);
@ -539,7 +539,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> {
fn visit_or_expr( fn visit_or_expr(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
let data = ast.expect_node_data_for_tag(idx, super::Tag::Or); let data = ast.expect_node_data_for_tag(idx, super::Tag::Or);
@ -577,7 +577,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> {
fn visit_and_expr( fn visit_and_expr(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
let data = ast.expect_node_data_for_tag(idx, super::Tag::Or); let data = ast.expect_node_data_for_tag(idx, super::Tag::Or);
@ -609,112 +609,112 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> {
fn visit_add_expr( fn visit_add_expr(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
self.visit_binop_expr(ast, idx) self.visit_binop_expr(ast, idx)
} }
fn visit_sub_expr( fn visit_sub_expr(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
self.visit_binop_expr(ast, idx) self.visit_binop_expr(ast, idx)
} }
fn visit_div_expr( fn visit_div_expr(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
self.visit_binop_expr(ast, idx) self.visit_binop_expr(ast, idx)
} }
fn visit_rem_expr( fn visit_rem_expr(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
self.visit_binop_expr(ast, idx) self.visit_binop_expr(ast, idx)
} }
fn visit_mul_expr( fn visit_mul_expr(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
self.visit_binop_expr(ast, idx) self.visit_binop_expr(ast, idx)
} }
fn visit_bitand_expr( fn visit_bitand_expr(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
self.visit_binop_expr(ast, idx) self.visit_binop_expr(ast, idx)
} }
fn visit_bitor_expr( fn visit_bitor_expr(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
self.visit_binop_expr(ast, idx) self.visit_binop_expr(ast, idx)
} }
fn visit_bitxor_expr( fn visit_bitxor_expr(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
self.visit_binop_expr(ast, idx) self.visit_binop_expr(ast, idx)
} }
fn visit_eq_expr( fn visit_eq_expr(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
self.visit_binop_expr(ast, idx) self.visit_binop_expr(ast, idx)
} }
fn visit_neq_expr( fn visit_neq_expr(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
self.visit_binop_expr(ast, idx) self.visit_binop_expr(ast, idx)
} }
fn visit_lt_expr( fn visit_lt_expr(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
self.visit_binop_expr(ast, idx) self.visit_binop_expr(ast, idx)
} }
fn visit_gt_expr( fn visit_gt_expr(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
self.visit_binop_expr(ast, idx) self.visit_binop_expr(ast, idx)
} }
fn visit_le_expr( fn visit_le_expr(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
self.visit_binop_expr(ast, idx) self.visit_binop_expr(ast, idx)
} }
fn visit_ge_expr( fn visit_ge_expr(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
self.visit_binop_expr(ast, idx) self.visit_binop_expr(ast, idx)
} }
fn visit_shl_expr( fn visit_shl_expr(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
self.visit_binop_expr(ast, idx) self.visit_binop_expr(ast, idx)
} }
fn visit_shr_expr( fn visit_shr_expr(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
self.visit_binop_expr(ast, idx) self.visit_binop_expr(ast, idx)
@ -722,9 +722,9 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> {
} }
impl IrFunctionBuilder<'_> { impl IrFunctionBuilder<'_> {
fn visit_var_decl_common( fn visit_var_decl_common<'a>(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: Index, idx: Index,
) -> Result<Option<u32>, Error> { ) -> Result<Option<u32>, Error> {
let (tag, data) = ast.get_node_tag_and_data(idx); let (tag, data) = ast.get_node_tag_and_data(idx);
@ -783,7 +783,11 @@ impl IrFunctionBuilder<'_> {
/// handles all binary operations that don't short circuit and visit /// handles all binary operations that don't short circuit and visit
/// both lhs and rhs. /// both lhs and rhs.
fn visit_binop_expr(&mut self, ast: &mut super::Ast, idx: Index) -> Result<Option<u32>, Error> { fn visit_binop_expr<'a>(
&mut self,
ast: &'a mut super::Ast,
idx: Index,
) -> Result<Option<u32>, Error> {
use triples::Data; use triples::Data;
let (tag, data) = ast.get_node_tag_and_data(idx); let (tag, data) = ast.get_node_tag_and_data(idx);
let (lhs, rhs) = data.as_two_indices(); let (lhs, rhs) = data.as_two_indices();
@ -820,14 +824,14 @@ impl IrFunctionBuilder<'_> {
} }
} }
impl AstVisitorTrait for IrBuilder { impl<'a> AstVisitorTrait<&'a mut super::Ast> for IrBuilder {
type Value = (); type Value = ();
type Error = Error; type Error = Error;
const UNIMPL: Self::Error = Error::Unimplemented; const UNIMPL: Self::Error = Error::Unimplemented;
fn visit_function_decl( fn visit_function_decl(
&mut self, &mut self,
ast: &mut super::Ast, ast: &'a mut super::Ast,
idx: super::Index, idx: super::Index,
) -> Result<(), Self::Error> { ) -> Result<(), Self::Error> {
let data = ast.expect_node_data_for_tag(idx, super::Tag::FunctionDecl); let data = ast.expect_node_data_for_tag(idx, super::Tag::FunctionDecl);

View file

@ -10,9 +10,10 @@ use num_bigint::BigInt;
use crate::{ use crate::{
ast::FloatingType, comptime::ComptimeNumber, lexer::SourceLocation, ast::FloatingType, comptime::ComptimeNumber, lexer::SourceLocation,
symbol_table::syms2::DeclKind, tokens::Token, writeln_indented, symbol_table::syms2::DeclKind, tokens::Token,
}; };
pub mod debug;
pub mod intern; pub mod intern;
pub mod ir; pub mod ir;
pub mod parser; pub mod parser;
@ -2192,75 +2193,3 @@ where
} }
} }
} }
pub struct AstRenderer<'a> {
ast: &'a Ast,
#[allow(dead_code)]
syms: &'a crate::symbol_table::syms2::Symbols,
ip: &'a InternPool,
cache: TypeCache,
comptime_cache: ComptimeCache,
}
pub struct NodeDisplay<'a> {
node: Index,
ast: &'a Ast,
ip: &'a InternPool,
}
impl<'a> Display for NodeDisplay<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let node = self.node;
let tag = self.ast.tags[node];
let loc = self.ast.source_locs[node];
let children = Children(self.ast.get_node_children(node));
let ty = self
.ast
.get_type_of_node(self.ip, &mut TypeCache::new(), node);
let is_comptime = self
.ast
.is_node_comptime_evaluable(&mut ComptimeCache::default(), node);
writeln!(
f,
"{node} {}({ty}) = ({loc}) {tag:?} {children}",
if is_comptime { "CONST " } else { "" }
)?;
Ok(())
}
}
impl<'a> AstRenderer<'a> {
pub fn new(
ast: &'a Ast,
ip: &'a InternPool,
syms: &'a crate::symbol_table::syms2::Symbols,
) -> Self {
Self {
ast,
syms,
ip,
cache: TypeCache::new(),
comptime_cache: ComptimeCache::default(),
}
}
fn render<W: core::fmt::Write>(&mut self, w: &mut W) -> core::fmt::Result {
self.ast.visitor().visit_pre(|ast, scopes, node, tag, _| {
let loc = ast.source_locs[node];
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(())
}
}

View file

@ -47,16 +47,12 @@ impl Parser {
} }
} }
pub fn display(&self) -> AstRenderer<'_> { pub fn display(&self) -> debug::AstRenderer<'_> {
AstRenderer::new(&self.ast, &self.intern, &self.syms) debug::AstRenderer::new(&self.ast, &self.intern, &self.syms)
} }
pub fn node_display(&self, node: Index) -> NodeDisplay<'_> { pub fn node_display(&self, node: Index) -> debug::NodeDisplay {
NodeDisplay { debug::NodeDisplay::new(&self.ast, &self.intern, node)
node,
ast: &self.ast,
ip: &self.intern,
}
} }
pub fn create_comptime_folding_graph(&mut self, pointer_bits: u16) { pub fn create_comptime_folding_graph(&mut self, pointer_bits: u16) {
@ -153,6 +149,7 @@ impl Parser {
/// folds more AST-patterns into structures that are easier to build the IR with /// folds more AST-patterns into structures that are easier to build the IR with
pub fn fold_more_patterns(&mut self) { pub fn fold_more_patterns(&mut self) {
use visitor::AstExt; use visitor::AstExt;
self.ast.visitor_mut().visit_post(|ast, _, _i, tag, data| { self.ast.visitor_mut().visit_post(|ast, _, _i, tag, data| {
match tag { match tag {
// normalise functions with block-with-trailing-expr into block // normalise functions with block-with-trailing-expr into block

View file

@ -1,7 +1,22 @@
use super::*; use super::*;
pub trait AstExt { pub trait AstExt {
fn get_node_children(&self, node: Index) -> Vec<Index>; fn get_node_children(&self, node: Index) -> Vec<Index>;
fn get_node_tag_and_data(&self, node: Index) -> (Tag, Data); fn get_node_tag_and_data(&self, node: Index) -> (Tag, Data);
fn get_node_data_for_tag(&self, idx: Index, tag: Tag) -> Option<Data> {
let (t, data) = self.get_node_tag_and_data(idx);
if t == tag {
Some(data)
} else {
None
}
}
fn expect_node_data_for_tag(&self, idx: Index, tag: Tag) -> Data {
self.get_node_data_for_tag(idx, tag)
.expect(&format!("node {idx} is not a {tag:?}"))
}
} }
impl AstExt for &Ast { impl AstExt for &Ast {
@ -13,6 +28,7 @@ impl AstExt for &Ast {
(self.tags[node], self.datas[node]) (self.tags[node], self.datas[node])
} }
} }
impl AstExt for &mut Ast { impl AstExt for &mut Ast {
fn get_node_children(&self, node: Index) -> Vec<Index> { fn get_node_children(&self, node: Index) -> Vec<Index> {
Ast::get_node_children(self, node) Ast::get_node_children(self, node)
@ -236,50 +252,30 @@ impl Ast {
} }
} }
impl Ast { pub trait AstVisitorTrait<Ast: AstExt> {
pub fn visit_all_functions_mut<V>(&mut self, visitor: &mut impl AstVisitorTrait) {
for i in
(0..self.tags.functions.len()).map(|i| Index::new(Kind::Function, i as u32).unwrap())
{
visitor.visit_function_decl(self, i);
}
}
pub fn visit_function_mut<F: FnMut(&mut Self)>(&mut self) {}
}
pub trait AstVisitorTrait {
type Error; type Error;
type Value; type Value;
const UNIMPL: Self::Error; const UNIMPL: Self::Error;
fn visit_function_decl( fn visit_function_decl(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
&mut self,
ast: &mut Ast,
idx: Index,
) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_parameter(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_parameter(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_parameter_list( fn visit_parameter_list(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
&mut self,
ast: &mut Ast,
idx: Index,
) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_block(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_block(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_block_trailing_expr( fn visit_block_trailing_expr(
&mut self, &mut self,
ast: &mut Ast, ast: Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
@ -287,163 +283,141 @@ pub trait AstVisitorTrait {
} }
fn visit_block_maybe_trailing( fn visit_block_maybe_trailing(
&mut self, &mut self,
ast: &mut Ast, ast: Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
use visitor::AstExt;
match ast.get_node_tag_and_data(idx).0 { match ast.get_node_tag_and_data(idx).0 {
Tag::BlockTrailingExpr => self.visit_block(ast, idx), Tag::BlockTrailingExpr => self.visit_block(ast, idx),
Tag::Block => self.visit_block_trailing_expr(ast, idx), Tag::Block => self.visit_block_trailing_expr(ast, idx),
_ => unreachable!(), _ => unreachable!(),
} }
} }
fn visit_function_proto( fn visit_function_proto(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
&mut self,
ast: &mut Ast,
idx: Index,
) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_call_expr(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_call_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_add_expr(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_add_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_sub_expr(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_sub_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_mul_expr(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_mul_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_div_expr(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_div_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_rem_expr(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_rem_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_eq_expr(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_eq_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_neq_expr(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_neq_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_lt_expr(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_lt_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_gt_expr(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_gt_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_le_expr(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_le_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_ge_expr(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_ge_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_shl_expr(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_shl_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_shr_expr(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_shr_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_bitor_expr(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_bitor_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_bitxor_expr(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_bitxor_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_bitand_expr(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_bitand_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_or_expr(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_or_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_and_expr(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_and_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_not_expr(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_not_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_negate_expr(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_negate_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_deref_expr(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_deref_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_address_of_expr( fn visit_address_of_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
&mut self,
ast: &mut Ast,
idx: Index,
) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_explicit_cast_expr( fn visit_explicit_cast_expr(
&mut self, &mut self,
ast: &mut Ast, ast: Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_assign(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_assign(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_subscript_expr( fn visit_subscript_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
&mut self,
ast: &mut Ast,
idx: Index,
) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_if_expr(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_if_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_if_else_expr( fn visit_if_else_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
&mut self,
ast: &mut Ast,
idx: Index,
) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_argument(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_argument(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_any_argument( fn visit_any_argument(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
&mut self,
ast: &mut Ast,
idx: Index,
) -> Result<Self::Value, Self::Error> {
use visitor::AstExt;
match ast.get_node_tag_and_data(idx).0 { match ast.get_node_tag_and_data(idx).0 {
Tag::Argument => self.visit_argument(ast, idx), Tag::Argument => self.visit_argument(ast, idx),
Tag::NamedArgument => self.visit_named_argument(ast, idx), Tag::NamedArgument => self.visit_named_argument(ast, idx),
@ -451,76 +425,60 @@ pub trait AstVisitorTrait {
} }
} }
fn visit_named_argument( fn visit_named_argument(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
&mut self,
ast: &mut Ast,
idx: Index,
) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_argument_list( fn visit_argument_list(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
&mut self,
ast: &mut Ast,
idx: Index,
) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_constant(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_constant(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_return(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_return(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_return_expr(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_return_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_global_decl(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_global_decl(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_var_decl(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_var_decl(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_mut_var_decl( fn visit_mut_var_decl(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
&mut self,
ast: &mut Ast,
idx: Index,
) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_var_assign_decl( fn visit_var_assign_decl(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
&mut self,
ast: &mut Ast,
idx: Index,
) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_mut_var_assign_decl( fn visit_mut_var_assign_decl(
&mut self, &mut self,
ast: &mut Ast, ast: Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_decl_ref(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_decl_ref(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx); _ = (ast, idx);
Err(Self::UNIMPL) Err(Self::UNIMPL)
} }
fn visit_value_to_place_conversion( fn visit_value_to_place_conversion(
&mut self, &mut self,
ast: &mut Ast, ast: Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
let idx = ast let idx = ast
@ -531,7 +489,7 @@ pub trait AstVisitorTrait {
} }
fn visit_place_to_value_conversion( fn visit_place_to_value_conversion(
&mut self, &mut self,
ast: &mut Ast, ast: Ast,
idx: Index, idx: Index,
) -> Result<Self::Value, Self::Error> { ) -> Result<Self::Value, Self::Error> {
let idx = ast let idx = ast
@ -541,8 +499,7 @@ pub trait AstVisitorTrait {
self.visit_any(ast, idx) self.visit_any(ast, idx)
} }
fn visit_any(&mut self, ast: &mut Ast, idx: Index) -> Result<Self::Value, Self::Error> { fn visit_any(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
use visitor::AstExt;
match ast.get_node_tag_and_data(idx).0 { match ast.get_node_tag_and_data(idx).0 {
Tag::FunctionProto => self.visit_function_proto(ast, idx), Tag::FunctionProto => self.visit_function_proto(ast, idx),
Tag::FunctionDecl => self.visit_function_decl(ast, idx), Tag::FunctionDecl => self.visit_function_decl(ast, idx),
@ -609,20 +566,3 @@ pub trait AstVisitorTrait {
} }
} }
} }
impl Ast {
pub fn get_node_data_for_tag(&self, idx: Index, tag: Tag) -> Option<Data> {
use visitor::AstExt;
let (t, data) = self.get_node_tag_and_data(idx);
if t == tag {
Some(data)
} else {
None
}
}
pub fn expect_node_data_for_tag(&self, idx: Index, tag: Tag) -> Data {
self.get_node_data_for_tag(idx, tag)
.expect(&format!("node {idx} is not a {tag:?}"))
}
}

View file

@ -29,6 +29,9 @@ pub mod symbol_table;
pub mod tokens; pub mod tokens;
pub mod triples; pub mod triples;
mod utils;
use utils::unit;
pub fn tokenize<'a>( pub fn tokenize<'a>(
bytes: &'a [u8], bytes: &'a [u8],
) -> Result<lexer::Tokenizer<'a>, (lexer::Tokenizer<'a>, Vec<lexer::TokenizeError>)> { ) -> Result<lexer::Tokenizer<'a>, (lexer::Tokenizer<'a>, Vec<lexer::TokenizeError>)> {
@ -70,5 +73,3 @@ impl BitSize for &[u8] {
bits as u32 bits as u32
} }
} }
pub fn unit<T>(_: T) {}

25
src/utils.rs Normal file
View file

@ -0,0 +1,25 @@
use core::{cell::UnsafeCell, mem::ManuallyDrop};
pub fn unit<T>(_: T) {}
pub struct DropGuard<F: FnOnce()>(UnsafeCell<ManuallyDrop<F>>);
impl<F> DropGuard<F>
where
F: FnOnce(),
{
pub fn new(f: F) -> DropGuard<F> {
Self(UnsafeCell::new(ManuallyDrop::new(f)))
}
}
impl<F> Drop for DropGuard<F>
where
F: FnOnce(),
{
fn drop(&mut self) {
unsafe {
ManuallyDrop::take(&mut *self.0.get())();
}
}
}