#include "statement_printers.hpp" #include "basic_printers.hpp" #include "doc_printers.hpp" #include "expression_nodes.hpp" #include "expression_printers.hpp" #include "type_printers.hpp" namespace printers { void print_import(const nodes::Import &statement, Printer &printer) { printer.print(":: "); print_identifier(*statement.get_import_name(), printer); if (*statement.get_import_name()->get() != *statement.get_module_name()->get()) { printer.print(" = "); print_identifier(*statement.get_module_name(), printer); } if (statement.symbols_size() > 0) { printer.print(" :"); for (size_t i = 0; i < statement.symbols_size(); ++i) { printer.space(); // TODO: properly print operator identifier print_identifier(*statement.get_symbol(i), printer); } } printer.print(";"); printer.new_indent_line(); printer.new_indent_line(); } // IN PROGRESS void print_constraint(const nodes::Constraint &statement, Printer &printer) { printer.print("? "); print_expression(*statement.get_expression(), printer); printer.print(";"); } void print_type_definition(const nodes::TypeDefinition &statement, Printer &printer) { print_docs(*statement.get_docs(), printer); // TODO if (statement.is_on_heap()) { printer.print("^"); } print_identifier(*statement.get_name(), printer); for (size_t i = 0; i < statement.get_arguments_size(); ++i) { printer.space(); print_identifier(*statement.get_argument(i), printer); } if (statement.get_type().has_value()) { printer.print(" = "); size_t previous_indentation_level = printer.get_current_indentation_level(); printer.set_current_indentation_level(printer.get_current_position()); print_variant_type(*statement.get_type().value(), printer); printer.set_current_indentation_level(previous_indentation_level); } // TODO: same to typeclass, make separated function if (statement.get_methods_size() > 0) { printer.print(" {"); printer.indent(); for (size_t i = 0; i < statement.get_methods_size(); ++i) { printer.new_indent_line(); print_function_definition(*statement.get_method(i), printer); printer.new_indent_line(); } printer.deindent(); printer.new_indent_line(); printer.print("} "); } else { printer.print(";"); } } // IN PROGRESS void print_function_definition(const nodes::FunctionDefinition &statement, Printer &printer) { print_docs(*statement.get_docs(), printer); // TODO for (size_t i = 0; i < statement.get_constraints_size(); ++i) { print_constraint(*statement.get_constraint(i), printer); printer.new_indent_line(); } switch (statement.get_modifier()) { case nodes::FunctionDefinition::STATIC: break; case nodes::FunctionDefinition::LET: printer.print(printer.print_words_instead_of_symbols() ? "let " : "% "); break; case nodes::FunctionDefinition::VAR: printer.print(printer.print_words_instead_of_symbols() ? "var " : "$ "); break; default: // remove ?? break; } print_identifier(*statement.get_name(), printer); // TODO: same fragments with function type, maybe better make separated // function for (size_t i = 0; i < statement.get_arguments_size(); ++i) { if (statement.get_argument_types_size() == 0) { if (statement.get_argument_annotation(i).has_value()) { print_annotation(*statement.get_argument_annotation(i).value(), printer); printer.space(); } switch (statement.get_argument_reference_type(i)) { case nodes::Modifier::OUT: printer.print(printer.print_words_instead_of_symbols() ? "out " : "-> "); break; case nodes::Modifier::IN: printer.print(printer.print_words_instead_of_symbols() ? "in " : "<- "); break; case nodes::Modifier::REF: printer.print(printer.print_words_instead_of_symbols() ? "ref " : "<> "); break; case nodes::Modifier::NONE: break; default: // TODO: handle errors ?? break; } } print_identifier(*statement.get_argument(i), printer); if (statement.get_argument_types_size() == 0) { // TODO: can't be optional and result in same time if (statement.is_argument_optional(i)) { printer.print("?"); } if (statement.is_argument_result(i)) { printer.print("!"); } } } if (statement.get_argument_types_size() > 0) { // TODO printer.print(" :"); for (size_t i = 0; i < statement.get_argument_types_size(); ++i) { printer.space(); if (statement.get_argument_annotation(i).has_value()) { print_annotation(*statement.get_argument_annotation(i).value(), printer); printer.space(); } switch (statement.get_argument_reference_type(i)) { case nodes::Modifier::OUT: printer.print(printer.print_words_instead_of_symbols() ? "out " : "-> "); break; case nodes::Modifier::IN: printer.print(printer.print_words_instead_of_symbols() ? "in " : "<- "); break; case nodes::Modifier::REF: printer.print(printer.print_words_instead_of_symbols() ? "ref " : "<> "); break; case nodes::Modifier::NONE: break; default: // TODO: handle errors ?? break; } print_type(*statement.get_argument_type(i), printer); // TODO: can't be optional and result in same time if (statement.is_argument_optional(i)) { printer.print("?"); } if (statement.is_argument_result(i)) { printer.print("!"); } } } if (statement.get_expression().has_value()) { printer.print(" = "); print_expression(*statement.get_expression().value(), printer); } else { printer.print(";"); } } // IN PROGRESS void print_typeclass_definition(const nodes::TypeclassDefinition &statement, Printer &printer) { print_docs(*statement.get_docs(), printer); // TODO print_identifier(*statement.get_name(), printer); if (statement.get_base_typeclasses_size() > 0) { printer.print(" :"); for (size_t i = 0; i < statement.get_base_typeclasses_size(); ++i) { printer.space(); print_identifier(*statement.get_base_typeclass(i), printer); } } if (statement.get_methods_size() > 0) { printer.print(" {"); printer.indent(); for (size_t i = 0; i < statement.get_methods_size(); ++i) { printer.new_indent_line(); print_function_definition(*statement.get_method(i), printer); printer.new_indent_line(); } printer.deindent(); printer.new_indent_line(); printer.print("} "); } else { printer.print(";"); } printer.new_indent_line(); printer.new_indent_line(); } // IN PROGRESS } // namespace printers // TODO: print operator in ()