diff --git a/src/ast/unparse.rs b/src/ast/unparse.rs index 38de925..e3306cd 100644 --- a/src/ast/unparse.rs +++ b/src/ast/unparse.rs @@ -1,5 +1,5 @@ -use crate::ast::FunctionModifier::{Cons, Mut, MutRef, Ref, Static}; use crate::ast::*; +use crate::util::indent_writer::IndentWriter; macro_rules! to_unparse_vec { ( $nodes:expr ) => { @@ -11,23 +11,19 @@ macro_rules! to_unparse_vec { } macro_rules! unparse_contained_declarations { - ( $declarations:expr, $buf:expr ) => { + ( $declarations:expr, $writer:expr ) => { if !$declarations.is_empty() { - write!($buf, "{{\n")?; - unparse_list($buf, "\n\n", &to_unparse_vec!($declarations)); - write!($buf, "\n}}")?; + $writer.writeln("{")?; + $writer.increase_indent(); + unparse_list($writer, "\n\n", &to_unparse_vec!($declarations)); + $writer.decrease_indent(); + $writer.writeln_indented("}")?; } }; } -macro_rules! unparse_ok { - () => { - Ok(()) - }; -} - pub trait Unparse { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result; + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()>; } pub trait ListUnparse: Unparse { @@ -45,30 +41,30 @@ pub trait ListUnparse: Unparse { } impl Unparse for T { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - write!(buf, "{}", Self::prefix())?; - unparse_list(buf, Self::separator(), &self.inner())?; - write!(buf, "{}", Self::suffix())?; - unparse_ok!() + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { + writer.write(Self::prefix())?; + unparse_list(writer, Self::separator(), &self.inner())?; + writer.write(Self::suffix())?; + Ok(()) } } fn unparse_list( - buf: &mut dyn std::fmt::Write, + writer: &mut IndentWriter, sep: &str, items: &[&dyn Unparse], -) -> std::fmt::Result { +) -> std::io::Result<()> { for (i, item) in items.iter().enumerate() { - item.unparse(buf)?; + item.unparse(writer)?; if i < items.len() - 1 { - write!(buf, "{}", sep)?; + writer.write(sep)?; } } Ok(()) } -fn unparse_comma_list(buf: &mut dyn std::fmt::Write, items: &[&dyn Unparse]) -> std::fmt::Result { - unparse_list(buf, ", ", items) +fn unparse_comma_list(writer: &mut IndentWriter, items: &[&dyn Unparse]) -> std::io::Result<()> { + unparse_list(writer, ", ", items) } /* Implementations */ @@ -76,59 +72,59 @@ fn unparse_comma_list(buf: &mut dyn std::fmt::Write, items: &[&dyn Unparse]) -> /* Operators */ impl Unparse for Operator { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use Operator::*; match self { - Binary(op) => op.unparse(buf), - PrefixUnary(op) => op.unparse(buf), - SuffixUnary(op) => op.unparse(buf), + Binary(op) => op.unparse(writer), + PrefixUnary(op) => op.unparse(writer), + SuffixUnary(op) => op.unparse(writer), } } } impl Unparse for BinaryOperator { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use BinaryOperator::*; match self { - Or => write!(buf, "||"), - And => write!(buf, "&&"), - EqualTo => write!(buf, "=="), - NotEqualTo => write!(buf, "!="), - Greater => write!(buf, ">"), - Less => write!(buf, "<"), - GreaterEqual => write!(buf, ">="), - LessEqual => write!(buf, "<="), - Add => write!(buf, "+"), - Subtract => write!(buf, "-"), - Multiply => write!(buf, "*"), - Divide => write!(buf, "/"), - Modulo => write!(buf, "%"), - LeftShift => write!(buf, "<<"), - RightShift => write!(buf, ">>"), + Or => writer.write("||"), + And => writer.write("&&"), + EqualTo => writer.write("=="), + NotEqualTo => writer.write("!="), + Greater => writer.write(">"), + Less => writer.write("<"), + GreaterEqual => writer.write(">="), + LessEqual => writer.write("<="), + Add => writer.write("+"), + Subtract => writer.write("-"), + Multiply => writer.write("*"), + Divide => writer.write("/"), + Modulo => writer.write("%"), + LeftShift => writer.write("<<"), + RightShift => writer.write(">>"), } } } impl Unparse for PrefixUnaryOperator { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use PrefixUnaryOperator::*; match self { - Spread => write!(buf, "..."), - BorrowMut => write!(buf, "&mut"), - Borrow => write!(buf, "&"), - Mut => write!(buf, "mut"), - Not => write!(buf, "!"), - Negative => write!(buf, "-"), + Spread => writer.write("..."), + BorrowMut => writer.write("&mut"), + Borrow => writer.write("&"), + Mut => writer.write("mut"), + Not => writer.write("!"), + Negative => writer.write("-"), } } } impl Unparse for SuffixUnaryOperator { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use SuffixUnaryOperator::*; match self { - PlusPlus => write!(buf, "++"), - MinusMinus => write!(buf, "--"), + PlusPlus => writer.write("++"), + MinusMinus => writer.write("--"), } } } @@ -136,8 +132,8 @@ impl Unparse for SuffixUnaryOperator { /* Names */ impl Unparse for Identifier { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - write!(buf, "{}", self.name) + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { + writer.write(&self.name) } } @@ -154,72 +150,72 @@ impl ListUnparse for FullyQualifiedName { /* TypeUse and components */ impl Unparse for TypeUse { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use TypeUse::*; match self { - Void => write!(buf, "Void"), + Void => writer.write("Void"), InterfaceOrClass(interface_or_class_type_use) => { - interface_or_class_type_use.unparse(buf) + interface_or_class_type_use.unparse(writer) } - Tuple(tuple_type_use) => tuple_type_use.unparse(buf), - Function(function_type_use) => function_type_use.unparse(buf), + Tuple(tuple_type_use) => tuple_type_use.unparse(writer), + Function(function_type_use) => function_type_use.unparse(writer), } } } impl Unparse for InterfaceOrClassTypeUse { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { for _ in 0..self.borrow_count { - write!(buf, "&")?; + writer.write("&")?; } if self.is_mutable { - write!(buf, "mut")?; + writer.write("mut")?; } if self.borrow_count > 0 || self.is_mutable { - write!(buf, " ")?; + writer.write(" ")?; } - self.fqn.unparse(buf)?; - self.generics.unparse(buf)?; - unparse_ok!() + self.fqn.unparse(writer)?; + self.generics.unparse(writer)?; + Ok(()) } } impl Unparse for TupleTypeUse { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { for _ in 0..self.borrow_count { - write!(buf, "&")?; + writer.write("&")?; } if self.is_mutable { - write!(buf, "mut")?; + writer.write("mut")?; } if self.borrow_count > 0 || self.is_mutable { - write!(buf, " ")?; + writer.write(" ")?; } - self.arguments.unparse(buf)?; - unparse_ok!() + self.arguments.unparse(writer)?; + Ok(()) } } impl Unparse for FunctionTypeUse { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { for _ in 0..self.borrow_count { - write!(buf, "&")?; + writer.write("&")?; } if let Some(function_type_modifier) = &self.function_modifier { - function_type_modifier.unparse(buf)?; + function_type_modifier.unparse(writer)?; } if self.borrow_count > 0 || self.function_modifier.is_some() { - write!(buf, " ")?; + writer.write(" ")?; } - write!(buf, "fn ")?; + writer.write("fn ")?; if !self.generics.is_empty() { - self.generics.unparse(buf)?; - write!(buf, " ")?; + self.generics.unparse(writer)?; + writer.write(" ")?; } - self.parameters.unparse(buf)?; - write!(buf, " ")?; - self.return_type.unparse(buf)?; - unparse_ok!() + self.parameters.unparse(writer)?; + writer.write(" ")?; + self.return_type.unparse(writer)?; + Ok(()) } } @@ -302,13 +298,13 @@ impl ListUnparse for ImplementsList { /* Function Type Modifier */ impl Unparse for FunctionTypeModifier { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use FunctionTypeModifier::*; match self { - Cons => write!(buf, "cons"), - MutRef => write!(buf, "mut ref"), - Mut => write!(buf, "mut"), - Ref => write!(buf, "ref"), + Cons => writer.write("cons"), + MutRef => writer.write("mut ref"), + Mut => writer.write("mut"), + Ref => writer.write("ref"), } } } @@ -334,25 +330,25 @@ impl ListUnparse for Parameters { } impl Unparse for Parameter { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - self.identifier.unparse(buf)?; - write!(buf, ": ")?; - self.type_use.unparse(buf)?; - unparse_ok!() + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { + self.identifier.unparse(writer)?; + writer.write(": ")?; + self.type_use.unparse(writer)?; + Ok(()) } } /* Return Type */ impl Unparse for ReturnType { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - write!(buf, "-> ")?; - self.declared_type.unparse(buf)?; + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { + writer.write("-> ")?; + self.declared_type.unparse(writer)?; if !self.references.is_empty() { - write!(buf, " ")?; - self.references.unparse(buf)?; + writer.write(" ")?; + self.references.unparse(writer)?; } - unparse_ok!() + Ok(()) } } @@ -373,65 +369,67 @@ impl ListUnparse for References { /* Top-level construct */ impl Unparse for CompilationUnit { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { if let Some(namespace) = &self.namespace { - write!(buf, "ns ")?; - namespace.unparse(buf)?; - write!(buf, "\n\n")?; + writer.write("ns ")?; + namespace.unparse(writer)?; + writer.write("\n\n")?; } - unparse_list(buf, "\n\n", &to_unparse_vec!(self.declarations))?; - unparse_ok!() + unparse_list(writer, "\n\n", &to_unparse_vec!(self.declarations))?; + Ok(()) } } /* Declarations allowed in each level */ impl Unparse for ModuleLevelDeclaration { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use ModuleLevelDeclaration::*; match self { - Module(module_declaration) => module_declaration.unparse(buf), - Interface(interface_declaration) => interface_declaration.unparse(buf), - Class(class_declaration) => class_declaration.unparse(buf), - Function(function_declaration) => function_declaration.unparse(buf), + Module(module_declaration) => module_declaration.unparse(writer), + Interface(interface_declaration) => interface_declaration.unparse(writer), + Class(class_declaration) => class_declaration.unparse(writer), + Function(function_declaration) => function_declaration.unparse(writer), PlatformFunction(platform_function_declaration) => { - platform_function_declaration.unparse(buf) + platform_function_declaration.unparse(writer) } } } } impl Unparse for InterfaceLevelDeclaration { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use InterfaceLevelDeclaration::*; match self { - Module(module_declaration) => module_declaration.unparse(buf), - Interface(interface_declaration) => interface_declaration.unparse(buf), - Class(class_declaration) => class_declaration.unparse(buf), - Function(interface_function_declaration) => interface_function_declaration.unparse(buf), + Module(module_declaration) => module_declaration.unparse(writer), + Interface(interface_declaration) => interface_declaration.unparse(writer), + Class(class_declaration) => class_declaration.unparse(writer), + Function(interface_function_declaration) => { + interface_function_declaration.unparse(writer) + } OperatorFunction(interface_operator_function_declaration) => { - interface_operator_function_declaration.unparse(buf) + interface_operator_function_declaration.unparse(writer) } } } } impl Unparse for ClassLevelDeclaration { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use ClassLevelDeclaration::*; match self { - Module(module_declaration) => module_declaration.unparse(buf), - Interface(interface_declaration) => interface_declaration.unparse(buf), - Class(class_declaration) => class_declaration.unparse(buf), - Function(function_declaration) => function_declaration.unparse(buf), + Module(module_declaration) => module_declaration.unparse(writer), + Interface(interface_declaration) => interface_declaration.unparse(writer), + Class(class_declaration) => class_declaration.unparse(writer), + Function(function_declaration) => function_declaration.unparse(writer), OperatorFunction(operator_function_declaration) => { - operator_function_declaration.unparse(buf) + operator_function_declaration.unparse(writer) } PlatformFunction(platform_function_declaration) => { - platform_function_declaration.unparse(buf) + platform_function_declaration.unparse(writer) } - Property(property_declaration) => property_declaration.unparse(buf), - Field(field_declaration) => field_declaration.unparse(buf), + Property(property_declaration) => property_declaration.unparse(writer), + Field(field_declaration) => field_declaration.unparse(writer), } } } @@ -439,181 +437,205 @@ impl Unparse for ClassLevelDeclaration { /* Declarations */ impl Unparse for ModuleDeclaration { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { if self.is_public { - write!(buf, "pub ")?; + writer.write_indented("pub mod ")?; + } else { + writer.write_indented("mod ")?; } - write!(buf, "mod ")?; - self.identifier.unparse(buf)?; - unparse_contained_declarations!(self.declarations, buf); - unparse_ok!() + self.identifier.unparse(writer)?; + unparse_contained_declarations!(self.declarations, writer); + Ok(()) } } impl Unparse for InterfaceDeclaration { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { if self.is_public { - write!(buf, "pub ")?; + writer.write_indented("pub int ")?; + } else { + writer.write_indented("int ")?; } - write!(buf, "int ")?; - self.identifier.unparse(buf)?; + self.identifier.unparse(writer)?; if !self.generics.is_empty() { - self.generics.unparse(buf)?; - write!(buf, " ")?; + self.generics.unparse(writer)?; + writer.write(" ")?; } if !self.implements.is_empty() { - self.implements.unparse(buf)?; - write!(buf, " ")?; + self.implements.unparse(writer)?; + writer.write(" ")?; } - unparse_contained_declarations!(self.declarations, buf); - unparse_ok!() + unparse_contained_declarations!(self.declarations, writer); + Ok(()) } } impl Unparse for ClassDeclaration { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { if self.is_public { - write!(buf, "pub ")?; + writer.write_indented("pub class ")?; + } else { + writer.write_indented("class ")?; } - write!(buf, "class ")?; - self.identifier.unparse(buf)?; + self.identifier.unparse(writer)?; if !self.generics.is_empty() { - self.generics.unparse(buf)?; + self.generics.unparse(writer)?; } if let Some(class_constructor) = &self.class_constructor { - class_constructor.unparse(buf)?; + class_constructor.unparse(writer)?; } - write!(buf, " ")?; + writer.write(" ")?; if !self.implements.is_empty() { - self.implements.unparse(buf)?; - write!(buf, " ")?; + self.implements.unparse(writer)?; + writer.write(" ")?; } - unparse_contained_declarations!(self.declarations, buf); - unparse_ok!() + unparse_contained_declarations!(self.declarations, writer); + Ok(()) } } /* Function declarations and components */ impl Unparse for FunctionDefinition { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { if self.is_public { - write!(buf, "pub ")?; + writer.write_indented("pub ")?; + if let Some(modifier) = &self.modifier { + modifier.unparse(writer)?; + writer.write(" fn ")?; + } else { + writer.write(" fn ")?; + } + } else if let Some(modifier) = &self.modifier { + writer.write_indented("")?; + modifier.unparse(writer)?; + writer.write(" fn ")?; + } else { + writer.write_indented("fn ")?; } - if let Some(modifier) = &self.modifier { - modifier.unparse(buf)?; - write!(buf, " ")?; - } - write!(buf, "fn ")?; if !self.generics.is_empty() { - self.generics.unparse(buf)?; - write!(buf, " ")?; + self.generics.unparse(writer)?; + writer.write(" ")?; } - self.identifier.unparse(buf)?; - self.parameters.unparse(buf)?; - write!(buf, " ")?; - self.return_type.unparse(buf)?; - write!(buf, " ")?; - self.body.unparse(buf)?; - unparse_ok!() + self.identifier.unparse(writer)?; + self.parameters.unparse(writer)?; + writer.write(" ")?; + self.return_type.unparse(writer)?; + writer.write(" ")?; + self.body.unparse(writer)?; + Ok(()) } } impl Unparse for OperatorFunctionDefinition { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { if self.is_public { - write!(buf, "pub ")?; + writer.write_indented("pub ")?; + if let Some(modifier) = &self.modifier { + modifier.unparse(writer)?; + writer.write(" op ")?; + } else { + writer.write("op ")?; + } + } else if let Some(modifier) = &self.modifier { + writer.write_indented("")?; + modifier.unparse(writer)?; + writer.write(" op ")?; + } else { + writer.write_indented("op ")?; } - if let Some(modifier) = &self.modifier { - modifier.unparse(buf)?; - write!(buf, " ")?; - } - self.operator.unparse(buf)?; - write!(buf, " ")?; - self.parameters.unparse(buf)?; - write!(buf, " ")?; - self.return_type.unparse(buf)?; - write!(buf, " ")?; - self.body.unparse(buf)?; - unparse_ok!() + self.operator.unparse(writer)?; + writer.write(" ")?; + self.parameters.unparse(writer)?; + writer.write(" ")?; + self.return_type.unparse(writer)?; + writer.write(" ")?; + self.body.unparse(writer)?; + Ok(()) } } impl Unparse for PlatformFunctionDeclaration { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { if self.is_public { - write!(buf, "pub ")?; + writer.write_indented("pub platform fn ")?; + } else { + writer.write_indented("platform fn ")?; } - write!(buf, "platform fn ")?; if !self.generics.is_empty() { - self.generics.unparse(buf)?; - write!(buf, " ")?; + self.generics.unparse(writer)?; + writer.write(" ")?; } - self.identifier.unparse(buf)?; - self.parameters.unparse(buf)?; - write!(buf, " ")?; - self.return_type.unparse(buf)?; - unparse_ok!() + self.identifier.unparse(writer)?; + self.parameters.unparse(writer)?; + writer.write(" ")?; + self.return_type.unparse(writer)?; + Ok(()) } } impl Unparse for InterfaceFunctionDeclaration { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { if let Some(modifier) = &self.modifier { - modifier.unparse(buf)?; - write!(buf, " ")?; + writer.write_indented("")?; + modifier.unparse(writer)?; + writer.write(" fn ")?; + } else { + writer.write_indented("fn ")?; } if !self.generics.is_empty() { - self.parameters.unparse(buf)?; - write!(buf, " ")?; + self.parameters.unparse(writer)?; + writer.write(" ")?; } - self.identifier.unparse(buf)?; - self.parameters.unparse(buf)?; - write!(buf, " ")?; - self.return_type.unparse(buf)?; + self.identifier.unparse(writer)?; + self.parameters.unparse(writer)?; + writer.write(" ")?; + self.return_type.unparse(writer)?; if let Some(body) = &self.body { - write!(buf, " ")?; - body.unparse(buf)?; + writer.write(" ")?; + body.unparse(writer)?; } - unparse_ok!() + Ok(()) } } impl Unparse for InterfaceOperatorFunctionDeclaration { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { if let Some(modifier) = &self.modifier { - modifier.unparse(buf)?; - write!(buf, " ")?; + writer.write_indented("")?; + modifier.unparse(writer)?; + writer.write(" op ")?; + } else { + writer.write_indented("op ")?; } - write!(buf, "op ")?; if !self.generics.is_empty() { - self.generics.unparse(buf)?; - write!(buf, " ")?; + self.generics.unparse(writer)?; + writer.write(" ")?; } - self.operator.unparse(buf)?; - write!(buf, " ")?; - self.parameters.unparse(buf)?; - write!(buf, " ")?; - self.return_type.unparse(buf)?; + self.operator.unparse(writer)?; + writer.write(" ")?; + self.parameters.unparse(writer)?; + writer.write(" ")?; + self.return_type.unparse(writer)?; if let Some(body) = &self.body { - write!(buf, " ")?; - body.unparse(buf)?; + writer.write(" ")?; + body.unparse(writer)?; } - unparse_ok!() + Ok(()) } } /* Function Modifier */ impl Unparse for FunctionModifier { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use FunctionModifier::*; match self { - Static => write!(buf, "static"), - Cons => write!(buf, "cons"), - Mut => write!(buf, "mut"), - Ref => write!(buf, "ref"), - MutRef => write!(buf, "mut ref"), + Static => writer.write("static"), + Cons => writer.write("cons"), + Mut => writer.write("mut"), + Ref => writer.write("ref"), + MutRef => writer.write("mut ref"), } } } @@ -621,17 +643,25 @@ impl Unparse for FunctionModifier { /* Function Body */ impl Unparse for FunctionBody { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use FunctionBody::*; match self { Equals(expression) => { - write!(buf, "= ")?; - expression.unparse(buf) + writer.write("= ")?; + expression.unparse(writer)?; + writer.writeln("") + } + Block(body) => { + writer.writeln("{")?; + writer.increase_indent(); + body.unparse_inner(writer)?; + writer.decrease_indent(); + writer.writeln_indented("}") } - Block(body) => body.unparse(buf), Alias(identifier) => { - write!(buf, "alias ")?; - identifier.unparse(buf) + writer.write("alias ")?; + identifier.unparse(writer)?; + writer.writeln("") } } } @@ -658,258 +688,283 @@ impl ListUnparse for ClassConstructor { } impl Unparse for ClassConstructorParameter { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use ClassConstructorParameter::*; match self { - Property(property) => property.unparse(buf), - Field(field) => field.unparse(buf), + Property(property) => property.unparse(writer), + Field(field) => field.unparse(writer), } } } impl Unparse for PropertyDeclaration { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { if self.is_mutable { - write!(buf, "mut ")?; + writer.write("mut ")?; } - self.identifier.unparse(buf)?; - write!(buf, ": ")?; - self.declared_type.unparse(buf)?; - unparse_ok!() + self.identifier.unparse(writer)?; + writer.write(": ")?; + self.declared_type.unparse(writer)?; + Ok(()) } } impl Unparse for FieldDeclaration { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { if self.is_mutable { - write!(buf, "mut ")?; + writer.write("mut ")?; } - write!(buf, "fld ")?; - self.identifier.unparse(buf)?; - write!(buf, ": ")?; - self.declared_type.unparse(buf)?; - unparse_ok!() + writer.write("fld ")?; + self.identifier.unparse(writer)?; + writer.write(": ")?; + self.declared_type.unparse(writer)?; + Ok(()) } } /* Statements */ impl Unparse for BlockStatement { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - write!(buf, "{{\n")?; + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { + writer.writeln_indented("{")?; + self.unparse_inner(writer)?; + writer.writeln_indented("}")?; + Ok(()) + } +} + +impl BlockStatement { + fn unparse_inner(&self, writer: &mut IndentWriter) -> std::io::Result<()> { + writer.increase_indent(); for statement in &self.statements { - statement.unparse(buf)?; + statement.unparse(writer)?; } if let Some(expression) = &self.expression { - expression.unparse(buf)?; - write!(buf, "\n")?; + expression.unparse(writer)?; + writer.writeln("")?; } - write!(buf, "}}")?; - unparse_ok!() + writer.decrease_indent(); + Ok(()) } } impl Unparse for Statement { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use Statement::*; match self { - BlockStatement(statement) => statement.unparse(buf), - CallStatement(call) => call.unparse(buf), - VariableDeclarationStatement(declaration) => declaration.unparse(buf), - AssignStatement(assign_statement) => assign_statement.unparse(buf), - ReturnStatement(return_expression) => return_expression.unparse(buf), - IfStatement(if_statement) => if_statement.unparse(buf), - IfElseStatement(if_else_statement) => if_else_statement.unparse(buf), - WhileStatement(while_statement) => while_statement.unparse(buf), - ForStatement(for_statement) => for_statement.unparse(buf), + BlockStatement(statement) => statement.unparse(writer), + CallStatement(call) => call.unparse(writer), + VariableDeclarationStatement(declaration) => declaration.unparse(writer), + AssignStatement(assign_statement) => assign_statement.unparse(writer), + ReturnStatement(return_expression) => return_expression.unparse(writer), + IfStatement(if_statement) => if_statement.unparse(writer), + IfElseStatement(if_else_statement) => if_else_statement.unparse(writer), + WhileStatement(while_statement) => while_statement.unparse(writer), + ForStatement(for_statement) => for_statement.unparse(writer), }?; - write!(buf, ";\n")?; - unparse_ok!() + match self { + BlockStatement(_) => {} + IfStatement(_) => {} + IfElseStatement(_) => {} + WhileStatement(_) => {} + ForStatement(_) => {} + _ => { + writer.writeln(";")?; + } + } + Ok(()) } } impl Unparse for VariableDeclarationStatement { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - write!(buf, "let ")?; + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { + writer.write_indented("let ")?; if self.is_mutable { - write!(buf, "mut ")?; + writer.write("mut ")?; } - self.identifier.unparse(buf)?; + self.identifier.unparse(writer)?; if let Some(declared_type) = &self.declared_type { - write!(buf, ": ")?; - declared_type.unparse(buf)?; + writer.write(": ")?; + declared_type.unparse(writer)?; } if let Some(initializer) = &self.initializer { - write!(buf, " = ")?; - initializer.unparse(buf)?; + writer.write(" = ")?; + initializer.unparse(writer)?; } - unparse_ok!() + Ok(()) } } impl Unparse for AssignStatement { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - self.lhs.unparse(buf)?; - write!(buf, " = ")?; - self.rhs.unparse(buf)?; - unparse_ok!() + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { + writer.write_indented("")?; + self.lhs.unparse(writer)?; + writer.write(" = ")?; + self.rhs.unparse(writer)?; + Ok(()) } } impl Unparse for CallStatement { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - self.0.unparse(buf)?; - unparse_ok!() + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { + writer.write_indented("")?; + self.0.unparse(writer)?; + Ok(()) } } impl Unparse for ReturnStatement { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - write!(buf, "return")?; + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { + writer.write_indented("return")?; if let Some(expression) = &self.0 { - write!(buf, " ")?; - expression.unparse(buf)?; + writer.write(" ")?; + expression.unparse(writer)?; } - unparse_ok!() + Ok(()) } } impl Unparse for IfStatement { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - write!(buf, "if ")?; - self.condition.unparse(buf)?; - write!(buf, " {{\n")?; - self.then_block.unparse(buf)?; - write!(buf, "\n}}")?; - unparse_ok!() + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { + writer.write_indented("if ")?; + self.condition.unparse(writer)?; + writer.writeln(" {")?; + self.then_block.unparse_inner(writer)?; + writer.writeln_indented("}")?; + Ok(()) } } impl Unparse for IfElseStatement { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - write!(buf, "if ")?; - self.condition.unparse(buf)?; - write!(buf, " ")?; - self.then_block.unparse(buf)?; - write!(buf, " ")?; - self.else_ifs.unparse(buf)?; - write!(buf, "else ")?; - self.else_block.unparse(buf)?; - unparse_ok!() + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { + writer.write_indented("if ")?; + self.condition.unparse(writer)?; + writer.writeln(" {")?; + self.then_block.unparse_inner(writer)?; + writer.write_indented("} ")?; + self.else_ifs.unparse(writer)?; + writer.writeln("else {")?; + self.else_block.unparse_inner(writer)?; + writer.writeln_indented("}")?; + Ok(()) } } impl Unparse for ElseIfs { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { for if_statement in &self.0 { - write!(buf, " else ")?; - if_statement.unparse(buf)?; - write!(buf, " ")?; + writer.write(" else if ")?; + if_statement.condition.unparse(writer)?; + writer.writeln(" {")?; + if_statement.then_block.unparse_inner(writer)?; + writer.write_indented("} ")?; } - unparse_ok!() + Ok(()) } } impl Unparse for WhileStatement { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - write!(buf, "while ")?; - self.condition.unparse(buf)?; - write!(buf, " ")?; - self.body.unparse(buf)?; - unparse_ok!() + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { + writer.write_indented("while ")?; + self.condition.unparse(writer)?; + writer.writeln(" {")?; + self.body.unparse_inner(writer)?; + writer.writeln_indented("}")?; + Ok(()) } } impl Unparse for ForStatement { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - write!(buf, "for ")?; - self.variable.unparse(buf)?; - write!(buf, " in ")?; - self.iterator.unparse(buf)?; - write!(buf, " ")?; - self.body.unparse(buf)?; - unparse_ok!() + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { + writer.write_indented("for ")?; + self.variable.unparse(writer)?; + writer.write(" in ")?; + self.iterator.unparse(writer)?; + writer.writeln(" {")?; + self.body.unparse_inner(writer)?; + writer.writeln_indented("}")?; + Ok(()) } } /* Expressions */ impl Unparse for Expression { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use Expression::*; match self { - Ternary(ternary) => ternary.unparse(buf), - Binary(binary) => binary.unparse(buf), - UnaryPrefix(prefix) => prefix.unparse(buf), - UnarySuffix(suffix) => suffix.unparse(buf), - Call(call) => call.unparse(buf), - ObjectAccess(object_access) => object_access.unparse(buf), - Literal(literal) => literal.unparse(buf), - FullyQualifiedName(fully_qualified_name) => fully_qualified_name.unparse(buf), - Closure(closure) => closure.unparse(buf), + Ternary(ternary) => ternary.unparse(writer), + Binary(binary) => binary.unparse(writer), + UnaryPrefix(prefix) => prefix.unparse(writer), + UnarySuffix(suffix) => suffix.unparse(writer), + Call(call) => call.unparse(writer), + ObjectAccess(object_access) => object_access.unparse(writer), + Literal(literal) => literal.unparse(writer), + FullyQualifiedName(fully_qualified_name) => fully_qualified_name.unparse(writer), + Closure(closure) => closure.unparse(writer), } } } impl Unparse for TernaryExpression { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - self.condition.unparse(buf)?; - write!(buf, " ? ")?; - self.true_expression.unparse(buf)?; - write!(buf, " : ")?; - self.false_expression.unparse(buf)?; - unparse_ok!() + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { + self.condition.unparse(writer)?; + writer.write(" ? ")?; + self.true_expression.unparse(writer)?; + writer.write(" : ")?; + self.false_expression.unparse(writer)?; + Ok(()) } } impl Unparse for BinaryExpression { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - self.left.unparse(buf)?; - write!(buf, " ")?; - self.operator.unparse(buf)?; - write!(buf, " ")?; - self.right.unparse(buf)?; - unparse_ok!() + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { + self.left.unparse(writer)?; + writer.write(" ")?; + self.operator.unparse(writer)?; + writer.write(" ")?; + self.right.unparse(writer)?; + Ok(()) } } impl Unparse for PrefixExpression { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use PrefixUnaryOperator::*; match &self.operator { - BorrowMut => write!(buf, "&mut "), - Mut => write!(buf, "mut "), - other => other.unparse(buf), + BorrowMut => writer.write("&mut "), + Mut => writer.write("mut "), + other => other.unparse(writer), }?; - self.expression.unparse(buf)?; - unparse_ok!() + self.expression.unparse(writer)?; + Ok(()) } } impl Unparse for SuffixExpression { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - self.expression.unparse(buf)?; - self.operator.unparse(buf)?; - unparse_ok!() + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { + self.expression.unparse(writer)?; + self.operator.unparse(writer)?; + Ok(()) } } impl Unparse for CallExpression { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - self.callee.unparse(buf)?; + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { + self.callee.unparse(writer)?; if let Some(turbo_fish) = &self.turbo_fish { - turbo_fish.unparse(buf)?; + turbo_fish.unparse(writer)?; } - self.arguments.unparse(buf)?; - unparse_ok!() + self.arguments.unparse(writer)?; + Ok(()) } } impl Unparse for TurboFish { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - write!(buf, "::")?; - self.0.unparse(buf)?; - unparse_ok!() + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { + writer.write("::")?; + self.0.unparse(writer)?; + Ok(()) } } @@ -932,62 +987,62 @@ impl ListUnparse for CallArguments { } impl Unparse for CallArgument { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - self.0.unparse(buf) + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { + self.0.unparse(writer) } } impl Unparse for Closure { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - write!(buf, "{{ -> TODO }}") + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { + writer.write("{{ -> TODO }}") } } impl Unparse for ObjectAccess { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - self.receiver.unparse(buf)?; - self.navigations.unparse(buf)?; - unparse_ok!() + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { + self.receiver.unparse(writer)?; + self.navigations.unparse(writer)?; + Ok(()) } } impl Unparse for ObjectNavigations { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { for navigation in &self.0 { - navigation.unparse(buf)?; + navigation.unparse(writer)?; } - unparse_ok!() + Ok(()) } } impl Unparse for ObjectNavigation { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use ObjectNavigation::*; match self { Index(expression) => { - write!(buf, "[")?; - expression.unparse(buf)?; - write!(buf, "]")?; + writer.write("[")?; + expression.unparse(writer)?; + writer.write("]")?; } Identifier(identifier) => { - write!(buf, ".")?; - identifier.unparse(buf)?; + writer.write(".")?; + identifier.unparse(writer)?; } } - unparse_ok!() + Ok(()) } } impl Unparse for Literal { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use Literal::*; match self { - Integer(i) => write!(buf, "{}", i), - Long(l) => write!(buf, "{}", l), - Double(d) => write!(buf, "{}", d), - USize(u) => write!(buf, "{}", u), - String(s) => write!(buf, "\"{}\"", s), - Boolean(b) => write!(buf, "{}", b), + Integer(i) => writer.write(&format!("{}", i)), + Long(l) => writer.write(&format!("{}", l)), + Double(d) => writer.write(&format!("{}", d)), + USize(u) => writer.write(&format!("{}", u)), + String(s) => writer.write(&format!("\"{}\"", s)), + Boolean(b) => writer.write(&format!("{}", b)), } } } diff --git a/src/bin/dmc/unparse.rs b/src/bin/dmc/unparse.rs index 8c2dcb6..a902b04 100644 --- a/src/bin/dmc/unparse.rs +++ b/src/bin/dmc/unparse.rs @@ -1,8 +1,9 @@ -use std::path::PathBuf; -use pest::Parser; use deimos::ast::build::build_ast; use deimos::ast::unparse::Unparse; use deimos::parser::{DeimosParser, Rule}; +use deimos::util::indent_writer::IndentWriter; +use pest::Parser; +use std::path::PathBuf; pub fn unparse(path: &PathBuf) { let src = std::fs::read_to_string(path).expect(&format!("Could not read {:?}", path)); @@ -11,10 +12,11 @@ pub fn unparse(path: &PathBuf) { Ok(mut pairs) => { let compilation_unit_pair = pairs.next().unwrap(); let compilation_unit = build_ast(compilation_unit_pair); - let mut out = String::new(); - compilation_unit.unparse(&mut out).expect("Failed to write to string."); - println!("{}", out); - }, + let mut writer = IndentWriter::new(0, " ", Box::new(std::io::stdout())); + compilation_unit + .unparse(&mut writer) + .expect("Failed to write to string."); + } Err(e) => { eprintln!("{}", e); }