lang/src/expression_printers.cpp

401 lines
10 KiB
C++
Raw Normal View History

#include "expression_printers.hpp"
#include "basic_nodes.hpp"
#include "basic_printers.hpp"
#include "expression_nodes.hpp"
#include "type_printers.hpp"
namespace printers {
void print_expression(const nodes::Expression &expression,
2023-07-24 21:23:18 +03:00
printers::Printer &printer) {
if (expression.is_scoped()) {
printer.print("(");
}
switch (expression.get_any()->index()) {
// --- flow control
case 0: // Match
print_match(*expression.get<nodes::Match>().value(), printer);
break;
case 1: // Condition
print_condition(*expression.get<nodes::Condition>().value(), printer);
break;
case 2: // Loop
print_loop(*expression.get<nodes::Loop>().value(), printer);
break;
// --- containers
case 3: // Container
print_container(*expression.get<nodes::Container>().value(), printer);
break;
// --- modifiers
case 4: // Return
print_return(*expression.get<nodes::Return>().value(), printer);
break;
case 5: // NameDefinition
print_name_definition(*expression.get<nodes::NameDefinition>().value(),
printer);
break;
case 6: // Access
print_access(*expression.get<nodes::Access>().value(), printer);
break;
case 7: // LoopControl
print_loop_control(*expression.get<nodes::LoopControl>().value(), printer);
break;
case 8: // ModifierExpression
print_modifier_expression(
*expression.get<nodes::ModifierExpression>().value(), printer);
break;
// --- other
case 9: // NameExpression
print_name_expression(*expression.get<nodes::NameExpression>().value(),
printer);
break;
case 10: // Constructor
print_constructor(*expression.get<nodes::Constructor>().value(), printer);
break;
case 11: // Lambda
print_lambda(*expression.get<nodes::Lambda>().value(), printer);
break;
// --- literal
case 12: // Literal
print_literal(*expression.get<nodes::Literal>().value(), printer);
break;
}
if (expression.is_scoped()) {
printer.print(")");
}
}
// --- flow control
2023-07-24 21:23:18 +03:00
void print_case(const nodes::Match::Case &expression, Printer &printer) {
switch (expression.case_type()) {
case nodes::Match::Case::PATTERN_VALUE:
printer.print(":=");
break;
case nodes::Match::Case::VALUE_PATTERN:
printer.print("=:");
break;
}
printer.space();
print_expression(*expression.get_value(), printer);
if (expression.get_condition().has_value()) {
printer.print(printer.print_words_instead_of_symbols() ? " if " : " ?? ");
print_expression(*expression.get_condition().value(), printer);
}
if (expression.get_expression().has_value()) {
printer.print(printer.print_words_instead_of_symbols() ? " do " : " => ");
print_expression(*expression.get_expression().value(), printer);
}
} // IN PROGRESS
void print_match(const nodes::Match &expression, printers::Printer &printer) {
2023-07-24 21:23:18 +03:00
print_expression(*expression.get_value(), printer);
printer.space();
2023-07-24 23:55:11 +03:00
size_t previous_indentation_level = printer.get_current_indentation_level();
printer.set_current_indentation_level(printer.current_position());
2023-07-24 21:23:18 +03:00
for (size_t i = 0; i < expression.cases_size(); ++i) {
print_case(*expression.get_case(i), printer);
if (i + 1 < expression.cases_size()) {
2023-07-24 23:55:11 +03:00
printer.new_indent_line();
2023-07-24 21:23:18 +03:00
}
}
2023-07-24 23:55:11 +03:00
printer.set_current_indentation_level(previous_indentation_level);
} // IN PROGRESS
void print_condition(const nodes::Condition &expression,
2023-07-24 21:23:18 +03:00
printers::Printer &printer) {
for (size_t i = 0; i < expression.cases_size(); ++i) {
if (i == 0) {
printer.print(printer.print_words_instead_of_symbols() ? "if " : "?? ");
} else {
printer.print(printer.print_words_instead_of_symbols() ? "elif " : "!! ");
}
print_expression(*expression.get_case(i).first, printer);
printer.print(printer.print_words_instead_of_symbols() ? "do " : "=> ");
print_expression(*expression.get_case(i).second, printer);
}
if (expression.get_else_case().has_value()) {
printer.print(printer.print_words_instead_of_symbols() ? "else " : "!!=> ");
print_expression(*expression.get_else_case().value(), printer);
}
}
void print_loop(const nodes::Loop &expression, printers::Printer &printer) {
2023-07-24 21:23:18 +03:00
printer.print(printer.print_words_instead_of_symbols() ? "for " : "@");
switch (expression.get_type()) {
case nodes::Loop::LOOP:
printer.space();
break;
case nodes::Loop::WHILE:
printer.space();
print_expression(*expression.get_condition().value(), printer);
printer.space();
break;
case nodes::Loop::FOR:
printer.space();
print_expression(*expression.get_variable().value(), printer);
printer.print(" : ");
print_expression(*expression.get_interval().value(), printer);
printer.space();
break;
}
printer.print(printer.print_words_instead_of_symbols() ? "do " : "=> ");
print_expression(*expression.get_expression(), printer);
printer.print(";");
} // IN PROGRESS
// --- containers
void print_container(const nodes::Container &expression,
2023-07-24 21:23:18 +03:00
printers::Printer &printer) {
bool is_array = expression.get_type() == nodes::Container::ARRAY;
if (is_array) {
printer.print("[[");
} else {
printer.print("{");
printer.indent();
printer.new_indent_line();
}
for (size_t i = 0; i < expression.expressions_size(); ++i) {
print_expression(*expression.get_expression(i), printer);
if (is_array) {
printer.space();
} else {
printer.print(";");
printer.new_indent_line();
}
}
if (is_array) {
printer.print("]]");
} else {
printer.deindent();
printer.print("}");
printer.new_indent_line();
}
} // IN PROGRESS
// --- modifiers
void print_return(const nodes::Return &expression, printers::Printer &printer) {
switch (expression.get_type()) {
case nodes::Return::RETURN:
printer.print("return ");
break;
case nodes::Return::BRING:
printer.print("bring ");
break;
default:
break;
}
print_expression(*expression.get_expression(), printer);
}
void print_name_definition(const nodes::NameDefinition &expression,
printers::Printer &printer) {
if (printer.print_words_instead_of_symbols()) {
switch (expression.get_modifier()) {
case nodes::NameDefinition::LET:
printer.print("let ");
break;
case nodes::NameDefinition::VAR:
printer.print("var ");
break;
default:
break;
}
} else {
switch (expression.get_modifier()) {
case nodes::NameDefinition::LET:
printer.print("% ");
break;
case nodes::NameDefinition::VAR:
printer.print("$ ");
break;
default:
break;
}
}
print_identifier(*expression.get_name(), printer);
}
void print_access(const nodes::Access &expression, printers::Printer &printer) {
print_expression(*expression.get_value(), printer);
switch (expression.get_type()) {
case nodes::Access::ARRAY:
2023-07-24 21:23:18 +03:00
printer.print("[");
break;
case nodes::Access::TUPLE:
2023-07-24 21:23:18 +03:00
printer.print(".");
break;
default:
break;
}
print_expression(*expression.get_index(), printer);
switch (expression.get_type()) {
case nodes::Access::ARRAY:
2023-07-24 21:23:18 +03:00
printer.print("]");
break;
case nodes::Access::TUPLE:
break;
default:
break;
}
}
void print_loop_control(const nodes::LoopControl &expression,
printers::Printer &printer) {
switch (expression.get_type()) {
case nodes::LoopControl::BREAK:
printer.print("break");
break;
case nodes::LoopControl::CONTINUE:
printer.print("continue");
break;
default:
break;
}
}
void print_modifier_expression(const nodes::ModifierExpression &expression,
printers::Printer &printer) {
if (printer.print_words_instead_of_symbols()) {
switch (expression.get_modifier()) {
case nodes::Modifier::OUT:
printer.print("out ");
break;
case nodes::Modifier::IN:
printer.print("in ");
break;
case nodes::Modifier::REF:
printer.print("ref ");
break;
default:
break;
}
} else {
switch (expression.get_modifier()) {
case nodes::Modifier::OUT:
printer.print("-> ");
break;
case nodes::Modifier::IN:
printer.print("<- ");
break;
case nodes::Modifier::REF:
printer.print("<> ");
break;
default:
break;
}
}
print_expression(*expression.get_expression(), printer);
switch (expression.get_modifier()) {
case nodes::Modifier::OR_FALSE:
2023-07-24 21:23:18 +03:00
printer.print("?");
break;
case nodes::Modifier::OR_RETURN:
2023-07-24 21:23:18 +03:00
printer.print("!");
break;
default:
break;
}
}
// --- other
void print_name_expression(const nodes::NameExpression &expression,
printers::Printer &printer) {
if (expression.is_operator_call() || expression.is_point_call()) {
print_expression(*expression.get_argument_value(0), printer);
if (expression.is_point_call()) {
2023-07-24 21:23:18 +03:00
printer.print(".");
} else {
printer.space();
}
} else if (expression.get_prefix().has_value()) {
print_type(*expression.get_prefix().value(), printer);
2023-07-24 21:23:18 +03:00
printer.print(".");
}
2023-07-24 22:50:18 +03:00
// TODO: properly print operator name
print_identifier(*expression.get_name(), printer);
for (size_t i = 0; i < expression.arguments_size(); ++i) {
printer.space();
if (expression.get_argument_annotation(i).has_value()) {
print_annotation(*expression.get_argument_annotation(i).value(), printer);
printer.space();
}
print_expression(*expression.get_argument_value(i), printer);
}
} // IN PROGRESS
void print_constructor(const nodes::Constructor &expression,
printers::Printer &printer) {
print_type(*expression.get_type(), printer);
for (size_t i = 0; i < expression.arguments_size(); ++i) {
printer.space();
if (expression.get_argument_annotation(i).has_value()) {
print_annotation(*expression.get_argument_annotation(i).value(), printer);
printer.space();
}
print_expression(*expression.get_argument_value(i), printer);
}
} // IN PROGRESS
void print_lambda(const nodes::Lambda &expression, printers::Printer &printer) {
printer.print(printer.print_words_instead_of_symbols() ? "lambda " : "\\ ");
for (size_t i = 0; i < expression.arguments_size(); ++i) {
print_identifier(*expression.get_argument(i), printer);
printer.space();
}
2023-07-24 21:23:18 +03:00
printer.print(printer.print_words_instead_of_symbols() ? "do " : "=> ");
print_expression(*expression.get_expression(), printer);
} // IN PROGRESS
} // namespace printers