diff --git a/include/basic_printers.hpp b/include/basic_printers.hpp index 34321e4..e584761 100644 --- a/include/basic_printers.hpp +++ b/include/basic_printers.hpp @@ -42,9 +42,9 @@ public: print_spaces(indentation); } - void indent() { ++current_indentation_level_; } + void indent() { current_indentation_level_ += tab_width_; } - void deindent() { --current_indentation_level_; } + void deindent() { current_indentation_level_ -= tab_width_; } void tab() { print_spaces(tab_width_); } @@ -64,7 +64,15 @@ public: return print_words_instead_of_symbols_; } - size_t get_current_position() { return current_position_; } + size_t get_current_position() const { return current_position_; } + + size_t get_current_indentation_level() const { + return current_indentation_level_; + } + + size_t set_current_indentation_level(size_t indentation_level) { + current_indentation_level_ = indentation_level; + } private: void end_line() { diff --git a/include/doc_printers.hpp b/include/doc_printers.hpp new file mode 100644 index 0000000..3ffbe04 --- /dev/null +++ b/include/doc_printers.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include "basic_printers.hpp" +#include "doc_nodes.hpp" + +namespace printers { + +void print_docs(const nodes::SymbolDocs &docs, Printer &printer); + +} // namespace printers diff --git a/include/statement_nodes.hpp b/include/statement_nodes.hpp index b0ef122..8078f93 100644 --- a/include/statement_nodes.hpp +++ b/include/statement_nodes.hpp @@ -72,7 +72,7 @@ public: std::vector> &&annotations, std::vector &&arguments, std::vector &&reference_types, - std::vector> &&types, + std::vector &&types, std::vector &&optional_arguments, std::vector &&result_arguments, std::optional expression) @@ -101,7 +101,7 @@ public: // - ModifierType get_modifier() { return modifier_; } + ModifierType get_modifier() const { return modifier_; } // @@ -135,7 +135,7 @@ public: // - Modifier get_argument_reference_type(size_t id) { + Modifier get_argument_reference_type(size_t id) const { return reference_types_.at(id); } @@ -143,19 +143,9 @@ public: size_t get_argument_types_size() const { return types_.size(); } - std::optional get_argument_type(size_t id) { - if (types_.at(id).has_value()) { - return types_[id].value().get(); - } - return std::nullopt; - } + Type *get_argument_type(size_t id) { return types_.at(id).get(); } - std::optional get_argument_type(size_t id) const { - if (types_.at(id).has_value()) { - return types_[id].value().get(); - } - return std::nullopt; - } + const Type *get_argument_type(size_t id) const { return types_.at(id).get(); } // @@ -191,7 +181,7 @@ private: std::vector> annotations_; std::vector arguments_; std::vector reference_types_; - std::vector> types_; + std::vector types_; std::vector optional_arguments_; std::vector result_arguments_; std::optional expression_; @@ -215,7 +205,7 @@ public: // - bool is_on_heap() { return is_on_heap_; } + bool is_on_heap() const { return is_on_heap_; } // diff --git a/src/doc_printers.cpp b/src/doc_printers.cpp new file mode 100644 index 0000000..3c0bada --- /dev/null +++ b/src/doc_printers.cpp @@ -0,0 +1,14 @@ +#include "doc_printers.hpp" +#include "utils.hpp" + +namespace printers { + +// TODO + +void print_docs(const nodes::SymbolDocs &docs, Printer &printer) { + + error_handling::handle_general_error("Docs printing unimplemented yet"); + +} // IN PROGRESS + +} // namespace printers diff --git a/src/expression_printers.cpp b/src/expression_printers.cpp index 10dd1d3..84b40e2 100644 --- a/src/expression_printers.cpp +++ b/src/expression_printers.cpp @@ -85,7 +85,6 @@ void print_case(const nodes::Match::Case &expression, Printer &printer) { 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); } @@ -101,16 +100,20 @@ void print_match(const nodes::Match &expression, printers::Printer &printer) { printer.space(); - size_t indentation = printer.get_current_position(); + 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_line(indentation); + printer.new_indent_line(); } } + printer.set_current_indentation_level(previous_indentation_level); + } // IN PROGRESS void print_condition(const nodes::Condition &expression, diff --git a/src/statement_builders.cpp b/src/statement_builders.cpp index 98e2850..d650d2f 100644 --- a/src/statement_builders.cpp +++ b/src/statement_builders.cpp @@ -236,7 +236,7 @@ build_function_definition(parser::ParseTree::Node parser_node, std::vector> type_annotations; std::vector type_reference_types; - std::vector> types; + std::vector types; std::optional expression_node; @@ -277,7 +277,7 @@ build_function_definition(parser::ParseTree::Node parser_node, current_node.next_sibling().is_named() && current_node.next_sibling().get_value() == "!"); - if (optional_arguments.back() | result_arguments.back()) { + if (optional_arguments.back() || result_arguments.back()) { at_least_one_argument_modifier_found = true; } diff --git a/src/statement_printers.cpp b/src/statement_printers.cpp index 890e97a..a51e2a1 100644 --- a/src/statement_printers.cpp +++ b/src/statement_printers.cpp @@ -1,7 +1,10 @@ #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 { @@ -39,11 +42,166 @@ void print_constraint(const nodes::Constraint &statement, Printer &printer) { 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,