Improve Debug and Display implementations

This commit is contained in:
Sofia 2025-07-09 18:42:08 +03:00
parent 49df6c9ed9
commit d5daaa0e87
8 changed files with 346 additions and 38 deletions

View File

@ -44,7 +44,7 @@ pub struct InstructionHolder {
pub(crate) data: InstructionData,
}
#[derive(Debug, Clone)]
#[derive(Clone)]
pub struct Builder {
modules: Rc<RefCell<Vec<ModuleHolder>>>,
}

View File

@ -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, &params),
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(())
}
}
}
}

View File

@ -91,7 +91,7 @@ pub struct IfExpression(
pub struct LetStatement(pub String, pub Option<Type>, pub Expression, pub TokenRange);
#[derive(Debug, Clone)]
pub struct ImportStatement(Vec<String>, pub TokenRange);
pub struct ImportStatement(pub Vec<String>, pub TokenRange);
#[derive(Debug)]
pub struct FunctionDefinition(pub FunctionSignature, pub Block, pub TokenRange);

View File

@ -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<String, ReidError> {
while !matches!(token_stream.peek().unwrap_or(Token::Eof), Token::Eof) {
let statement = token_stream.parse::<TopLevelStatement>()?;
dbg!(&statement);
statements.push(statement);
}
@ -51,17 +51,15 @@ pub fn compile(source: &str) -> Result<String, ReidError> {
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);

200
reid/src/mir/display.rs Normal file
View File

@ -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::<Vec<_>>()
.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, "<External>"),
}
}
}
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)
}
}

View File

@ -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;

View File

@ -141,8 +141,6 @@ impl Expression {
) -> Result<TypeKind, ErrorKind> {
match &mut self.0 {
ExprKind::Variable(var_ref) => {
dbg!(&state.scope);
let existing = state.or_else(
state
.scope

72
reid/src/pad_adapter.rs Normal file
View File

@ -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)
}
}