Start on pretty_print.rs for pretty-printing ASTs.

This commit is contained in:
Jesse Brault 2025-05-15 11:05:23 -05:00
parent 68a2c22be7
commit 1c2e5300ac
4 changed files with 277 additions and 2 deletions

View File

@ -1,8 +1,8 @@
use pest::Parser;
pub mod build;
mod pretty_print;
pub mod unparse;
// Operators
#[derive(Debug)]

231
src/ast/pretty_print.rs Normal file
View File

@ -0,0 +1,231 @@
use crate::ast::*;
use crate::util::indent_writer::IndentWriter;
use std::fmt::Debug;
trait PrettyPrint {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result;
}
impl PrettyPrint for Identifier {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result {
writer.writeln_indented(&format!("Identifier({})", self.name))
}
}
impl PrettyPrint for FullyQualifiedName {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result {
writer.writeln_indented("FullyQualifiedName")?;
writer.increase_indent();
for identifier in &self.0 {
identifier.pretty_print(writer)?;
}
writer.decrease_indent();
Ok(())
}
}
impl PrettyPrint for TypeUse {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result {
use TypeUse::*;
match self {
Void => {
writer.writeln_indented("TypeUse(Void)")?;
}
InterfaceOrClass(t) => {
writer.increase_indent();
t.pretty_print(writer)?;
writer.decrease_indent();
}
Tuple(t) => {
writer.increase_indent();
t.pretty_print(writer)?;
writer.decrease_indent();
}
Function(t) => {
writer.increase_indent();
t.pretty_print(writer)?;
writer.decrease_indent();
}
}
Ok(())
}
}
impl PrettyPrint for InterfaceOrClassTypeUse {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result {
writer.writeln_indented(&format!(
"InterfaceOrClassTypeUse(borrow_count = {}, is_mutable = {})",
self.borrow_count, self.is_mutable
))?;
writer.increase_indent();
self.fqn.pretty_print(writer)?;
self.generics.pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
}
impl PrettyPrint for TupleTypeUse {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result {
writer.writeln_indented(&format!(
"TupleTypeUse(borrow_count = {}, is_mutable = {})",
self.borrow_count,
self.is_mutable
))?;
writer.increase_indent();
self.arguments.pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
}
impl PrettyPrint for FunctionTypeUse {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result {
writer.writeln_indented(&format!(
"FunctionTypeUse(borrow_count = {})",
self.borrow_count
))?;
writer.increase_indent();
if let Some(function_type_modifier) = &self.function_modifier {
function_type_modifier.pretty_print(writer)?;
}
self.generics.pretty_print(writer)?;
self.parameters.pretty_print(writer)?;
self.return_type.pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
}
impl PrettyPrint for GenericArguments {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result {
writer.writeln_indented("GenericArguments")?;
writer.increase_indent();
for type_use in &self.0 {
type_use.pretty_print(writer)?;
}
writer.decrease_indent();
Ok(())
}
}
impl PrettyPrint for GenericParameters {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result {
writer.writeln_indented("GenericParameters")?;
writer.increase_indent();
for identifier in &self.0 {
identifier.pretty_print(writer)?;
}
writer.decrease_indent();
Ok(())
}
}
impl PrettyPrint for TupleArguments {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result {
writer.writeln_indented("TupleArguments")?;
writer.increase_indent();
for type_use in &self.0 {
type_use.pretty_print(writer)?;
}
writer.decrease_indent();
Ok(())
}
}
impl PrettyPrint for ImplementsList {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result {
writer.writeln_indented("ImplementsList")?;
writer.increase_indent();
for type_use in &self.0 {
type_use.pretty_print(writer)?;
}
writer.decrease_indent();
Ok(())
}
}
impl PrettyPrint for FunctionTypeModifier {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result {
use FunctionTypeModifier::*;
writer.writeln_indented(&format!(
"FunctionTypeModifier({})",
match self {
Cons => "cons",
MutRef => "mut ref",
Mut => "mut",
Ref => "ref"
}
))
}
}
impl PrettyPrint for Parameters {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result {
writer.writeln_indented("Parameters")?;
writer.increase_indent();
for parameter in &self.0 {
parameter.pretty_print(writer)?;
}
writer.decrease_indent();
Ok(())
}
}
impl PrettyPrint for Parameter {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result {
writer.writeln_indented("Parameter")?;
writer.increase_indent();
self.identifier.pretty_print(writer)?;
self.type_use.pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
}
impl PrettyPrint for ReturnType {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result {
writer.writeln_indented("ReturnType")?;
writer.increase_indent();
self.declared_type.pretty_print(writer)?;
self.references.pretty_print(writer)?;
writer.decrease_indent();
Ok(())
}
}
impl PrettyPrint for References {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result {
writer.writeln_indented("References")?;
writer.increase_indent();
for identifier in &self.0 {
identifier.pretty_print(writer)?;
}
writer.decrease_indent();
Ok(())
}
}
impl PrettyPrint for CompilationUnit {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result {
writer.writeln_indented("CompilationUnit")?;
writer.increase_indent();
if let Some(namespace) = &self.namespace {
writer.writeln_indented("Namespace")?;
writer.increase_indent();
namespace.pretty_print(writer)?;
writer.decrease_indent();
}
for declaration in &self.declarations {
declaration.pretty_print(writer)?;
}
writer.decrease_indent();
Ok(())
}
}
impl PrettyPrint for ModuleLevelDeclaration {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result {
todo!()
}
}

44
src/util/indent_writer.rs Normal file
View File

@ -0,0 +1,44 @@
use std::fmt::Write;
pub struct IndentWriter {
indent_level: usize,
indent_string: String,
out: Box<dyn Write>,
}
impl IndentWriter {
pub fn new(start_level: usize, indent_string: String, out: Box<dyn Write>) -> IndentWriter {
IndentWriter {
indent_level: start_level,
indent_string,
out,
}
}
pub fn increase_indent(&mut self) {
self.indent_level += 1;
}
pub fn decrease_indent(&mut self) {
self.indent_level -= 1;
}
pub fn write(&mut self, s: &str) -> std::fmt::Result {
write!(self.out, "{}", s)
}
pub fn writeln(&mut self, s: &str) -> std::fmt::Result {
self.write(&format!("{}\n", s))
}
pub fn write_indented(&mut self, s: &str) -> std::fmt::Result {
for _ in 0..self.indent_level {
write!(self.out, "{}", self.indent_string)?;
}
write!(self.out, "{}", s)
}
pub fn writeln_indented(&mut self, s: &str) -> std::fmt::Result {
self.write_indented(&format!("{}\n", s))
}
}

View File

@ -1 +1 @@
pub mod trie;
pub mod indent_writer;