1209 lines
34 KiB
Rust
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("}")
|
|
}
|
|
}
|
|
}
|
|
}
|