From c980eb8a728642c58d9d3a7e25bf0d5b508c69f8 Mon Sep 17 00:00:00 2001 From: Jesse Brault Date: Thu, 15 May 2025 08:52:34 -0500 Subject: [PATCH] Fix up unparse.rs. --- src/ast/build.rs | 34 +-- src/ast/mod.rs | 24 +- src/ast/unparse.rs | 594 ++++++++++++++++++++++++++------------------- 3 files changed, 360 insertions(+), 292 deletions(-) diff --git a/src/ast/build.rs b/src/ast/build.rs index 63ce52a..986f717 100644 --- a/src/ast/build.rs +++ b/src/ast/build.rs @@ -1,18 +1,4 @@ -use crate::ast::{ - AssignStatement, BinaryExpression, BinaryOperator, BlockStatement, CallArgument, CallArguments, - CallExpression, CallStatement, ClassConstructor, ClassConstructorParameter, ClassDeclaration, - ClassLevelDeclaration, Closure, CompilationUnit, Expression, FieldDeclaration, ForStatement, - FullyQualifiedName, FunctionBody, FunctionDefinition, FunctionModifier, FunctionTypeModifier, - FunctionTypeUse, GenericArguments, GenericParameter, GenericParameters, Identifier, - IfElseStatement, IfStatement, ImplementsList, InterfaceDeclaration, - InterfaceFunctionDeclaration, InterfaceLevelDeclaration, InterfaceOperatorFunctionDeclaration, - InterfaceOrClassTypeUse, Literal, ModuleDeclaration, ModuleLevelDeclaration, ObjectAccess, - ObjectNavigation, ObjectNavigations, OperatorFunctionDefinition, Parameter, Parameters, - PlatformFunctionDeclaration, PrefixExpression, PrefixUnaryOperator, PropertyDeclaration, - Reference, References, ReturnStatement, ReturnType, Statement, SuffixExpression, - SuffixUnaryOperator, TernaryExpression, TupleArguments, TupleTypeUse, TurboFish, TypeUse, - UnarySuffixExpression, VariableDeclarationStatement, WhileStatement, -}; +use crate::ast::*; use crate::parser::Rule; use pest::iterators::{Pair, Pairs}; @@ -170,11 +156,7 @@ fn build_generic_parameters(generic_parameters_pair: Pair) -> GenericParam identifier_list_pair .into_inner() .map(|identifier_pair| { - GenericParameter(expect_and_use( - identifier_pair, - Rule::Identifier, - build_identifier, - )) + expect_and_use(identifier_pair, Rule::Identifier, build_identifier) }) .collect(), ) @@ -259,11 +241,7 @@ fn build_references(ref_list_pair: Pair) -> References { References( inner .map(|identifier_pair| { - Reference(expect_and_use( - identifier_pair, - Rule::Identifier, - build_identifier, - )) + expect_and_use(identifier_pair, Rule::Identifier, build_identifier) }) .collect(), ) @@ -1127,15 +1105,15 @@ fn build_string_literal(pair: Pair) -> Literal { fn build_boolean_literal(pair: Pair) -> Literal { let inner_pair = pair.into_inner().next().unwrap(); match inner_pair.as_rule() { - Rule::True => Literal::BooleanLiteral(true), - Rule::False => Literal::BooleanLiteral(false), + Rule::True => Literal::Boolean(true), + Rule::False => Literal::Boolean(false), _ => unreachable!(), } } fn build_single_quote_string(pair: Pair) -> Literal { let inner_pair = pair.into_inner().next().unwrap(); - Literal::StringLiteral(inner_pair.to_string()) + Literal::String(inner_pair.to_string()) } fn build_double_quote_string(pair: Pair) -> Literal { diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 921f350..9c77018 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -111,7 +111,7 @@ impl Default for GenericArguments { /* Generic parameters */ #[derive(Debug)] -pub struct GenericParameters(pub Vec); +pub struct GenericParameters(pub Vec); impl GenericParameters { pub fn is_empty(&self) -> bool { @@ -125,9 +125,6 @@ impl Default for GenericParameters { } } -#[derive(Debug)] -pub struct GenericParameter(pub Identifier); - /* Tuple Arguments */ #[derive(Debug)] @@ -150,7 +147,7 @@ impl Default for ImplementsList { } } -/* Function Type Modifier and Function Modifier */ +/* Function Type Modifier */ #[derive(Debug)] pub enum FunctionTypeModifier { @@ -203,7 +200,7 @@ impl ReturnType { /* References */ #[derive(Debug)] -pub struct References(pub Vec); +pub struct References(pub Vec); impl References { pub fn is_empty(&self) -> bool { @@ -217,9 +214,6 @@ impl Default for References { } } -#[derive(Debug)] -pub struct Reference(pub Identifier); - /* Top-level construct */ #[derive(Debug)] @@ -536,10 +530,10 @@ pub enum ObjectNavigation { #[derive(Debug)] pub enum Literal { - IntegerLiteral(i32), - LongLiteral(i64), - DoubleLiteral(f64), - USizeLiteral(usize), - StringLiteral(String), - BooleanLiteral(bool), + Integer(i32), + Long(i64), + Double(f64), + USize(usize), + String(String), + Boolean(bool), } diff --git a/src/ast/unparse.rs b/src/ast/unparse.rs index a591e2b..b15532e 100644 --- a/src/ast/unparse.rs +++ b/src/ast/unparse.rs @@ -1,3 +1,4 @@ +use crate::ast::FunctionModifier::{Cons, Mut, MutRef, Ref, Static}; use crate::ast::*; macro_rules! to_unparse_vec { @@ -80,6 +81,7 @@ impl Unparse for Operator { match self { Binary(op) => op.unparse(buf), PrefixUnary(op) => op.unparse(buf), + SuffixUnary(op) => op.unparse(buf), } } } @@ -111,12 +113,22 @@ impl Unparse for PrefixUnaryOperator { fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::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, "-"), + } + } +} + +impl Unparse for SuffixUnaryOperator { + fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + use SuffixUnaryOperator::*; + match self { PlusPlus => write!(buf, "++"), MinusMinus => write!(buf, "--"), - CallOp => write!(buf, "()"), - Spread => write!(buf, "..."), } } } @@ -134,34 +146,80 @@ impl ListUnparse for FullyQualifiedName { "::" } - fn inner(&self) -> Vec<&dyn Unparse> { - to_unparse_vec!(self.identifiers) - } -} - -/* 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) } } -impl Unparse for GenericParameter { +/* TypeUse and components */ + +impl Unparse for TypeUse { fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - self.0.unparse(buf) + use TypeUse::*; + match self { + Void => write!(buf, "Void"), + InterfaceOrClass(interface_or_class_type_use) => { + interface_or_class_type_use.unparse(buf) + } + Tuple(tuple_type_use) => tuple_type_use.unparse(buf), + Function(function_type_use) => function_type_use.unparse(buf), + } + } +} + +impl Unparse for InterfaceOrClassTypeUse { + fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + for _ in 0..self.borrow_count { + write!(buf, "&")?; + } + if self.is_mutable { + write!(buf, "mut")?; + } + if self.borrow_count > 0 || self.is_mutable { + write!(buf, " ")?; + } + self.fqn.unparse(buf)?; + self.generics.unparse(buf)?; + unparse_ok!() + } +} + +impl Unparse for TupleTypeUse { + fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + for _ in 0..self.borrow_count { + write!(buf, "&")?; + } + if self.is_mutable { + write!(buf, "mut")?; + } + if self.borrow_count > 0 || self.is_mutable { + write!(buf, " ")?; + } + self.arguments.unparse(buf)?; + unparse_ok!() + } +} + +impl Unparse for FunctionTypeUse { + fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + for _ in 0..self.borrow_count { + write!(buf, "&")?; + } + if let Some(function_type_modifier) = &self.function_modifier { + function_type_modifier.unparse(buf)?; + } + if self.borrow_count > 0 || self.function_modifier.is_some() { + write!(buf, " ")?; + } + write!(buf, "fn ")?; + if !self.generics.is_empty() { + self.generics.unparse(buf)?; + write!(buf, " ")?; + } + self.parameters.unparse(buf)?; + write!(buf, " ")?; + self.return_type.unparse(buf)?; + unparse_ok!() } } @@ -185,36 +243,29 @@ impl ListUnparse for GenericArguments { } } -impl Unparse for GenericArgument { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - self.fqn.unparse(buf) +/* 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) } } -/* TypeUse and components */ +/* Tuple Arguments */ -impl Unparse for TypeUse { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - use TypeUse::*; - match self { - InterfaceOrClass(interface_or_class_type_use) => { - interface_or_class_type_use.unparse(buf) - } - Tuple(tuple_type_use) => tuple_type_use.unparse(buf), - Function(function_type_use) => function_type_use.unparse(buf), - } - } -} - -impl Unparse for InterfaceOrClassTypeUse { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - self.fqn.unparse(buf)?; - self.generics.unparse(buf)?; - unparse_ok!() - } -} - -impl ListUnparse for TupleTypeUse { +impl ListUnparse for TupleArguments { fn prefix() -> &'static str { "(" } @@ -232,28 +283,37 @@ impl ListUnparse for TupleTypeUse { } } -impl Unparse for FunctionTypeUse { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - if let Some(function_modifier) = &self.function_modifier { - function_modifier.unparse(buf)?; - } - write!(buf, " fn ")?; - if !self.generics.is_empty() { - self.generics.unparse(buf)?; - write!(buf, " ")?; - } - self.parameters.unparse(buf)?; - write!(buf, " ")?; - if !self.inputs.is_empty() { - self.inputs.unparse(buf)?; - write!(buf, " ")?; - } - self.return_type.unparse(buf)?; - unparse_ok!() +/* 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 components */ +/* Function Type Modifier */ + +impl Unparse for FunctionTypeModifier { + fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + use FunctionTypeModifier::*; + match self { + Cons => write!(buf, "cons"), + MutRef => write!(buf, "mut ref"), + Mut => write!(buf, "mut"), + Ref => write!(buf, "ref"), + } + } +} + +/* Parameters */ impl ListUnparse for Parameters { fn prefix() -> &'static str { @@ -282,27 +342,20 @@ impl Unparse for Parameter { } } +/* 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)?; if !self.references.is_empty() { + write!(buf, " ")?; self.references.unparse(buf)?; } unparse_ok!() } } -impl Unparse for VoidOrTypeUse { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - use VoidOrTypeUse::*; - match self { - Void => write!(buf, "Void"), - TypeUse(type_use) => type_use.unparse(buf), - } - } -} - impl ListUnparse for References { fn prefix() -> &'static str { "ref " @@ -317,85 +370,6 @@ impl ListUnparse for References { } } -impl Unparse for Reference { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - self.0.unparse(buf) - } -} - -/* Input parameters and arguments */ - -impl Unparse for DelegateOrIdentifier { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - use DelegateOrIdentifier::*; - match self { - Delegate => write!(buf, "delegate"), - Identifier(identifier) => identifier.unparse(buf), - } - } -} - -impl ListUnparse for InputParameters { - fn prefix() -> &'static str { - "|" - } - - fn separator() -> &'static str { - ", " - } - - fn suffix() -> &'static str { - "|" - } - - fn inner(&self) -> Vec<&dyn Unparse> { - to_unparse_vec!(self.0) - } -} - -impl ListUnparse for InputArguments { - 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 InputArgument { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - self.lhs.unparse(buf)?; - write!(buf, " = ")?; - self.rhs.unparse(buf)?; - unparse_ok!() - } -} - -/* Implements */ - -impl ListUnparse for ImplementsList { - fn prefix() -> &'static str { - ": " - } - - fn separator() -> &'static str { - " + " - } - - fn inner(&self) -> Vec<&dyn Unparse> { - to_unparse_vec!(self.0) - } -} - /* Top-level construct */ impl Unparse for CompilationUnit { @@ -416,7 +390,6 @@ impl Unparse for ModuleLevelDeclaration { fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { use ModuleLevelDeclaration::*; match self { - Type(type_declaration) => type_declaration.unparse(buf), Module(module_declaration) => module_declaration.unparse(buf), Interface(interface_declaration) => interface_declaration.unparse(buf), Class(class_declaration) => class_declaration.unparse(buf), @@ -432,7 +405,6 @@ impl Unparse for InterfaceLevelDeclaration { fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { use InterfaceLevelDeclaration::*; match self { - Type(type_declaration) => type_declaration.unparse(buf), Module(module_declaration) => module_declaration.unparse(buf), Interface(interface_declaration) => interface_declaration.unparse(buf), Class(class_declaration) => class_declaration.unparse(buf), @@ -448,7 +420,6 @@ impl Unparse for ClassLevelDeclaration { fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { use ClassLevelDeclaration::*; match self { - Type(type_declaration) => type_declaration.unparse(buf), Module(module_declaration) => module_declaration.unparse(buf), Interface(interface_declaration) => interface_declaration.unparse(buf), Class(class_declaration) => class_declaration.unparse(buf), @@ -459,6 +430,7 @@ impl Unparse for ClassLevelDeclaration { PlatformFunction(platform_function_declaration) => { platform_function_declaration.unparse(buf) } + Property(property_declaration) => property_declaration.unparse(buf), Field(field_declaration) => field_declaration.unparse(buf), } } @@ -466,24 +438,6 @@ impl Unparse for ClassLevelDeclaration { /* Declarations */ -impl Unparse for TypeDeclaration { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - if self.is_public { - write!(buf, "pub ")?; - } - write!(buf, "type ")?; - self.identifier.unparse(buf)?; - write!(buf, " ")?; - if let Some(type_parameters) = &self.parameters { - type_parameters.unparse(buf)?; - write!(buf, " ")?; - } - write!(buf, "= ")?; - self.rhs.unparse(buf)?; - Ok(()) - } -} - impl Unparse for ModuleDeclaration { fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { if self.is_public { @@ -507,10 +461,6 @@ impl Unparse for InterfaceDeclaration { self.generics.unparse(buf)?; write!(buf, " ")?; } - if !self.inputs.is_empty() { - self.inputs.unparse(buf)?; - write!(buf, " ")?; - } if !self.implements.is_empty() { self.implements.unparse(buf)?; write!(buf, " ")?; @@ -545,37 +495,7 @@ impl Unparse for ClassDeclaration { /* Function declarations and components */ -impl Unparse for FunctionModifier { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::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"), - } - } -} - -impl Unparse for FunctionBody { - fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - use FunctionBody::*; - match self { - Equals(expression) => { - write!(buf, "= ")?; - expression.unparse(buf) - } - Block(body) => body.unparse(buf), - Alias(identifier) => { - write!(buf, "alias ")?; - identifier.unparse(buf) - } - } - } -} - -impl Unparse for FunctionDeclaration { +impl Unparse for FunctionDefinition { fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { if self.is_public { write!(buf, "pub ")?; @@ -590,16 +510,14 @@ impl Unparse for FunctionDeclaration { self.identifier.unparse(buf)?; self.parameters.unparse(buf)?; write!(buf, " ")?; - if let Some(return_type) = &self.return_type { - return_type.unparse(buf)?; - write!(buf, " ")?; - } + self.return_type.unparse(buf)?; + write!(buf, " ")?; self.body.unparse(buf)?; unparse_ok!() } } -impl Unparse for OperatorFunctionDeclaration { +impl Unparse for OperatorFunctionDefinition { fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { if self.is_public { write!(buf, "pub ")?; @@ -612,10 +530,8 @@ impl Unparse for OperatorFunctionDeclaration { write!(buf, " ")?; self.parameters.unparse(buf)?; write!(buf, " ")?; - if let Some(return_type) = &self.return_type { - return_type.unparse(buf)?; - write!(buf, " ")?; - } + self.return_type.unparse(buf)?; + write!(buf, " ")?; self.body.unparse(buf)?; unparse_ok!() } @@ -653,6 +569,10 @@ impl Unparse for InterfaceFunctionDeclaration { self.parameters.unparse(buf)?; write!(buf, " ")?; self.return_type.unparse(buf)?; + if let Some(body) = &self.body { + write!(buf, " ")?; + body.unparse(buf)?; + } unparse_ok!() } } @@ -673,10 +593,48 @@ impl Unparse for InterfaceOperatorFunctionDeclaration { self.parameters.unparse(buf)?; write!(buf, " ")?; self.return_type.unparse(buf)?; + if let Some(body) = &self.body { + write!(buf, " ")?; + body.unparse(buf)?; + } unparse_ok!() } } +/* Function Modifier */ + +impl Unparse for FunctionModifier { + fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::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"), + } + } +} + +/* Function Body */ + +impl Unparse for FunctionBody { + fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + use FunctionBody::*; + match self { + Equals(expression) => { + write!(buf, "= ")?; + expression.unparse(buf) + } + Block(body) => body.unparse(buf), + Alias(identifier) => { + write!(buf, "alias ")?; + identifier.unparse(buf) + } + } + } +} + /* Class components */ impl ListUnparse for ClassConstructor { @@ -699,8 +657,18 @@ impl ListUnparse for ClassConstructor { impl Unparse for ClassConstructorParameter { fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - if self.is_field { - write!(buf, "fld ")?; + use ClassConstructorParameter::*; + match self { + Property(property) => property.unparse(buf), + Field(field) => field.unparse(buf), + } + } +} + +impl Unparse for PropertyDeclaration { + fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + if self.is_mutable { + write!(buf, "mut ")?; } self.identifier.unparse(buf)?; write!(buf, ": ")?; @@ -714,6 +682,7 @@ impl Unparse for FieldDeclaration { if self.is_mutable { write!(buf, "mut ")?; } + write!(buf, "fld ")?; self.identifier.unparse(buf)?; write!(buf, ": ")?; self.declared_type.unparse(buf)?; @@ -723,21 +692,17 @@ impl Unparse for FieldDeclaration { /* Statements */ -impl ListUnparse for BlockStatement { - fn prefix() -> &'static str { - "{\n" - } - - fn separator() -> &'static str { - "\n" - } - - fn suffix() -> &'static str { - "\n}" - } - - fn inner(&self) -> Vec<&dyn Unparse> { - to_unparse_vec!(self.0) +impl Unparse for BlockStatement { + fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + write!(buf, "{{")?; + for statement in &self.statements { + statement.unparse(buf)?; + } + if let Some(expression) = &self.expression { + expression.unparse(buf)?; + } + write!(buf, "}}")?; + unparse_ok!() } } @@ -746,7 +711,7 @@ impl Unparse for Statement { use Statement::*; match self { BlockStatement(statement) => statement.unparse(buf), - CallStatement(call_expression) => call_expression.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), @@ -755,7 +720,8 @@ impl Unparse for Statement { WhileStatement(while_statement) => while_statement.unparse(buf), ForStatement(for_statement) => for_statement.unparse(buf), }?; - write!(buf, "\n") + write!(buf, ";\n")?; + unparse_ok!() } } @@ -780,7 +746,17 @@ impl Unparse for VariableDeclarationStatement { impl Unparse for AssignStatement { fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - self.0.unparse(buf) + self.lhs.unparse(buf)?; + write!(buf, " = ")?; + self.rhs.unparse(buf)?; + unparse_ok!() + } +} + +impl Unparse for CallStatement { + fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + self.0.unparse(buf)?; + unparse_ok!() } } @@ -815,7 +791,7 @@ impl Unparse for IfElseStatement { write!(buf, " ")?; self.else_ifs.unparse(buf)?; write!(buf, "else ")?; - self.else_Block.unparse(buf)?; + self.else_block.unparse(buf)?; unparse_ok!() } } @@ -855,29 +831,94 @@ impl Unparse for ForStatement { /* Expressions */ -impl Unparse for AssignmentExpression { +impl Unparse for Expression { fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - self.identifier.unparse(buf)?; - write!(buf, " = ")?; + use Expression::*; + match self { + Ternary(ternary) => ternary.unparse(buf), + Binary(binary) => binary.unparse(buf), + UnaryPrefix(prefix) => prefix.unparse(buf), + Suffix(suffix) => suffix.unparse(buf), + Literal(literal) => literal.unparse(buf), + FullyQualifiedName(fully_qualified_name) => fully_qualified_name.unparse(buf), + Closure(closure) => closure.unparse(buf), + } + } +} + +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!() + } +} + +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!() + } +} + +impl Unparse for PrefixExpression { + fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + use PrefixUnaryOperator::*; + match &self.operator { + BorrowMut => write!(buf, "&mut "), + Mut => write!(buf, "mut "), + other => other.unparse(buf), + }?; self.expression.unparse(buf)?; unparse_ok!() } } -impl Unparse for Expression { +impl Unparse for SuffixExpression { fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - todo!() + use SuffixExpression::*; + match self { + Call(call) => call.unparse(buf), + ObjectAccess(object) => object.unparse(buf), + Unary(unary) => unary.unparse(buf), + } } } impl Unparse for CallExpression { fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { self.callee.unparse(buf)?; + if let Some(turbo_fish) = &self.turbo_fish { + turbo_fish.unparse(buf)?; + } self.arguments.unparse(buf)?; unparse_ok!() } } +impl Unparse for UnarySuffixExpression { + fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + self.expression.unparse(buf)?; + self.operator.unparse(buf)?; + unparse_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!() + } +} + impl ListUnparse for CallArguments { fn prefix() -> &'static str { "(" @@ -901,3 +942,58 @@ impl Unparse for CallArgument { self.0.unparse(buf) } } + +impl Unparse for Closure { + fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + write!(buf, "{{ -> 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!() + } +} + +impl Unparse for ObjectNavigations { + fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + for navigation in &self.0 { + navigation.unparse(buf)?; + } + unparse_ok!() + } +} + +impl Unparse for ObjectNavigation { + fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + use ObjectNavigation::*; + match self { + Index(expression) => { + write!(buf, "[")?; + expression.unparse(buf)?; + write!(buf, "]")?; + } + Identifier(identifier) => { + write!(buf, ".")?; + identifier.unparse(buf)?; + } + } + unparse_ok!() + } +} + +impl Unparse for Literal { + fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::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), + } + } +}