From d6450b5f32b49f271d2b7fb3ae2941ec78b54d79 Mon Sep 17 00:00:00 2001 From: Janis Date: Thu, 6 Mar 2025 12:41:39 +0100 Subject: [PATCH] using the new visitor for debug rendering --- src/ast2/debug.rs | 159 +++++++++++++++++++++++++++++++++++ src/ast2/ir.rs | 108 ++++++++++++------------ src/ast2/mod.rs | 75 +---------------- src/ast2/parser.rs | 13 ++- src/ast2/visitor.rs | 196 +++++++++++++++----------------------------- src/lib.rs | 5 +- src/utils.rs | 25 ++++++ 7 files changed, 318 insertions(+), 263 deletions(-) create mode 100644 src/ast2/debug.rs create mode 100644 src/utils.rs diff --git a/src/ast2/debug.rs b/src/ast2/debug.rs new file mode 100644 index 0000000..edc34f5 --- /dev/null +++ b/src/ast2/debug.rs @@ -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, + 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 { + 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(&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(()) + } +} diff --git a/src/ast2/ir.rs b/src/ast2/ir.rs index 6bf74ba..6a3b105 100644 --- a/src/ast2/ir.rs +++ b/src/ast2/ir.rs @@ -36,14 +36,14 @@ struct IrFunctionBuilder<'a> { function: Function, } -impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> { +impl<'b, 'a> AstVisitorTrait<&'a mut super::Ast> for IrFunctionBuilder<'b> { type Error = Error; type Value = Option; const UNIMPL: Self::Error = Error::Unimplemented; fn visit_block( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: super::Index, ) -> Result { 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( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { 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( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { 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( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { 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( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { self.visit_var_decl_common(ast, idx) @@ -126,7 +126,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> { fn visit_mut_var_decl( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { self.visit_var_decl_common(ast, idx) @@ -134,7 +134,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> { fn visit_var_assign_decl( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { self.visit_var_decl_common(ast, idx) @@ -142,7 +142,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> { fn visit_mut_var_assign_decl( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { self.visit_var_decl_common(ast, idx) @@ -150,7 +150,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> { fn visit_return( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { _ = (ast, idx); @@ -160,7 +160,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> { } fn visit_return_expr( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { 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( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { 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( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { 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( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { 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( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { 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( // &mut self, - // ast: &mut super::Ast, + // ast: &'a mut super::Ast, // idx: Index, // ) -> Result { // todo!() @@ -260,7 +260,7 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> { fn visit_argument_list( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { 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( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { 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( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: super::Index, ) -> Result { 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( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { 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( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { 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( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { 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( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { 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( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { 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( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { 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( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { 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( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { 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( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { 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( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { 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( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { 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( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { 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( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { self.visit_binop_expr(ast, idx) } fn visit_sub_expr( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { self.visit_binop_expr(ast, idx) } fn visit_div_expr( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { self.visit_binop_expr(ast, idx) } fn visit_rem_expr( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { self.visit_binop_expr(ast, idx) } fn visit_mul_expr( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { self.visit_binop_expr(ast, idx) } fn visit_bitand_expr( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { self.visit_binop_expr(ast, idx) } fn visit_bitor_expr( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { self.visit_binop_expr(ast, idx) } fn visit_bitxor_expr( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { self.visit_binop_expr(ast, idx) } fn visit_eq_expr( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { self.visit_binop_expr(ast, idx) } fn visit_neq_expr( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { self.visit_binop_expr(ast, idx) } fn visit_lt_expr( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { self.visit_binop_expr(ast, idx) } fn visit_gt_expr( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { self.visit_binop_expr(ast, idx) } fn visit_le_expr( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { self.visit_binop_expr(ast, idx) } fn visit_ge_expr( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { self.visit_binop_expr(ast, idx) } fn visit_shl_expr( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { self.visit_binop_expr(ast, idx) } fn visit_shr_expr( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result { self.visit_binop_expr(ast, idx) @@ -722,9 +722,9 @@ impl<'a> AstVisitorTrait for IrFunctionBuilder<'a> { } impl IrFunctionBuilder<'_> { - fn visit_var_decl_common( + fn visit_var_decl_common<'a>( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: Index, ) -> Result, Error> { 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 /// both lhs and rhs. - fn visit_binop_expr(&mut self, ast: &mut super::Ast, idx: Index) -> Result, Error> { + fn visit_binop_expr<'a>( + &mut self, + ast: &'a mut super::Ast, + idx: Index, + ) -> Result, Error> { use triples::Data; let (tag, data) = ast.get_node_tag_and_data(idx); 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 Error = Error; const UNIMPL: Self::Error = Error::Unimplemented; fn visit_function_decl( &mut self, - ast: &mut super::Ast, + ast: &'a mut super::Ast, idx: super::Index, ) -> Result<(), Self::Error> { let data = ast.expect_node_data_for_tag(idx, super::Tag::FunctionDecl); diff --git a/src/ast2/mod.rs b/src/ast2/mod.rs index a723530..4284bae 100644 --- a/src/ast2/mod.rs +++ b/src/ast2/mod.rs @@ -10,9 +10,10 @@ use num_bigint::BigInt; use crate::{ 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 ir; 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(&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(()) - } -} diff --git a/src/ast2/parser.rs b/src/ast2/parser.rs index 6dcf183..1a68792 100644 --- a/src/ast2/parser.rs +++ b/src/ast2/parser.rs @@ -47,16 +47,12 @@ impl Parser { } } - pub fn display(&self) -> AstRenderer<'_> { - AstRenderer::new(&self.ast, &self.intern, &self.syms) + pub fn display(&self) -> debug::AstRenderer<'_> { + debug::AstRenderer::new(&self.ast, &self.intern, &self.syms) } - pub fn node_display(&self, node: Index) -> NodeDisplay<'_> { - NodeDisplay { - node, - ast: &self.ast, - ip: &self.intern, - } + pub fn node_display(&self, node: Index) -> debug::NodeDisplay { + debug::NodeDisplay::new(&self.ast, &self.intern, node) } 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 pub fn fold_more_patterns(&mut self) { use visitor::AstExt; + self.ast.visitor_mut().visit_post(|ast, _, _i, tag, data| { match tag { // normalise functions with block-with-trailing-expr into block diff --git a/src/ast2/visitor.rs b/src/ast2/visitor.rs index c853efa..d536139 100644 --- a/src/ast2/visitor.rs +++ b/src/ast2/visitor.rs @@ -1,7 +1,22 @@ use super::*; + pub trait AstExt { fn get_node_children(&self, node: Index) -> Vec; fn get_node_tag_and_data(&self, node: Index) -> (Tag, Data); + + fn get_node_data_for_tag(&self, idx: Index, tag: Tag) -> Option { + 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 { @@ -13,6 +28,7 @@ impl AstExt for &Ast { (self.tags[node], self.datas[node]) } } + impl AstExt for &mut Ast { fn get_node_children(&self, node: Index) -> Vec { Ast::get_node_children(self, node) @@ -236,50 +252,30 @@ impl Ast { } } -impl Ast { - pub fn visit_all_functions_mut(&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(&mut self) {} -} - -pub trait AstVisitorTrait { +pub trait AstVisitorTrait { type Error; type Value; const UNIMPL: Self::Error; - fn visit_function_decl( - &mut self, - ast: &mut Ast, - idx: Index, - ) -> Result { + fn visit_function_decl(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_parameter(&mut self, ast: &mut Ast, idx: Index) -> Result { + fn visit_parameter(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_parameter_list( - &mut self, - ast: &mut Ast, - idx: Index, - ) -> Result { + fn visit_parameter_list(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_block(&mut self, ast: &mut Ast, idx: Index) -> Result { + fn visit_block(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } fn visit_block_trailing_expr( &mut self, - ast: &mut Ast, + ast: Ast, idx: Index, ) -> Result { _ = (ast, idx); @@ -287,163 +283,141 @@ pub trait AstVisitorTrait { } fn visit_block_maybe_trailing( &mut self, - ast: &mut Ast, + ast: Ast, idx: Index, ) -> Result { - use visitor::AstExt; match ast.get_node_tag_and_data(idx).0 { Tag::BlockTrailingExpr => self.visit_block(ast, idx), Tag::Block => self.visit_block_trailing_expr(ast, idx), _ => unreachable!(), } } - fn visit_function_proto( - &mut self, - ast: &mut Ast, - idx: Index, - ) -> Result { + fn visit_function_proto(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_call_expr(&mut self, ast: &mut Ast, idx: Index) -> Result { + fn visit_call_expr(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_add_expr(&mut self, ast: &mut Ast, idx: Index) -> Result { + fn visit_add_expr(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_sub_expr(&mut self, ast: &mut Ast, idx: Index) -> Result { + fn visit_sub_expr(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_mul_expr(&mut self, ast: &mut Ast, idx: Index) -> Result { + fn visit_mul_expr(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_div_expr(&mut self, ast: &mut Ast, idx: Index) -> Result { + fn visit_div_expr(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_rem_expr(&mut self, ast: &mut Ast, idx: Index) -> Result { + fn visit_rem_expr(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_eq_expr(&mut self, ast: &mut Ast, idx: Index) -> Result { + fn visit_eq_expr(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_neq_expr(&mut self, ast: &mut Ast, idx: Index) -> Result { + fn visit_neq_expr(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_lt_expr(&mut self, ast: &mut Ast, idx: Index) -> Result { + fn visit_lt_expr(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_gt_expr(&mut self, ast: &mut Ast, idx: Index) -> Result { + fn visit_gt_expr(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_le_expr(&mut self, ast: &mut Ast, idx: Index) -> Result { + fn visit_le_expr(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_ge_expr(&mut self, ast: &mut Ast, idx: Index) -> Result { + fn visit_ge_expr(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_shl_expr(&mut self, ast: &mut Ast, idx: Index) -> Result { + fn visit_shl_expr(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_shr_expr(&mut self, ast: &mut Ast, idx: Index) -> Result { + fn visit_shr_expr(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_bitor_expr(&mut self, ast: &mut Ast, idx: Index) -> Result { + fn visit_bitor_expr(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_bitxor_expr(&mut self, ast: &mut Ast, idx: Index) -> Result { + fn visit_bitxor_expr(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_bitand_expr(&mut self, ast: &mut Ast, idx: Index) -> Result { + fn visit_bitand_expr(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_or_expr(&mut self, ast: &mut Ast, idx: Index) -> Result { + fn visit_or_expr(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_and_expr(&mut self, ast: &mut Ast, idx: Index) -> Result { + fn visit_and_expr(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_not_expr(&mut self, ast: &mut Ast, idx: Index) -> Result { + fn visit_not_expr(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_negate_expr(&mut self, ast: &mut Ast, idx: Index) -> Result { + fn visit_negate_expr(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_deref_expr(&mut self, ast: &mut Ast, idx: Index) -> Result { + fn visit_deref_expr(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_address_of_expr( - &mut self, - ast: &mut Ast, - idx: Index, - ) -> Result { + fn visit_address_of_expr(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } fn visit_explicit_cast_expr( &mut self, - ast: &mut Ast, + ast: Ast, idx: Index, ) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_assign(&mut self, ast: &mut Ast, idx: Index) -> Result { + fn visit_assign(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_subscript_expr( - &mut self, - ast: &mut Ast, - idx: Index, - ) -> Result { + fn visit_subscript_expr(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_if_expr(&mut self, ast: &mut Ast, idx: Index) -> Result { + fn visit_if_expr(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_if_else_expr( - &mut self, - ast: &mut Ast, - idx: Index, - ) -> Result { + fn visit_if_else_expr(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_argument(&mut self, ast: &mut Ast, idx: Index) -> Result { + fn visit_argument(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_any_argument( - &mut self, - ast: &mut Ast, - idx: Index, - ) -> Result { - use visitor::AstExt; + fn visit_any_argument(&mut self, ast: Ast, idx: Index) -> Result { match ast.get_node_tag_and_data(idx).0 { Tag::Argument => self.visit_argument(ast, idx), Tag::NamedArgument => self.visit_named_argument(ast, idx), @@ -451,76 +425,60 @@ pub trait AstVisitorTrait { } } - fn visit_named_argument( - &mut self, - ast: &mut Ast, - idx: Index, - ) -> Result { + fn visit_named_argument(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_argument_list( - &mut self, - ast: &mut Ast, - idx: Index, - ) -> Result { + fn visit_argument_list(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_constant(&mut self, ast: &mut Ast, idx: Index) -> Result { + fn visit_constant(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_return(&mut self, ast: &mut Ast, idx: Index) -> Result { + fn visit_return(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_return_expr(&mut self, ast: &mut Ast, idx: Index) -> Result { + fn visit_return_expr(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_global_decl(&mut self, ast: &mut Ast, idx: Index) -> Result { + fn visit_global_decl(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_var_decl(&mut self, ast: &mut Ast, idx: Index) -> Result { + fn visit_var_decl(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_mut_var_decl( - &mut self, - ast: &mut Ast, - idx: Index, - ) -> Result { + fn visit_mut_var_decl(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_var_assign_decl( - &mut self, - ast: &mut Ast, - idx: Index, - ) -> Result { + fn visit_var_assign_decl(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } fn visit_mut_var_assign_decl( &mut self, - ast: &mut Ast, + ast: Ast, idx: Index, ) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } - fn visit_decl_ref(&mut self, ast: &mut Ast, idx: Index) -> Result { + fn visit_decl_ref(&mut self, ast: Ast, idx: Index) -> Result { _ = (ast, idx); Err(Self::UNIMPL) } fn visit_value_to_place_conversion( &mut self, - ast: &mut Ast, + ast: Ast, idx: Index, ) -> Result { let idx = ast @@ -531,7 +489,7 @@ pub trait AstVisitorTrait { } fn visit_place_to_value_conversion( &mut self, - ast: &mut Ast, + ast: Ast, idx: Index, ) -> Result { let idx = ast @@ -541,8 +499,7 @@ pub trait AstVisitorTrait { self.visit_any(ast, idx) } - fn visit_any(&mut self, ast: &mut Ast, idx: Index) -> Result { - use visitor::AstExt; + fn visit_any(&mut self, ast: Ast, idx: Index) -> Result { match ast.get_node_tag_and_data(idx).0 { Tag::FunctionProto => self.visit_function_proto(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 { - 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:?}")) - } -} diff --git a/src/lib.rs b/src/lib.rs index 9553eab..e20e10a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -29,6 +29,9 @@ pub mod symbol_table; pub mod tokens; pub mod triples; +mod utils; +use utils::unit; + pub fn tokenize<'a>( bytes: &'a [u8], ) -> Result, (lexer::Tokenizer<'a>, Vec)> { @@ -70,5 +73,3 @@ impl BitSize for &[u8] { bits as u32 } } - -pub fn unit(_: T) {} diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..1b3a9eb --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,25 @@ +use core::{cell::UnsafeCell, mem::ManuallyDrop}; + +pub fn unit(_: T) {} + +pub struct DropGuard(UnsafeCell>); + +impl DropGuard +where + F: FnOnce(), +{ + pub fn new(f: F) -> DropGuard { + Self(UnsafeCell::new(ManuallyDrop::new(f))) + } +} + +impl Drop for DropGuard +where + F: FnOnce(), +{ + fn drop(&mut self) { + unsafe { + ManuallyDrop::take(&mut *self.0.get())(); + } + } +}