From d5daaa0e870426d1acd2969371efea2b7745fa7a Mon Sep 17 00:00:00 2001 From: sofia Date: Wed, 9 Jul 2025 18:42:08 +0300 Subject: [PATCH] Improve Debug and Display implementations --- reid-llvm-lib/src/builder.rs | 2 +- reid-llvm-lib/src/debug.rs | 87 +++++++++++---- reid/src/ast/mod.rs | 2 +- reid/src/lib.rs | 10 +- reid/src/mir/display.rs | 200 +++++++++++++++++++++++++++++++++++ reid/src/mir/mod.rs | 9 +- reid/src/mir/typecheck.rs | 2 - reid/src/pad_adapter.rs | 72 +++++++++++++ 8 files changed, 346 insertions(+), 38 deletions(-) create mode 100644 reid/src/mir/display.rs create mode 100644 reid/src/pad_adapter.rs diff --git a/reid-llvm-lib/src/builder.rs b/reid-llvm-lib/src/builder.rs index d995486..7956bd4 100644 --- a/reid-llvm-lib/src/builder.rs +++ b/reid-llvm-lib/src/builder.rs @@ -44,7 +44,7 @@ pub struct InstructionHolder { pub(crate) data: InstructionData, } -#[derive(Debug, Clone)] +#[derive(Clone)] pub struct Builder { modules: Rc>>, } diff --git a/reid-llvm-lib/src/debug.rs b/reid-llvm-lib/src/debug.rs index c353891..9a9c421 100644 --- a/reid-llvm-lib/src/debug.rs +++ b/reid-llvm-lib/src/debug.rs @@ -1,11 +1,17 @@ -use std::fmt::Debug; +use std::fmt::{Debug, Write}; use crate::{CmpPredicate, InstructionData, InstructionKind, TerminatorKind, builder::*}; +impl Debug for Builder { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_list().entries(self.get_modules().borrow().iter()); + Ok(()) + } +} + impl Debug for ModuleHolder { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_tuple(&format!("Module({})", self.data.name)) - .field(&self.value) + f.debug_tuple(&format!("{}({:#?}) ", self.data.name, self.value)) .field(&self.functions) .finish() } @@ -14,7 +20,7 @@ impl Debug for ModuleHolder { impl Debug for FunctionHolder { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_tuple(&format!( - "{}({:?}) -> {:?}", + "{}({:?}) -> {:?} ", self.data.name, self.data.params, self.data.ret )) .field(&self.blocks) @@ -24,8 +30,7 @@ impl Debug for FunctionHolder { impl Debug for BlockHolder { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_tuple(&format!("Block({})", self.data.name)) - .field(&self.value) + f.debug_tuple(&format!("{}[{:?}]", &self.data.name, &self.value)) .field(&self.instructions) .field(&self.data.terminator) .finish() @@ -34,7 +39,9 @@ impl Debug for BlockHolder { impl Debug for InstructionHolder { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{:?} = {:?}", &self.value, &self.data) + self.value.fmt(f)?; + f.write_str(" = ")?; + self.data.fmt(f) } } @@ -46,19 +53,19 @@ impl Debug for InstructionData { impl Debug for ModuleValue { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "M[{}]", &self.0) + write!(f, "M[{:0>2}]", self.0) } } impl Debug for FunctionValue { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "F[{}, {}]", &self.0.0, &self.1,) + write!(f, "F[{:0>2}-{:0>2}]", &self.0.0, self.1) } } impl Debug for BlockValue { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "B[{}, {}, {}]", &self.0.0.0, &self.0.1, self.1) + write!(f, "B[{:0>2}-{:0>2}-{:0>2}]", &self.0.0.0, &self.0.1, self.1) } } @@ -66,7 +73,7 @@ impl Debug for InstructionValue { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!( f, - "I<{}-{}-{}-{}>", + "I[{:0>2}-{:0>2}-{:0>2}-{:0>2}]", &self.0.0.0.0, &self.0.0.1, &self.0.1, self.1 ) } @@ -75,17 +82,41 @@ impl Debug for InstructionValue { impl Debug for InstructionKind { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - Self::Param(nth) => write!(f, "Param({})", &nth), - Self::Constant(c) => write!(f, "{:?}", &c), - Self::Add(lhs, rhs) => write!(f, "{:?} + {:?}", &lhs, &rhs), - Self::Sub(lhs, rhs) => write!(f, "{:?} + {:?}", &lhs, &rhs), - Self::Phi(val) => write!(f, "Phi: {:?}", &val), - Self::ICmp(cmp, lhs, rhs) => write!(f, "{:?} {:?} {:?}", &lhs, &cmp, &rhs), - Self::FunctionCall(fun, params) => write!(f, "{:?}({:?})", &fun, ¶ms), + Self::Param(nth) => fmt_call(f, &"Param", &nth), + Self::Constant(c) => c.fmt(f), + Self::Add(lhs, rhs) => fmt_binop(f, lhs, &"+", rhs), + Self::Sub(lhs, rhs) => fmt_binop(f, lhs, &"-", rhs), + Self::Phi(val) => fmt_call(f, &"Phi", &val), + Self::ICmp(cmp, lhs, rhs) => fmt_binop(f, lhs, cmp, rhs), + Self::FunctionCall(fun, params) => fmt_call(f, fun, params), } } } +fn fmt_binop( + f: &mut std::fmt::Formatter<'_>, + lhs: &impl std::fmt::Debug, + op: &impl std::fmt::Debug, + rhs: &impl std::fmt::Debug, +) -> std::fmt::Result { + lhs.fmt(f)?; + f.write_char(' ')?; + op.fmt(f)?; + f.write_char(' ')?; + rhs.fmt(f) +} + +fn fmt_call( + f: &mut std::fmt::Formatter<'_>, + fun: &impl std::fmt::Debug, + params: &impl std::fmt::Debug, +) -> std::fmt::Result { + fun.fmt(f)?; + f.write_char('(')?; + params.fmt(f)?; + f.write_char(')') +} + impl Debug for CmpPredicate { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { @@ -102,9 +133,23 @@ impl Debug for CmpPredicate { impl Debug for TerminatorKind { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - Self::Ret(val) => write!(f, "Ret {:?}", &val), - Self::Branch(val) => write!(f, "Br {:?}", &val), - Self::CondBr(cond, b1, b2) => write!(f, "CondBr {:?} ? {:?} : {:?}", &cond, &b1, &b2), + Self::Ret(val) => { + write!(f, "Ret ")?; + val.fmt(f) + } + Self::Branch(val) => { + write!(f, "Br ")?; + val.fmt(f) + } + Self::CondBr(cond, b1, b2) => { + write!(f, "CondBr ")?; + cond.fmt(f)?; + write!(f, " ? ")?; + b1.fmt(f)?; + write!(f, " : ")?; + b2.fmt(f)?; + Ok(()) + } } } } diff --git a/reid/src/ast/mod.rs b/reid/src/ast/mod.rs index 038f5f5..8d11539 100644 --- a/reid/src/ast/mod.rs +++ b/reid/src/ast/mod.rs @@ -91,7 +91,7 @@ pub struct IfExpression( pub struct LetStatement(pub String, pub Option, pub Expression, pub TokenRange); #[derive(Debug, Clone)] -pub struct ImportStatement(Vec, pub TokenRange); +pub struct ImportStatement(pub Vec, pub TokenRange); #[derive(Debug)] pub struct FunctionDefinition(pub FunctionSignature, pub Block, pub TokenRange); diff --git a/reid/src/lib.rs b/reid/src/lib.rs index 35ab0aa..2aae4dd 100644 --- a/reid/src/lib.rs +++ b/reid/src/lib.rs @@ -7,6 +7,7 @@ mod ast; mod codegen; mod lexer; pub mod mir; +mod pad_adapter; mod token_stream; mod util; @@ -39,7 +40,6 @@ pub fn compile(source: &str) -> Result { while !matches!(token_stream.peek().unwrap_or(Token::Eof), Token::Eof) { let statement = token_stream.parse::()?; - dbg!(&statement); statements.push(statement); } @@ -51,17 +51,15 @@ pub fn compile(source: &str) -> Result { dbg!(&ast_module); let mut mir_context = mir::Context::from(vec![ast_module]); - dbg!(&mir_context); - let state = mir_context.pass(&mut TypeCheck {}); - dbg!(&mir_context); dbg!(&state); + + println!("{}", &mir_context); + if !state.errors.is_empty() { return Err(ReidError::TypeCheckErrors(state.errors)); } - dbg!(&mir_context); - let mut context = Context::new(); let codegen_modules = mir_context.codegen(&mut context); diff --git a/reid/src/mir/display.rs b/reid/src/mir/display.rs new file mode 100644 index 0000000..78848ae --- /dev/null +++ b/reid/src/mir/display.rs @@ -0,0 +1,200 @@ +use std::fmt::{write, Debug, Display, Write}; + +use crate::pad_adapter::PadAdapter; + +use super::*; + +impl Display for Context { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + for module in &self.modules { + Display::fmt(&module, f)?; + } + Ok(()) + } +} + +impl Display for Module { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + writeln!(f, "Module({}) {{", self.name)?; + + let mut state = Default::default(); + let mut inner_f = PadAdapter::wrap(f, &mut state); + + for import in &self.imports { + writeln!(inner_f, "{}", import)?; + } + for fun in &self.functions { + writeln!(inner_f, "{}", fun)?; + } + writeln!(f, "}}") + } +} + +impl Display for Import { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "import {}", self.0) + } +} + +impl Display for FunctionDefinition { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "fn {}({}) -> {} ", + self.name, + self.parameters + .iter() + .map(|(n, t)| format!("{}: {}", n, t)) + .collect::>() + .join(", "), + self.return_type + )?; + Display::fmt(&self.kind, f) + } +} + +impl Display for FunctionDefinitionKind { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Local(block, _) => { + write!(f, "{}", block)?; + Ok(()) + } + Self::Extern => write!(f, ""), + } + } +} + +impl Display for Block { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + writeln!(f, "{{")?; + let mut state = Default::default(); + let mut inner_f = PadAdapter::wrap(f, &mut state); + for statement in &self.statements { + write!(inner_f, "{}", statement)?; + } + if let Some(ret) = &self.return_expression { + match ret.0 { + ReturnKind::Hard => writeln!(inner_f, "Return(Hard): {}", ret.1), + ReturnKind::Soft => writeln!(inner_f, "Return(Hard): {}", ret.1), + }?; + } else { + writeln!(inner_f, "No Return")?; + } + writeln!(f, "}}") + } +} + +impl Display for Statement { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + writeln!(f, "{}", self.0) + } +} + +impl Display for StmtKind { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Let(var, block) => write!(f, "let {} = {}", var, block), + Self::Import(n) => write!(f, "import {}", n), + Self::Expression(exp) => Display::fmt(exp, f), + } + } +} + +impl Display for Expression { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + Display::fmt(&self.0, f) + } +} + +impl Display for ExprKind { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Variable(var) => Display::fmt(var, f), + Self::Literal(lit) => Display::fmt(lit, f), + Self::BinOp(op, lhs, rhs) => write!(f, "{} {} {}", lhs, op, rhs), + Self::FunctionCall(fc) => Display::fmt(fc, f), + Self::If(if_exp) => Display::fmt(&if_exp, f), + Self::Block(block) => Display::fmt(block, f), + } + } +} + +impl Display for IfExpression { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "if {} ", self.0)?; + Display::fmt(&self.1, f)?; + if let Some(e) = &self.2 { + Display::fmt(&e, f)?; + } + Ok(()) + } +} + +impl Display for FunctionCall { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}<{}>(", self.name, self.return_type)?; + for (i, param) in self.parameters.iter().enumerate() { + Display::fmt(param, f)?; + if i < (self.parameters.len() - 1) { + write!(f, ", ")?; + } + } + write!(f, ")") + } +} + +impl Display for VariableReference { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "v(\"{}\", {})", &self.1, &self.0) + } +} + +impl Display for Literal { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::I8(val) => write!(f, "{}i8", val), + Self::I16(val) => write!(f, "{}i16", val), + Self::I32(val) => write!(f, "{}i32", val), + Self::I64(val) => write!(f, "{}i64", val), + Self::I128(val) => write!(f, "{}i128", val), + Self::U8(val) => write!(f, "{}u8", val), + Self::U16(val) => write!(f, "{}u16", val), + Self::U32(val) => write!(f, "{}u32", val), + Self::U64(val) => write!(f, "{}u64", val), + Self::U128(val) => write!(f, "{}u128", val), + Self::Vague(val) => val.fmt(f), + } + } +} + +impl Display for BinaryOperator { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + BinaryOperator::Add => write!(f, "+"), + BinaryOperator::Minus => write!(f, "-"), + BinaryOperator::Mult => write!(f, "*"), + BinaryOperator::And => write!(f, "&&"), + BinaryOperator::Logic(op) => Display::fmt(op, f), + } + } +} + +impl Display for LogicOperator { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + LogicOperator::LT => write!(f, "<"), + LogicOperator::LE => write!(f, "<="), + LogicOperator::GT => write!(f, ">"), + LogicOperator::GE => write!(f, ">="), + LogicOperator::EQ => write!(f, "=="), + LogicOperator::NE => write!(f, "!="), + } + } +} + +impl Display for Metadata { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{:?}", self.range) + } +} diff --git a/reid/src/mir/mod.rs b/reid/src/mir/mod.rs index 1507cf1..114210b 100644 --- a/reid/src/mir/mod.rs +++ b/reid/src/mir/mod.rs @@ -3,21 +3,16 @@ /// type-checked beforehand. use crate::token_stream::TokenRange; +mod display; pub mod pass; pub mod typecheck; pub mod types; -#[derive(Default, Debug, Clone, Copy)] +#[derive(Debug, Default, Clone, Copy)] pub struct Metadata { pub range: TokenRange, } -impl std::fmt::Display for Metadata { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{:?}", self.range) - } -} - impl std::ops::Add for Metadata { type Output = Metadata; diff --git a/reid/src/mir/typecheck.rs b/reid/src/mir/typecheck.rs index e7084e3..cdf14e1 100644 --- a/reid/src/mir/typecheck.rs +++ b/reid/src/mir/typecheck.rs @@ -141,8 +141,6 @@ impl Expression { ) -> Result { match &mut self.0 { ExprKind::Variable(var_ref) => { - dbg!(&state.scope); - let existing = state.or_else( state .scope diff --git a/reid/src/pad_adapter.rs b/reid/src/pad_adapter.rs new file mode 100644 index 0000000..08d01a7 --- /dev/null +++ b/reid/src/pad_adapter.rs @@ -0,0 +1,72 @@ +// Copyright (c) The Rust Project Contributors +// +// Permission is hereby granted, free of charge, to any +// person obtaining a copy of this software and associated +// documentation files (the "Software"), to deal in the +// Software without restriction, including without +// limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice +// shall be included in all copies or substantial portions +// of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +use std::fmt; + +pub struct PadAdapter<'buf, 'state> { + buf: &'buf mut (dyn fmt::Write + 'buf), + state: &'state mut PadAdapterState, +} + +pub struct PadAdapterState { + on_newline: bool, +} + +impl Default for PadAdapterState { + fn default() -> Self { + PadAdapterState { on_newline: true } + } +} + +impl<'buf, 'state> PadAdapter<'buf, 'state> { + pub fn wrap<'slot, 'fmt: 'buf + 'slot>( + fmt: &'fmt mut fmt::Formatter<'_>, + state: &'state mut PadAdapterState, + ) -> Self { + PadAdapter { buf: fmt, state } + } +} + +impl fmt::Write for PadAdapter<'_, '_> { + fn write_str(&mut self, s: &str) -> fmt::Result { + for s in s.split_inclusive('\n') { + if self.state.on_newline { + self.buf.write_str(" ")?; + } + self.state.on_newline = s.ends_with('\n'); + self.buf.write_str(s)?; + } + Ok(()) + } + + fn write_char(&mut self, c: char) -> fmt::Result { + if self.state.on_newline { + self.buf.write_str(" ")?; + } + self.state.on_newline = c == '\n'; + self.buf.write_char(c) + } +}