use crate::ast::node::call_expression::*; use crate::ast::node::class::*; use crate::ast::node::closure::*; use crate::ast::node::compilation_unit::*; use crate::ast::node::d_string::*; use crate::ast::node::expression::*; use crate::ast::node::function::*; use crate::ast::node::generics::*; use crate::ast::node::implements_list::*; use crate::ast::node::interface::*; use crate::ast::node::level::*; use crate::ast::node::literal::*; use crate::ast::node::module::*; use crate::ast::node::named::Named; use crate::ast::node::names::*; use crate::ast::node::object_access::*; use crate::ast::node::operators::*; use crate::ast::node::statement::*; use crate::ast::node::tuple_arguments::*; use crate::ast::node::type_use::*; use crate::ast::node::use_statement::*; use crate::util::indent_writer::IndentWriter; macro_rules! to_unparse_vec { ( $nodes:expr ) => { $nodes .iter() .map(|node| *node as &dyn Unparse) .collect::>() }; } macro_rules! unparse_contained_declarations { ( $declarations:expr, $writer:expr ) => { if !$declarations.is_empty() { $writer.writeln("{")?; $writer.increase_indent(); unparse_list($writer, "\n\n", &to_unparse_vec!($declarations)); $writer.decrease_indent(); $writer.writeln_indented("}")?; } }; } pub trait Unparse { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()>; } pub trait ListUnparse: Unparse { fn prefix() -> &'static str { "" } fn separator() -> &'static str; fn suffix() -> &'static str { "" } fn inner(&self) -> Vec<&dyn Unparse>; } impl Unparse for T { 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( writer: &mut IndentWriter, sep: &str, items: &[&dyn Unparse], ) -> std::io::Result<()> { for (i, item) in items.iter().enumerate() { item.unparse(writer)?; if i < items.len() - 1 { writer.write(sep)?; } } Ok(()) } fn unparse_comma_list(writer: &mut IndentWriter, items: &[&dyn Unparse]) -> std::io::Result<()> { unparse_list(writer, ", ", items) } /* Implementations */ /* Operators */ impl Unparse for Operator { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use crate::ast::node::operators::Operator::*; match self { Binary(op) => op.unparse(writer), PrefixUnary(op) => op.unparse(writer), SuffixUnary(op) => op.unparse(writer), } } } impl Unparse for BinaryOperator { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use crate::ast::node::operators::BinaryOperator::*; match self { 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, writer: &mut IndentWriter) -> std::io::Result<()> { use crate::ast::node::operators::PrefixUnaryOperator::*; match self { Spread => writer.write("..."), BorrowMut => writer.write("&mut"), Borrow => writer.write("&"), Star => writer.write("*"), Mut => writer.write("mut"), Not => writer.write("!"), Negative => writer.write("-"), } } } impl Unparse for SuffixUnaryOperator { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use crate::ast::node::operators::SuffixUnaryOperator::*; match self { PlusPlus => writer.write("++"), MinusMinus => writer.write("--"), Call => writer.write("()"), Index => writer.write("[]"), } } } /* Names */ impl Unparse for Identifier { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { writer.write(&self.name()) } } impl ListUnparse for FullyQualifiedName { fn separator() -> &'static str { "::" } fn inner(&self) -> Vec<&dyn Unparse> { to_unparse_vec!(self.identifiers()) } } /* TypeUse and components */ impl Unparse for TypeUse { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use crate::ast::node::type_use::TypeUse::*; match self { Void => writer.write("Void"), InterfaceOrClass(interface_or_class_type_use) => { interface_or_class_type_use.unparse(writer) } 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, writer: &mut IndentWriter) -> std::io::Result<()> { for _ in 0..self.borrow_count() { writer.write("&")?; } if self.is_mutable() { writer.write("mut")?; } if self.borrow_count() > 0 || self.is_mutable() { writer.write(" ")?; } self.fqn().unparse(writer)?; self.generics().unparse(writer)?; Ok(()) } } impl Unparse for TupleTypeUse { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { for _ in 0..self.borrow_count() { writer.write("&")?; } if self.is_mutable() { writer.write("mut")?; } if self.borrow_count() > 0 || self.is_mutable() { writer.write(" ")?; } self.arguments().unparse(writer)?; Ok(()) } } impl Unparse for FunctionTypeUse { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { for _ in 0..self.borrow_count() { writer.write("&")?; } if let Some(function_type_modifier) = self.function_modifier() { function_type_modifier.unparse(writer)?; } if self.borrow_count() > 0 || self.function_modifier().is_some() { writer.write(" ")?; } writer.write("fn ")?; if !self.generics().is_empty() { self.generics().unparse(writer)?; writer.write(" ")?; } self.parameters().unparse(writer)?; writer.write(" ")?; self.return_type().unparse(writer)?; Ok(()) } } /* Generic arguments */ impl ListUnparse for GenericArguments { fn prefix() -> &'static str { "<" } fn separator() -> &'static str { ", " } fn suffix() -> &'static str { ">" } fn inner(&self) -> Vec<&dyn Unparse> { to_unparse_vec!(self.arguments()) } } /* Generic Parameters */ impl ListUnparse for GenericParameters { fn prefix() -> &'static str { "<" } fn separator() -> &'static str { ", " } fn suffix() -> &'static str { ">" } fn inner(&self) -> Vec<&dyn Unparse> { to_unparse_vec!(self.identifiers()) } } /* Tuple Arguments */ impl ListUnparse for TupleArguments { fn prefix() -> &'static str { "(" } fn separator() -> &'static str { ", " } fn suffix() -> &'static str { ")" } fn inner(&self) -> Vec<&dyn Unparse> { to_unparse_vec!(self.type_uses()) } } /* Implements List */ impl ListUnparse for ImplementsList { fn prefix() -> &'static str { ": " } fn separator() -> &'static str { " + " } fn inner(&self) -> Vec<&dyn Unparse> { to_unparse_vec!(self.type_uses()) } } /* Function Type Modifier */ impl Unparse for FunctionTypeModifier { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use crate::ast::node::function::FunctionTypeModifier::*; match self { Cons => writer.write("cons"), MutRef => writer.write("mut ref"), Mut => writer.write("mut"), Ref => writer.write("ref"), } } } /* Parameters */ impl ListUnparse for Parameters { fn prefix() -> &'static str { "(" } fn separator() -> &'static str { ", " } fn suffix() -> &'static str { ")" } fn inner(&self) -> Vec<&dyn Unparse> { to_unparse_vec!(self.parameters()) } } impl Unparse for Parameter { 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, writer: &mut IndentWriter) -> std::io::Result<()> { writer.write("-> ")?; self.declared_type().unparse(writer)?; if !self.references().is_empty() { writer.write(" ")?; self.references().unparse(writer)?; } Ok(()) } } impl ListUnparse for References { fn prefix() -> &'static str { "ref " } fn separator() -> &'static str { ", " } fn inner(&self) -> Vec<&dyn Unparse> { to_unparse_vec!(self.identifiers()) } } /* Top-level construct */ impl Unparse for CompilationUnit { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { if let Some(namespace) = self.namespace() { writer.write("ns ")?; namespace.unparse(writer)?; writer.write(";\n\n")?; } for use_statement in self.use_statements() { use_statement.unparse(writer)?; writer.write(";\n")?; } unparse_list(writer, "\n\n", &to_unparse_vec!(self.declarations()))?; Ok(()) } } impl Unparse for UseStatement { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { writer.write_indented("use ")?; for (i, identifier) in self.identifiers().iter().enumerate() { identifier.unparse(writer)?; if i != self.identifiers().len() - 2 { // 2 because of use writer.write("::")?; } } self.last().unparse(writer)?; Ok(()) } } impl Unparse for UseStatementLast { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { match self { UseStatementLast::Star => writer.write("*"), UseStatementLast::Identifiers(identifiers) => { writer.write("{")?; for (i, identifier) in identifiers.iter().enumerate() { identifier.unparse(writer)?; if i != identifiers.len() - 1 { writer.write(", ")?; } } writer.write("}")?; Ok(()) } UseStatementLast::Identifier(i) => i.unparse(writer), } } } /* Declarations allowed in each level */ impl Unparse for ModuleLevelDeclaration { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use crate::ast::node::level::ModuleLevelDeclaration::*; match self { 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(writer) } } } } impl Unparse for InterfaceLevelDeclaration { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use crate::ast::node::level::InterfaceLevelDeclaration::*; match self { 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(writer) } } } } impl Unparse for ClassLevelDeclaration { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use crate::ast::node::level::ClassLevelDeclaration::*; match self { 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(writer) } PlatformFunction(platform_function_declaration) => { platform_function_declaration.unparse(writer) } Property(property_declaration) => property_declaration.unparse(writer), Field(field_declaration) => field_declaration.unparse(writer), } } } /* Declarations */ impl Unparse for ModuleDeclaration { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { if self.is_public() { writer.write_indented("pub mod ")?; } else { writer.write_indented("mod ")?; } self.identifier().unparse(writer)?; unparse_contained_declarations!(self.declarations(), writer); Ok(()) } } impl Unparse for InterfaceDeclaration { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { if self.is_public() { writer.write_indented("pub int ")?; } else { writer.write_indented("int ")?; } self.identifier().unparse(writer)?; if !self.generics().is_empty() { self.generics().unparse(writer)?; writer.write(" ")?; } if !self.implements().is_empty() { self.implements().unparse(writer)?; writer.write(" ")?; } unparse_contained_declarations!(self.declarations(), writer); Ok(()) } } impl Unparse for ClassDeclaration { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { if self.is_public() { writer.write_indented("pub class ")?; } else { writer.write_indented("class ")?; } self.identifier().unparse(writer)?; if !self.generics().is_empty() { self.generics().unparse(writer)?; } if let Some(class_constructor) = self.class_constructor() { class_constructor.unparse(writer)?; } writer.write(" ")?; if !self.implements().is_empty() { self.implements().unparse(writer)?; writer.write(" ")?; } unparse_contained_declarations!(self.declarations(), writer); Ok(()) } } /* Function declarations and components */ impl Unparse for FunctionDefinition { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { if self.is_public() { 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 !self.generics().is_empty() { self.generics().unparse(writer)?; writer.write(" ")?; } 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, writer: &mut IndentWriter) -> std::io::Result<()> { if self.is_public() { 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 ")?; } 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, writer: &mut IndentWriter) -> std::io::Result<()> { if self.is_public() { writer.write_indented("pub platform fn ")?; } else { writer.write_indented("platform fn ")?; } if !self.generics().is_empty() { self.generics().unparse(writer)?; writer.write(" ")?; } self.identifier().unparse(writer)?; self.parameters().unparse(writer)?; writer.write(" ")?; self.return_type().unparse(writer)?; writer.write(";")?; Ok(()) } } impl Unparse for InterfaceFunctionDeclaration { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { if let Some(modifier) = self.modifier() { writer.write_indented("")?; modifier.unparse(writer)?; writer.write(" fn ")?; } else { writer.write_indented("fn ")?; } if !self.generics().is_empty() { self.generics().unparse(writer)?; writer.write(" ")?; } self.identifier().unparse(writer)?; self.parameters().unparse(writer)?; writer.write(" ")?; self.return_type().unparse(writer)?; if let Some(body) = self.body() { writer.write(" ")?; body.unparse(writer)?; } Ok(()) } } impl Unparse for InterfaceOperatorFunctionDeclaration { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { if let Some(modifier) = self.modifier() { writer.write_indented("")?; modifier.unparse(writer)?; writer.write(" op ")?; } else { writer.write_indented("op ")?; } if !self.generics().is_empty() { self.generics().unparse(writer)?; writer.write(" ")?; } self.operator().unparse(writer)?; writer.write(" ")?; self.parameters().unparse(writer)?; writer.write(" ")?; self.return_type().unparse(writer)?; if let Some(body) = self.body() { writer.write(" ")?; body.unparse(writer)?; } Ok(()) } } /* Function Modifier */ impl Unparse for FunctionModifier { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use crate::ast::node::function::FunctionModifier::*; match self { Static => writer.write("static"), Cons => writer.write("cons"), Mut => writer.write("mut"), Ref => writer.write("ref"), MutRef => writer.write("mut ref"), } } } /* Function Body */ impl Unparse for FunctionBody { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use crate::ast::node::function::FunctionBody::*; match self { Equals(expression) => { writer.write("= ")?; expression.unparse(writer)?; writer.writeln("") } Block(body) => { writer.writeln("{")?; body.unparse_inner(writer)?; writer.writeln_indented("}") } Alias(identifier) => { writer.write("alias ")?; identifier.unparse(writer)?; writer.writeln("") } } } } /* Class components */ impl ListUnparse for ClassConstructor { fn prefix() -> &'static str { "(" } fn separator() -> &'static str { ", " } fn suffix() -> &'static str { ")" } fn inner(&self) -> Vec<&dyn Unparse> { to_unparse_vec!(self.parameters()) } } impl Unparse for ClassConstructorParameter { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use crate::ast::node::class::ClassConstructorParameter::*; match self { Property(property) => property.unparse(writer), Field(field) => field.unparse(writer), } } } impl Unparse for PropertyDeclaration { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { if self.is_mutable() { writer.write("mut ")?; } self.identifier().unparse(writer)?; writer.write(": ")?; self.declared_type().unparse(writer)?; Ok(()) } } impl Unparse for FieldDeclaration { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { if self.is_mutable() { writer.write("mut ")?; } writer.write("fld ")?; self.identifier().unparse(writer)?; writer.write(": ")?; self.declared_type().unparse(writer)?; Ok(()) } } /* Statements */ impl Unparse for BlockStatement { 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(writer)?; } if let Some(expression) = self.expression() { expression.unparse(writer)?; writer.writeln("")?; } writer.decrease_indent(); Ok(()) } } impl Unparse for Statement { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use crate::ast::node::statement::Statement::*; match self { 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), }?; match self { BlockStatement(_) => {} IfStatement(_) => {} IfElseStatement(_) => {} WhileStatement(_) => {} ForStatement(_) => {} _ => { writer.writeln(";")?; } } Ok(()) } } impl Unparse for VariableDeclarationStatement { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { writer.write_indented("let ")?; if self.is_mutable() { writer.write("mut ")?; } self.identifier().unparse(writer)?; if let Some(declared_type) = self.declared_type() { writer.write(": ")?; declared_type.unparse(writer)?; } if let Some(initializer) = self.initializer() { writer.write(" = ")?; initializer.unparse(writer)?; } Ok(()) } } impl Unparse for AssignStatement { 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, writer: &mut IndentWriter) -> std::io::Result<()> { writer.write_indented("")?; self.expression().unparse(writer)?; Ok(()) } } impl Unparse for ReturnStatement { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { writer.write_indented("return")?; if let Some(expression) = self.expression() { writer.write(" ")?; expression.unparse(writer)?; } Ok(()) } } impl Unparse for IfStatement { 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, writer: &mut IndentWriter) -> std::io::Result<()> { self.if_statement().unparse(writer)?; self.else_ifs().unparse(writer)?; if let Some(else_block) = self.else_block() { else_block.unparse(writer)?; } Ok(()) } } impl Unparse for ElseIfs { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { for if_statement in self.if_statements() { writer.write_indented("else if (")?; if_statement.condition().unparse(writer)?; writer.writeln(") {")?; if_statement.then_block().unparse_inner(writer)?; writer.writeln_indented("}")?; } Ok(()) } } impl Unparse for ElseBlock { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { writer.write_indented("else ")?; self.block_statement().unparse(writer)?; Ok(()) } } impl Unparse for WhileStatement { 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, 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, writer: &mut IndentWriter) -> std::io::Result<()> { use crate::ast::node::expression::Expression::*; match self { 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, 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, 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, writer: &mut IndentWriter) -> std::io::Result<()> { use crate::ast::node::operators::PrefixUnaryOperator::*; match self.operator() { BorrowMut => writer.write("&mut "), Mut => writer.write("mut "), other => other.unparse(writer), }?; self.expression().unparse(writer)?; Ok(()) } } impl Unparse for SuffixExpression { 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, writer: &mut IndentWriter) -> std::io::Result<()> { self.callee().unparse(writer)?; if let Some(turbo_fish) = self.turbo_fish() { turbo_fish.unparse(writer)?; } self.arguments().unparse(writer)?; Ok(()) } } impl Unparse for TurboFish { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { writer.write("::")?; self.generics().unparse(writer)?; Ok(()) } } impl ListUnparse for CallArguments { fn prefix() -> &'static str { "(" } fn separator() -> &'static str { ", " } fn suffix() -> &'static str { ")" } fn inner(&self) -> Vec<&dyn Unparse> { to_unparse_vec!(self.arguments()) } } impl Unparse for CallArgument { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { self.expression().unparse(writer) } } impl Unparse for Closure { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { if let Some(modifier) = self.modifier() { match modifier { ClosureModifier::Cons => writer.write("cons "), ClosureModifier::Mut => writer.write("mut "), }?; } if self.is_move() { writer.write("move ")?; } if !self.captures().is_empty() { self.captures().unparse(writer)?; writer.write(" ")?; } writer.write("{ ")?; if !self.parameters().is_empty() { self.parameters().unparse(writer)?; writer.write(" -> ")?; } if !self.statements().is_empty() { writer.write("\n")?; writer.increase_indent(); for statement in self.statements() { statement.unparse(writer)?; } writer.decrease_indent(); } if let Some(expression) = self.expression() { if self.statements().is_empty() { expression.unparse(writer)?; writer.write(" }")?; } else { writer.increase_indent(); writer.write_indented("")?; expression.unparse(writer)?; writer.write("\n")?; writer.decrease_indent(); writer.write_indented("}")?; } } else if !self.statements().is_empty() { writer.write_indented(" }")?; } else { writer.write(" }")?; } Ok(()) } } impl Unparse for ClosureCaptures { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { writer.write("|")?; for (i, capture) in self.captures().iter().enumerate() { capture.unparse(writer)?; if i != self.captures().len() - 1 { writer.write(", ")?; } } writer.write("|")?; Ok(()) } } impl Unparse for ClosureCapture { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { for _ in 0..self.borrow_count() { writer.write("&")?; } if self.is_mutable() { writer.write("mut ")?; } self.identifier().unparse(writer)?; Ok(()) } } impl Unparse for ClosureParameters { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { for parameter in self.parameters() { parameter.unparse(writer)?; } Ok(()) } } impl Unparse for ClosureParameter { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { self.identifier().unparse(writer)?; if let Some(type_use) = self.type_use() { writer.write(": ")?; type_use.unparse(writer)?; } Ok(()) } } impl Unparse for ObjectAccess { 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, writer: &mut IndentWriter) -> std::io::Result<()> { for navigation in self.navigations() { navigation.unparse(writer)?; } Ok(()) } } impl Unparse for ObjectNavigation { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use crate::ast::node::object_access::ObjectNavigation::*; match self { Index(expression) => { writer.write("[")?; expression.unparse(writer)?; writer.write("]")?; } Identifier(identifier) => { writer.write(".")?; identifier.unparse(writer)?; } } Ok(()) } } impl Unparse for Literal { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use crate::ast::node::literal::Literal::*; match self { 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)), DString(d_string) => d_string.unparse(writer), BacktickString(d_string) => d_string.unparse(writer), Boolean(b) => writer.write(&format!("{}", b)), } } } impl Unparse for DString { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { writer.write("\"")?; for part in self.parts() { part.unparse(writer)?; } writer.write("\"")?; Ok(()) } } impl Unparse for DStringPart { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { match self { DStringPart::String(s) => writer.write(s), DStringPart::Expression(e) => { writer.write("${")?; e.unparse(writer)?; writer.write("}") } } } }