#include "statement_printers.hpp" #include "basic_nodes.hpp" #include "basic_printers.hpp" #include "doc_printers.hpp" #include "expression_nodes.hpp" #include "expression_printers.hpp" #include "statement_nodes.hpp" #include "type_printers.hpp" namespace printers { void print_source_file(const std::vector &statements, Printer &printer) { for (auto &statement : statements) { print_statement(statement, printer); } } void print_statement(const nodes::Statement &statement, Printer &printer) { switch (statement.get_any()->index()) { case 0: // Import print_import(*statement.get().value(), printer); printer.new_indent_line(); break; case 1: // TypeDefinition print_type_definition(*statement.get().value(), printer); printer.new_indent_line(); break; case 2: // FunctionDefinition print_function_definition( *statement.get().value(), printer); printer.new_indent_line(); break; case 3: // Extra print_extra(*statement.get().value(), printer); printer.new_indent_line(); break; case 4: // EmptyLines print_empty_lines(*statement.get().value(), printer); break; } } 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(); bool identifier_is_operator = (statement.get_symbol(i)->get_type() == nodes::Identifier::OPERATOR); if (identifier_is_operator) { printer.print("( "); } print_identifier(*statement.get_symbol(i), printer); if (identifier_is_operator) { printer.print(" )"); } } } printer.print(";"); } // 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); if (statement.is_on_heap()) { printer.print("<> "); } print_identifier(*statement.get_name(), printer); for (size_t i = 0; i < statement.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_indentation_level(); printer.set_indentation_level(printer.get_current_position() - 2); print_type(*statement.get_type().value().get(), printer); printer.set_indentation_level(previous_indentation_level); } printer.print(";"); } // IN PROGRESS // TODO: do not print prefix type for names void print_function_definition(const nodes::FunctionDefinition &statement, Printer &printer) { print_docs(*statement.get_docs(), printer); for (size_t i = 0; i < statement.constraints_size(); ++i) { print_constraint(*statement.get_constraint(i), printer); printer.new_indent_line(); } if (statement.is_method()) { printer.print("."); } bool identifier_is_operator = (statement.get_name()->get_type() == nodes::Identifier::OPERATOR); if (identifier_is_operator) { printer.print("( "); } print_identifier(*statement.get_name(), printer); if (identifier_is_operator) { printer.print(" )"); } print_modifier(statement.get_return_modifier(), printer); // ! or ? for (size_t i = 0; i < statement.arguments_size(); ++i) { if (!statement.get_argument(i)->get_name().has_value()) { break; } printer.space(); // all arguments are typed or are untyped in the same time if (!statement.get_argument(i)->get_type().has_value()) { // print annotation if (!statement.are_annotations_same_to_names() && statement.get_argument(i)->get_annotation().has_value()) { print_annotation(*statement.get_argument(i)->get_annotation().value(), printer); printer.space(); } print_modifier(statement.get_argument(i)->get_before_modifier(), printer, true); } print_identifier(*statement.get_argument(i)->get_name().value(), printer); // all arguments are typed or are untyped in the same time if (!statement.get_argument(i)->get_type().has_value()) { print_modifier(statement.get_argument(i)->get_after_modifier(), printer); } } // all arguments are typed or are untyped in the same time if (statement.arguments_size() > 0 && statement.get_argument(0)->get_type().has_value()) { printer.print(" :"); for (size_t i = 0; i < statement.arguments_size(); ++i) { printer.space(); if (statement.get_argument(i)->get_annotation().has_value()) { print_annotation(*statement.get_argument(i)->get_annotation().value(), printer); printer.space(); } print_modifier(statement.get_argument(i)->get_before_modifier(), printer, true); print_type(*statement.get_argument(i)->get_type().value(), printer); } } if (statement.get_expression().has_value()) { bool expression_is_container = statement.get_expression().value()->get().has_value(); printer.print(expression_is_container ? " " : " = "); size_t previous_indentation_level = printer.get_indentation_level(); if (!expression_is_container) { printer.set_indentation_level(printer.current_position()); } print_expression(*statement.get_expression().value(), printer); if (!expression_is_container) { printer.set_indentation_level(previous_indentation_level); printer.print(";"); } } else { printer.print(";"); } } // IN PROGRESS } // namespace printers