lang/src/statement_printers.cpp
2023-07-24 23:55:11 +03:00

244 lines
7 KiB
C++

#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 ()