deimos-lang/src/ast/unparse.rs
2025-05-18 08:32:16 -05:00

1209 lines
34 KiB
Rust

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::<Vec<&dyn Unparse>>()
};
}
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<T: ListUnparse> 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")?;
}
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(())
}
}
/* 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 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),
}
}
}
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("}")
}
}
}
}