More work on pretty print; add dmc p3 command.

This commit is contained in:
Jesse Brault 2025-05-15 11:27:05 -05:00
parent 1c2e5300ac
commit 58c66b437e
5 changed files with 128 additions and 36 deletions

View File

@ -1,7 +1,7 @@
use pest::Parser; use pest::Parser;
pub mod build; pub mod build;
mod pretty_print; pub mod pretty_print;
pub mod unparse; pub mod unparse;
// Operators // Operators

View File

@ -2,18 +2,18 @@ use crate::ast::*;
use crate::util::indent_writer::IndentWriter; use crate::util::indent_writer::IndentWriter;
use std::fmt::Debug; use std::fmt::Debug;
trait PrettyPrint { pub trait PrettyPrint {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result; fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()>;
} }
impl PrettyPrint for Identifier { 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)) writer.writeln_indented(&format!("Identifier({})", self.name))
} }
} }
impl PrettyPrint for FullyQualifiedName { 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.writeln_indented("FullyQualifiedName")?;
writer.increase_indent(); writer.increase_indent();
for identifier in &self.0 { for identifier in &self.0 {
@ -25,7 +25,7 @@ impl PrettyPrint for FullyQualifiedName {
} }
impl PrettyPrint for TypeUse { 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::*; use TypeUse::*;
match self { match self {
Void => { Void => {
@ -52,7 +52,7 @@ impl PrettyPrint for TypeUse {
} }
impl PrettyPrint for InterfaceOrClassTypeUse { 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!( writer.writeln_indented(&format!(
"InterfaceOrClassTypeUse(borrow_count = {}, is_mutable = {})", "InterfaceOrClassTypeUse(borrow_count = {}, is_mutable = {})",
self.borrow_count, self.is_mutable self.borrow_count, self.is_mutable
@ -66,11 +66,10 @@ impl PrettyPrint for InterfaceOrClassTypeUse {
} }
impl PrettyPrint for TupleTypeUse { 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!( writer.writeln_indented(&format!(
"TupleTypeUse(borrow_count = {}, is_mutable = {})", "TupleTypeUse(borrow_count = {}, is_mutable = {})",
self.borrow_count, self.borrow_count, self.is_mutable
self.is_mutable
))?; ))?;
writer.increase_indent(); writer.increase_indent();
self.arguments.pretty_print(writer)?; self.arguments.pretty_print(writer)?;
@ -80,7 +79,7 @@ impl PrettyPrint for TupleTypeUse {
} }
impl PrettyPrint for FunctionTypeUse { 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!( writer.writeln_indented(&format!(
"FunctionTypeUse(borrow_count = {})", "FunctionTypeUse(borrow_count = {})",
self.borrow_count self.borrow_count
@ -98,7 +97,7 @@ impl PrettyPrint for FunctionTypeUse {
} }
impl PrettyPrint for GenericArguments { 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.writeln_indented("GenericArguments")?;
writer.increase_indent(); writer.increase_indent();
for type_use in &self.0 { for type_use in &self.0 {
@ -110,7 +109,7 @@ impl PrettyPrint for GenericArguments {
} }
impl PrettyPrint for GenericParameters { 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.writeln_indented("GenericParameters")?;
writer.increase_indent(); writer.increase_indent();
for identifier in &self.0 { for identifier in &self.0 {
@ -122,7 +121,7 @@ impl PrettyPrint for GenericParameters {
} }
impl PrettyPrint for TupleArguments { 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.writeln_indented("TupleArguments")?;
writer.increase_indent(); writer.increase_indent();
for type_use in &self.0 { for type_use in &self.0 {
@ -134,7 +133,7 @@ impl PrettyPrint for TupleArguments {
} }
impl PrettyPrint for ImplementsList { 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.writeln_indented("ImplementsList")?;
writer.increase_indent(); writer.increase_indent();
for type_use in &self.0 { for type_use in &self.0 {
@ -146,7 +145,7 @@ impl PrettyPrint for ImplementsList {
} }
impl PrettyPrint for FunctionTypeModifier { 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::*; use FunctionTypeModifier::*;
writer.writeln_indented(&format!( writer.writeln_indented(&format!(
"FunctionTypeModifier({})", "FunctionTypeModifier({})",
@ -154,14 +153,14 @@ impl PrettyPrint for FunctionTypeModifier {
Cons => "cons", Cons => "cons",
MutRef => "mut ref", MutRef => "mut ref",
Mut => "mut", Mut => "mut",
Ref => "ref" Ref => "ref",
} }
)) ))
} }
} }
impl PrettyPrint for Parameters { 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.writeln_indented("Parameters")?;
writer.increase_indent(); writer.increase_indent();
for parameter in &self.0 { for parameter in &self.0 {
@ -173,7 +172,7 @@ impl PrettyPrint for Parameters {
} }
impl PrettyPrint for Parameter { 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.writeln_indented("Parameter")?;
writer.increase_indent(); writer.increase_indent();
self.identifier.pretty_print(writer)?; self.identifier.pretty_print(writer)?;
@ -184,7 +183,7 @@ impl PrettyPrint for Parameter {
} }
impl PrettyPrint for ReturnType { 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.writeln_indented("ReturnType")?;
writer.increase_indent(); writer.increase_indent();
self.declared_type.pretty_print(writer)?; self.declared_type.pretty_print(writer)?;
@ -195,7 +194,7 @@ impl PrettyPrint for ReturnType {
} }
impl PrettyPrint for References { 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.writeln_indented("References")?;
writer.increase_indent(); writer.increase_indent();
for identifier in &self.0 { for identifier in &self.0 {
@ -207,7 +206,7 @@ impl PrettyPrint for References {
} }
impl PrettyPrint for CompilationUnit { 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.writeln_indented("CompilationUnit")?;
writer.increase_indent(); writer.increase_indent();
if let Some(namespace) = &self.namespace { if let Some(namespace) = &self.namespace {
@ -225,7 +224,66 @@ impl PrettyPrint for CompilationUnit {
} }
impl PrettyPrint for ModuleLevelDeclaration { impl PrettyPrint for ModuleLevelDeclaration {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::fmt::Result { fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
todo!() 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!()
}
}

View File

@ -1,7 +1,9 @@
mod ast_dump; mod ast_dump;
mod p3;
use std::path::PathBuf; use std::path::PathBuf;
use crate::p3::pretty_print_parse;
use ast_dump::unparse; use ast_dump::unparse;
use clap::{Parser, Subcommand}; use clap::{Parser, Subcommand};
@ -16,7 +18,12 @@ struct Cli {
#[derive(Debug, Subcommand)] #[derive(Debug, Subcommand)]
enum Commands { enum Commands {
#[command(arg_required_else_help = true)] #[command(arg_required_else_help = true)]
Unparse { paths: Vec<PathBuf> }, Unparse {
paths: Vec<PathBuf>,
},
P3 {
paths: Vec<PathBuf>,
},
} }
fn main() { fn main() {
@ -27,5 +34,10 @@ fn main() {
unparse(&path); unparse(&path);
} }
} }
Commands::P3 { paths } => {
for path in paths {
pretty_print_parse(&path)
}
}
} }
} }

24
src/bin/dmc/p3.rs Normal file
View File

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

View File

@ -1,16 +1,14 @@
use std::fmt::Write;
pub struct IndentWriter { pub struct IndentWriter {
indent_level: usize, indent_level: usize,
indent_string: String, indent_string: String,
out: Box<dyn Write>, out: Box<dyn std::io::Write>,
} }
impl IndentWriter { impl IndentWriter {
pub fn new(start_level: usize, indent_string: String, out: Box<dyn Write>) -> IndentWriter { pub fn new(start_level: usize, indent_string: &str, out: Box<dyn std::io::Write>) -> IndentWriter {
IndentWriter { IndentWriter {
indent_level: start_level, indent_level: start_level,
indent_string, indent_string: indent_string.to_string(),
out, out,
} }
} }
@ -23,22 +21,22 @@ impl IndentWriter {
self.indent_level -= 1; 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) 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)) 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 { for _ in 0..self.indent_level {
write!(self.out, "{}", self.indent_string)?; write!(self.out, "{}", self.indent_string)?;
} }
write!(self.out, "{}", s) 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)) self.write_indented(&format!("{}\n", s))
} }
} }