#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, printers::Printer &printer) { if (expression.is_scoped()) { printer.print("("); } switch (expression.get_any()->index()) { // --- flow control case 0: // Match print_match(*expression.get().value(), printer); break; case 1: // Condition print_condition(*expression.get().value(), printer); break; case 2: // Loop print_loop(*expression.get().value(), printer); break; // --- containers case 3: // Container print_container(*expression.get().value(), printer); break; // --- modifiers case 4: // Return print_return(*expression.get().value(), printer); break; case 5: // NameDefinition print_name_definition(*expression.get().value(), printer); break; case 6: // Access print_access(*expression.get().value(), printer); break; case 7: // LoopControl print_loop_control(*expression.get().value(), printer); break; case 8: // ModifierExpression print_modifier_expression( *expression.get().value(), printer); break; // --- other case 9: // NameExpression print_name_expression(*expression.get().value(), printer); break; case 10: // Constructor print_constructor(*expression.get().value(), printer); break; case 11: // Lambda print_lambda(*expression.get().value(), printer); break; // --- literal case 12: // Literal print_literal(*expression.get().value(), printer); break; } if (expression.is_scoped()) { printer.print(")"); } } // --- flow control 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) { print_expression(*expression.get_value(), printer); printer.space(); size_t previous_indentation_level = printer.get_current_indentation_level(); printer.set_current_indentation_level(printer.current_position()); for (size_t i = 0; i < expression.cases_size(); ++i) { print_case(*expression.get_case(i), printer); if (i + 1 < expression.cases_size()) { printer.new_indent_line(); } } printer.set_current_indentation_level(previous_indentation_level); } // IN PROGRESS void print_condition(const nodes::Condition &expression, 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) { 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, 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: printer.print("["); break; case nodes::Access::TUPLE: printer.print("."); break; default: break; } print_expression(*expression.get_index(), printer); switch (expression.get_type()) { case nodes::Access::ARRAY: 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: printer.print("?"); break; case nodes::Modifier::OR_RETURN: 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()) { printer.print("."); } else { printer.space(); } } else if (expression.get_prefix().has_value()) { print_type(*expression.get_prefix().value(), printer); printer.print("."); } // 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(); } printer.print(printer.print_words_instead_of_symbols() ? "do " : "=> "); print_expression(*expression.get_expression(), printer); } // IN PROGRESS } // namespace printers