use crate::ast::*; 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 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 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 PrefixUnaryOperator::*; match self { 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, writer: &mut IndentWriter) -> std::io::Result<()> { use SuffixUnaryOperator::*; match self { PlusPlus => writer.write("++"), MinusMinus => 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 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.0) } } /* 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.0) } } /* 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.0) } } /* Implements List */ impl ListUnparse for ImplementsList { fn prefix() -> &'static str { ": " } fn separator() -> &'static str { " + " } fn inner(&self) -> Vec<&dyn Unparse> { to_unparse_vec!(self.0) } } /* Function Type Modifier */ impl Unparse for FunctionTypeModifier { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use 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.0) } } 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.0) } } /* 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")?; } unparse_list(writer, "\n\n", &to_unparse_vec!(self.declarations))?; Ok(()) } } /* Declarations allowed in each level */ impl Unparse for ModuleLevelDeclaration { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use 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 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 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)?; 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.parameters.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 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 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.0) } } impl Unparse for ClassConstructorParameter { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use 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 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.0.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.0 { 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.0 { 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.0.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 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 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.0.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.0) } } impl Unparse for CallArgument { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { self.0.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.0.iter().enumerate() { capture.unparse(writer)?; if i != self.0.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.0 { 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.0 { navigation.unparse(writer)?; } Ok(()) } } impl Unparse for ObjectNavigation { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use 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 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.0 { 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("}") } } } }