From 58c66b437e8b7306aa7fdd837cf13868c5d1bae5 Mon Sep 17 00:00:00 2001 From: Jesse Brault Date: Thu, 15 May 2025 11:27:05 -0500 Subject: [PATCH] More work on pretty print; add dmc p3 command. --- src/ast/mod.rs | 2 +- src/ast/pretty_print.rs | 106 +++++++++++++++++++++++++++++--------- src/bin/dmc/main.rs | 14 ++++- src/bin/dmc/p3.rs | 24 +++++++++ src/util/indent_writer.rs | 18 +++---- 5 files changed, 128 insertions(+), 36 deletions(-) create mode 100644 src/bin/dmc/p3.rs diff --git a/src/ast/mod.rs b/src/ast/mod.rs index c1accf7..2759c77 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -1,7 +1,7 @@ use pest::Parser; pub mod build; -mod pretty_print; +pub mod pretty_print; pub mod unparse; // Operators diff --git a/src/ast/pretty_print.rs b/src/ast/pretty_print.rs index cdfb5b8..e2381d2 100644 --- a/src/ast/pretty_print.rs +++ b/src/ast/pretty_print.rs @@ -2,18 +2,18 @@ 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; +pub trait PrettyPrint { + fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()>; } impl PrettyPrint for Identifier { - fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result { + fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { writer.writeln_indented(&format!("Identifier({})", self.name)) } } impl PrettyPrint for FullyQualifiedName { - fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result { + fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { writer.writeln_indented("FullyQualifiedName")?; writer.increase_indent(); for identifier in &self.0 { @@ -25,7 +25,7 @@ impl PrettyPrint for FullyQualifiedName { } impl PrettyPrint for TypeUse { - fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result { + fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use TypeUse::*; match self { Void => { @@ -52,7 +52,7 @@ impl PrettyPrint for TypeUse { } impl PrettyPrint for InterfaceOrClassTypeUse { - fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result { + fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { writer.writeln_indented(&format!( "InterfaceOrClassTypeUse(borrow_count = {}, is_mutable = {})", self.borrow_count, self.is_mutable @@ -66,11 +66,10 @@ impl PrettyPrint for InterfaceOrClassTypeUse { } impl PrettyPrint for TupleTypeUse { - fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result { + fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { writer.writeln_indented(&format!( "TupleTypeUse(borrow_count = {}, is_mutable = {})", - self.borrow_count, - self.is_mutable + self.borrow_count, self.is_mutable ))?; writer.increase_indent(); self.arguments.pretty_print(writer)?; @@ -80,7 +79,7 @@ impl PrettyPrint for TupleTypeUse { } impl PrettyPrint for FunctionTypeUse { - fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result { + fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { writer.writeln_indented(&format!( "FunctionTypeUse(borrow_count = {})", self.borrow_count @@ -98,7 +97,7 @@ impl PrettyPrint for FunctionTypeUse { } impl PrettyPrint for GenericArguments { - fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result { + fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { writer.writeln_indented("GenericArguments")?; writer.increase_indent(); for type_use in &self.0 { @@ -110,7 +109,7 @@ impl PrettyPrint for GenericArguments { } impl PrettyPrint for GenericParameters { - fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result { + fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { writer.writeln_indented("GenericParameters")?; writer.increase_indent(); for identifier in &self.0 { @@ -122,7 +121,7 @@ impl PrettyPrint for GenericParameters { } impl PrettyPrint for TupleArguments { - fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result { + fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { writer.writeln_indented("TupleArguments")?; writer.increase_indent(); for type_use in &self.0 { @@ -134,7 +133,7 @@ impl PrettyPrint for TupleArguments { } impl PrettyPrint for ImplementsList { - fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result { + fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { writer.writeln_indented("ImplementsList")?; writer.increase_indent(); for type_use in &self.0 { @@ -146,7 +145,7 @@ impl PrettyPrint for ImplementsList { } impl PrettyPrint for FunctionTypeModifier { - fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result { + fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use FunctionTypeModifier::*; writer.writeln_indented(&format!( "FunctionTypeModifier({})", @@ -154,14 +153,14 @@ impl PrettyPrint for FunctionTypeModifier { Cons => "cons", MutRef => "mut ref", Mut => "mut", - Ref => "ref" + Ref => "ref", } )) } } impl PrettyPrint for Parameters { - fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result { + fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { writer.writeln_indented("Parameters")?; writer.increase_indent(); for parameter in &self.0 { @@ -173,7 +172,7 @@ impl PrettyPrint for Parameters { } impl PrettyPrint for Parameter { - fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result { + fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { writer.writeln_indented("Parameter")?; writer.increase_indent(); self.identifier.pretty_print(writer)?; @@ -184,7 +183,7 @@ impl PrettyPrint for Parameter { } impl PrettyPrint for ReturnType { - fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result { + fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { writer.writeln_indented("ReturnType")?; writer.increase_indent(); self.declared_type.pretty_print(writer)?; @@ -195,7 +194,7 @@ impl PrettyPrint for ReturnType { } impl PrettyPrint for References { - fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result { + fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { writer.writeln_indented("References")?; writer.increase_indent(); for identifier in &self.0 { @@ -207,7 +206,7 @@ impl PrettyPrint for References { } impl PrettyPrint for CompilationUnit { - fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result { + fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { writer.writeln_indented("CompilationUnit")?; writer.increase_indent(); if let Some(namespace) = &self.namespace { @@ -225,7 +224,66 @@ impl PrettyPrint for CompilationUnit { } impl PrettyPrint for ModuleLevelDeclaration { - fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result { - todo!() - } + fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { + use ModuleLevelDeclaration::*; + match self { + Module(module) => module.pretty_print(writer), + Interface(interface) => interface.pretty_print(writer), + Class(class) => class.pretty_print(writer), + Function(function) => function.pretty_print(writer), + PlatformFunction(platform_function) => platform_function.pretty_print(writer) + } + } } + +impl PrettyPrint for InterfaceLevelDeclaration { + fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { + todo!() + } +} + +impl PrettyPrint for ModuleDeclaration { + fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { + writer.writeln_indented(&format!("ModuleDeclaration(is_public = {})", self.is_public))?; + writer.increase_indent(); + self.identifier.pretty_print(writer)?; + for declaration in &self.declarations { + declaration.pretty_print(writer)?; + } + writer.decrease_indent(); + Ok(()) + } +} + +impl PrettyPrint for InterfaceDeclaration { + fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { + writer.writeln_indented(&format!("InterfaceDeclaration(is_public = {})", self.is_public))?; + writer.increase_indent(); + self.identifier.pretty_print(writer)?; + self.generics.pretty_print(writer)?; + self.implements.pretty_print(writer)?; + for declaration in &self.declarations { + declaration.pretty_print(writer)?; + } + writer.decrease_indent(); + Ok(()) + } +} + +impl PrettyPrint for ClassDeclaration { + fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { + todo!() + } +} + +impl PrettyPrint for FunctionDefinition { + fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { + todo!() + } +} + +impl PrettyPrint for PlatformFunctionDeclaration { + fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { + todo!() + } +} \ No newline at end of file diff --git a/src/bin/dmc/main.rs b/src/bin/dmc/main.rs index 88eb636..4b34a31 100644 --- a/src/bin/dmc/main.rs +++ b/src/bin/dmc/main.rs @@ -1,7 +1,9 @@ mod ast_dump; +mod p3; use std::path::PathBuf; +use crate::p3::pretty_print_parse; use ast_dump::unparse; use clap::{Parser, Subcommand}; @@ -16,7 +18,12 @@ struct Cli { #[derive(Debug, Subcommand)] enum Commands { #[command(arg_required_else_help = true)] - Unparse { paths: Vec }, + Unparse { + paths: Vec, + }, + P3 { + paths: Vec, + }, } fn main() { @@ -27,5 +34,10 @@ fn main() { unparse(&path); } } + Commands::P3 { paths } => { + for path in paths { + pretty_print_parse(&path) + } + } } } diff --git a/src/bin/dmc/p3.rs b/src/bin/dmc/p3.rs new file mode 100644 index 0000000..3710d91 --- /dev/null +++ b/src/bin/dmc/p3.rs @@ -0,0 +1,24 @@ +use deimos::ast::build::build_ast; +use deimos::ast::pretty_print::PrettyPrint; +use deimos::parser::{DeimosParser, Rule}; +use deimos::util::indent_writer::IndentWriter; +use pest::Parser; +use std::path::PathBuf; + +pub fn pretty_print_parse(path: &PathBuf) { + let src = std::fs::read_to_string(path).expect(&format!("Unable to read {:?}", path)); + let parse_result = DeimosParser::parse(Rule::CompilationUnit, &src); + match parse_result { + Ok(mut pairs) => { + let compilation_unit_pair = pairs.next().unwrap(); + let compilation_unit = build_ast(compilation_unit_pair); + let mut indent_writer = IndentWriter::new(0, " ", Box::new(std::io::stdout())); + compilation_unit + .pretty_print(&mut indent_writer) + .expect("Unable to pretty-print."); + } + Err(e) => { + eprintln!("{}", e); + } + } +} diff --git a/src/util/indent_writer.rs b/src/util/indent_writer.rs index 4b62a98..36aa913 100644 --- a/src/util/indent_writer.rs +++ b/src/util/indent_writer.rs @@ -1,16 +1,14 @@ -use std::fmt::Write; - pub struct IndentWriter { indent_level: usize, indent_string: String, - out: Box, + out: Box, } impl IndentWriter { - pub fn new(start_level: usize, indent_string: String, out: Box) -> IndentWriter { + pub fn new(start_level: usize, indent_string: &str, out: Box) -> IndentWriter { IndentWriter { - indent_level: start_level, - indent_string, + indent_level: start_level, + indent_string: indent_string.to_string(), out, } } @@ -23,22 +21,22 @@ impl IndentWriter { self.indent_level -= 1; } - pub fn write(&mut self, s: &str) -> std::fmt::Result { + pub fn write(&mut self, s: &str) -> std::io::Result<()> { write!(self.out, "{}", s) } - pub fn writeln(&mut self, s: &str) -> std::fmt::Result { + pub fn writeln(&mut self, s: &str) -> std::io::Result<()> { self.write(&format!("{}\n", s)) } - pub fn write_indented(&mut self, s: &str) -> std::fmt::Result { + pub fn write_indented(&mut self, s: &str) -> std::io::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 { + pub fn writeln_indented(&mut self, s: &str) -> std::io::Result<()> { self.write_indented(&format!("{}\n", s)) } }