From b4ce56b5f70cf2a8b5f9dd3db827208628d671d7 Mon Sep 17 00:00:00 2001 From: ProgramSnail Date: Wed, 26 Jul 2023 13:43:14 +0300 Subject: [PATCH] function definition class structure changed, corresponding builders and printers fixes, fixes --- include/basic_printers.hpp | 2 + include/expression_nodes.hpp | 4 +- include/statement_nodes.hpp | 203 +++++++++++++++++++++++------------ include/type_nodes.hpp | 29 +++-- src/basic_builders.cpp | 7 +- src/basic_printers.cpp | 24 +++++ src/expression_nodes.cpp | 8 +- src/expression_printers.cpp | 46 ++------ src/statement_builders.cpp | 138 ++++++++++++------------ src/statement_printers.cpp | 109 ++++++++----------- src/type_builders.cpp | 20 ++-- src/type_nodes.cpp | 8 +- src/type_printers.cpp | 9 +- 13 files changed, 323 insertions(+), 284 deletions(-) diff --git a/include/basic_printers.hpp b/include/basic_printers.hpp index 6059c7d..37458a2 100644 --- a/include/basic_printers.hpp +++ b/include/basic_printers.hpp @@ -118,6 +118,8 @@ private: size_t indentation_level_ = 0; }; +void print_modifier(const nodes::Modifier &modifier, Printer &printer); + void print_literal(const nodes::Literal &literal, Printer &printer); void print_identifier(const nodes::Identifier &identifier, Printer &printer); diff --git a/include/expression_nodes.hpp b/include/expression_nodes.hpp index 28098e5..72283ba 100644 --- a/include/expression_nodes.hpp +++ b/include/expression_nodes.hpp @@ -24,10 +24,10 @@ public: private: ExpressionProxy(ExpressionStorage &expression_storage, size_t id) - : expression_storage_(expression_storage), id_(id) {} + : expression_storage_(&expression_storage), id_(id) {} private: - ExpressionStorage &expression_storage_; + ExpressionStorage *expression_storage_; size_t id_; }; diff --git a/include/statement_nodes.hpp b/include/statement_nodes.hpp index 82006cb..73a3999 100644 --- a/include/statement_nodes.hpp +++ b/include/statement_nodes.hpp @@ -66,24 +66,138 @@ public: VAR, }; + class Argument { + public: + Argument(const std::optional &annotation, Identifier &&name, + Modifier before_modifier = Modifier::NONE, + Modifier after_modifier = Modifier::NONE) + : annotation_(annotation), name_(std::move(name)), + before_modifier_(before_modifier), after_modifier_(after_modifier) {} + + Argument(const std::optional &annotation, + const Identifier &name, Modifier before_modifier = Modifier::NONE, + Modifier after_modifier = Modifier::NONE) + : annotation_(annotation), name_(name), + before_modifier_(before_modifier), after_modifier_(after_modifier) {} + + Argument(const std::optional &annotation, TypeProxy type, + Modifier before_modifier = Modifier::NONE) + : annotation_(annotation), type_(type), + before_modifier_(before_modifier), + after_modifier_(type.get()->get_modifier()) {} + + // + + bool add_type(const std::optional &annotation, TypeProxy type, + nodes::Modifier before_modifier = Modifier::NONE) { + if (annotation_.has_value() && + (!annotation.has_value() || + annotation_.value() != annotation.value())) { + return false; + } + + if (before_modifier_ != Modifier::NONE && + before_modifier_ != before_modifier) { + return false; + } + + if (after_modifier_ != Modifier::NONE && + after_modifier_ != type.get()->get_modifier()) { + return false; + } + + annotation_ = annotation; + type_ = type; + before_modifier_ = before_modifier; + after_modifier_ = type.get()->get_modifier(); + + return true; + } + + bool add_annotation(const std::string &annotation) { + if (annotation_.has_value()) { + return false; + } + + annotation_ = annotation; + + return true; + } + + // + + std::optional get_annotation() { + if (annotation_.has_value()) { + return &annotation_.value(); + } + return std::nullopt; + } + + std::optional get_annotation() const { + if (annotation_.has_value()) { + return &annotation_.value(); + } + return std::nullopt; + } + + // + + std::optional get_name() { + if (name_.has_value()) { + return &name_.value(); + } + return std::nullopt; + } + + std::optional get_name() const { + if (name_.has_value()) { + return &name_.value(); + } + return std::nullopt; + } + + // + + std::optional get_type() { + if (type_.has_value()) { + return type_.value().get(); + } + return std::nullopt; + } + + std::optional get_type() const { + if (type_.has_value()) { + return type_.value().get(); + } + return std::nullopt; + } + + // + + Modifier get_before_modifier() const { return before_modifier_; } + + Modifier get_after_modifier() const { return after_modifier_; } + + private: + std::optional annotation_; + std::optional name_; // no name for output arguments + std::optional type_; // no type if it is deduced + Modifier before_modifier_ = + Modifier::NONE; // in, out, ref, none // sync with type + Modifier after_modifier_ = + Modifier::NONE; // optional, result, none // sync with type + }; + FunctionDefinition(Node node, SymbolDocs &&docs, std::vector &&constraints, ModifierType modifier, const Identifier &name, - std::vector> &&annotations, - std::vector &&arguments, - std::vector &&reference_types, - std::vector &&types, - std::vector &&optional_arguments, - std::vector &&result_arguments, - bool is_annotations_same_to_names, + std::vector &&arguments, + bool are_annotations_same_to_names, std::optional expression) : Node(node), docs_(std::move(docs)), constraints_(std::move(constraints)), modifier_(modifier), name_(name), - annotations_(std::move(annotations)), arguments_(std::move(arguments)), - reference_types_(std::move(reference_types)), types_(std::move(types)), - optional_arguments_(optional_arguments), - result_arguments_(result_arguments), - is_annotations_same_to_names_(is_annotations_same_to_names), + arguments_(std::move(arguments)), + are_annotations_same_to_names_(are_annotations_same_to_names), expression_(expression) {} // @@ -114,57 +228,11 @@ public: // - std::optional get_argument_annotation(size_t id) { - if (annotations_.at(id).has_value()) { - return &annotations_[id].value(); - } - return std::nullopt; - } - - std::optional get_argument_annotation(size_t id) const { - if (annotations_.at(id).has_value()) { - return &annotations_[id].value(); - } - return std::nullopt; - } - - // - size_t get_arguments_size() const { return arguments_.size(); } - Identifier *get_argument(size_t id) { return &arguments_.at(id); } + Argument *get_argument(size_t id) { return &arguments_.at(id); } - const Identifier *get_argument(size_t id) const { return &arguments_.at(id); } - - // - - Modifier get_argument_reference_type(size_t id) const { - return reference_types_.at(id); - } - - // - - size_t get_argument_types_size() const { return types_.size(); } - - Type *get_argument_type(size_t id) { return types_.at(id).get(); } - - const Type *get_argument_type(size_t id) const { return types_.at(id).get(); } - - // - - bool is_argument_optional(size_t id) const { - return optional_arguments_.at(id); - } - - // - - bool is_argument_result(size_t id) const { return result_arguments_.at(id); } - - // - - bool is_annotations_same_to_names() const { - return is_annotations_same_to_names_; - } + const Argument *get_argument(size_t id) const { return &arguments_.at(id); } // @@ -182,18 +250,19 @@ public: return std::nullopt; } + // + + bool are_annotations_same_to_names() const { + return are_annotations_same_to_names_; + } + private: SymbolDocs docs_; std::vector constraints_; ModifierType modifier_; Identifier name_; - std::vector> annotations_; - std::vector arguments_; - std::vector reference_types_; - std::vector types_; - std::vector optional_arguments_; - std::vector result_arguments_; - bool is_annotations_same_to_names_; + std::vector arguments_; + bool are_annotations_same_to_names_; // needed for easier prinitng process std::optional expression_; }; // refactor ?? diff --git a/include/type_nodes.hpp b/include/type_nodes.hpp index a45d1f0..97fc055 100644 --- a/include/type_nodes.hpp +++ b/include/type_nodes.hpp @@ -24,10 +24,10 @@ public: private: TypeProxy(TypeStorage &type_storage, size_t id) - : type_storage_(type_storage), id_(id) {} + : type_storage_(&type_storage), id_(id) {} private: - TypeStorage &type_storage_; + TypeStorage *type_storage_; size_t id_; }; @@ -35,28 +35,26 @@ private: class Type : public Node { public: Type(Node node, Identifier &&identifier, bool is_on_heap = false, - bool is_optional = false, bool is_result = false) + Modifier modifier = Modifier::NONE) : Node(node), name_(std::move(identifier)), is_on_heap_(is_on_heap), - is_optional_(is_optional), is_result_(is_result) {} + modifier_(modifier) {} Type(Node node, const Identifier &identifier, bool is_on_heap = false, - bool is_optional = false, bool is_result = false) + Modifier modifier = Modifier::NONE) : Node(node), name_(identifier), is_on_heap_(is_on_heap), - is_optional_(is_optional), is_result_(is_result) {} + modifier_(modifier) {} Type(Node node, Identifier &&identifier, std::vector &¶meters, - bool is_on_heap = false, bool is_optional = false, - bool is_result = false) + bool is_on_heap = false, Modifier modifier = Modifier::NONE) : Node(node), name_(std::move(identifier)), parameters_(std::move(parameters)), is_on_heap_(is_on_heap), - is_optional_(is_optional), is_result_(is_result) {} + modifier_(modifier) {} Type(Node node, const Identifier &identifier, std::vector &¶meters, bool is_on_heap = false, - bool is_optional = false, bool is_result = false) + Modifier modifier = Modifier::NONE) : Node(node), name_(identifier), parameters_(std::move(parameters)), - is_on_heap_(is_on_heap), is_optional_(is_optional), - is_result_(is_result) {} + is_on_heap_(is_on_heap), modifier_(modifier) {} Identifier *get_name() { return &name_; } @@ -72,17 +70,14 @@ public: bool is_on_heap() const { return is_on_heap_; } - bool is_optional() const { return is_optional_; } - - bool is_result() const { return is_result_; } + Modifier get_modifier() const { return modifier_; } private: Identifier name_; std::vector parameters_; // or use allocator ?? bool is_on_heap_ = false; - bool is_optional_ = false; - bool is_result_ = false; + Modifier modifier_ = Modifier::NONE; // optional, result or none }; class TypeStorage { diff --git a/src/basic_builders.cpp b/src/basic_builders.cpp index 387e223..8105320 100644 --- a/src/basic_builders.cpp +++ b/src/basic_builders.cpp @@ -77,8 +77,7 @@ nodes::Literal build_string_literal(parser::ParseTree::Node parser_node) { std::string literal = parser_node.get_value(); // remove " from both sides ("string") - literal.pop_back(); - literal = literal.substr(1, literal.size() - 1); + literal = literal.substr(1, literal.size() - 2); // replace escape sequences with escape characters bool is_escape_symbol = false; @@ -111,9 +110,7 @@ nodes::Literal build_char_literal(parser::ParseTree::Node parser_node) { std::string literal = parser_node.get_value(); // remove '' from both sides (''x'') - literal.pop_back(); - literal.pop_back(); - literal = literal.substr(1, literal.size() - 2); + literal = literal.substr(2, literal.size() - 4); char ch = '\0'; diff --git a/src/basic_printers.cpp b/src/basic_printers.cpp index eedde37..bf2647c 100644 --- a/src/basic_printers.cpp +++ b/src/basic_printers.cpp @@ -6,6 +6,30 @@ namespace printers { +void print_modifier(const nodes::Modifier &modifier, Printer &printer) { + switch (modifier) { + 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::OR_FALSE: + printer.print("?"); + break; + case nodes::Modifier::OR_RETURN: + printer.print("!"); + break; + case nodes::Modifier::NONE: + break; + default: + break; + } +} + void print_literal(const nodes::Literal &literal, Printer &printer) { switch (literal.get_any()->index()) { case 0: // double diff --git a/src/expression_nodes.cpp b/src/expression_nodes.cpp index 730962b..2b52c20 100644 --- a/src/expression_nodes.cpp +++ b/src/expression_nodes.cpp @@ -2,12 +2,12 @@ namespace nodes { -Expression* ExpressionProxy::get() { - return expression_storage_.get_expression(id_); +Expression *ExpressionProxy::get() { + return expression_storage_->get_expression(id_); } -const Expression* ExpressionProxy::get() const { - return expression_storage_.get_expression(id_); +const Expression *ExpressionProxy::get() const { + return expression_storage_->get_expression(id_); } }; // namespace nodes diff --git a/src/expression_printers.cpp b/src/expression_printers.cpp index 36d102e..327ad02 100644 --- a/src/expression_printers.cpp +++ b/src/expression_printers.cpp @@ -2,7 +2,6 @@ #include "basic_nodes.hpp" #include "basic_printers.hpp" #include "expression_nodes.hpp" -#include "tokens.hpp" #include "type_printers.hpp" #include "utils.hpp" @@ -331,48 +330,17 @@ void print_loop_control(const nodes::LoopControl &expression, 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; - } + if (expression.get_modifier() == nodes::Modifier::OUT || + expression.get_modifier() == nodes::Modifier::IN || + expression.get_modifier() == nodes::Modifier::REF) { + print_modifier(expression.get_modifier(), printer); } 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; + if (expression.get_modifier() == nodes::Modifier::OR_FALSE || + expression.get_modifier() == nodes::Modifier::OR_RETURN) { + print_modifier(expression.get_modifier(), printer); } } diff --git a/src/statement_builders.cpp b/src/statement_builders.cpp index 1a843a9..562e543 100644 --- a/src/statement_builders.cpp +++ b/src/statement_builders.cpp @@ -254,29 +254,32 @@ build_function_definition(parser::ParseTree::Node parser_node, } } - std::vector> argument_annotations; - std::vector argument_reference_types; - std::vector arguments; - std::vector optional_arguments; - std::vector result_arguments; - - std::vector> type_annotations; - std::vector type_reference_types; - std::vector types; + std::vector arguments; + std::vector argument_types; std::optional expression_node; current_node = name_node.next_named_sibling(); bool at_least_one_argument_annotation_found = false; - bool at_least_one_argument_modifier_found = false; + + size_t current_type_id = 0; std::optional last_annotation; - nodes::Modifier last_reference_type = nodes::Modifier::NONE; + nodes::Modifier last_before_modifier = nodes::Modifier::NONE; + nodes::Modifier last_after_modifier = nodes::Modifier::NONE; while (!current_node.is_null()) { + // update last before modifier auto maybe_reference_node = current_node.previous_sibling(); if (!maybe_reference_node.is_null() && !maybe_reference_node.is_named()) { - last_reference_type = build_modifier(maybe_reference_node); + last_before_modifier = build_modifier(maybe_reference_node); + + // only out, in, ref allowed + if (last_before_modifier != nodes::Modifier::OUT && + last_before_modifier != nodes::Modifier::IN && + last_before_modifier != nodes::Modifier::REF) { + last_before_modifier = nodes::Modifier::NONE; + } } switch (tokens::string_to_type(current_node.get_type())) { @@ -284,38 +287,50 @@ build_function_definition(parser::ParseTree::Node parser_node, last_annotation = build_annotation(current_node); break; case tokens::Type::ARGUMENT_NAME_IDENTIFIER: + // update last after modifier + maybe_reference_node = current_node.next_sibling(); + if (!maybe_reference_node.is_null() && !maybe_reference_node.is_named()) { + last_after_modifier = build_modifier(maybe_reference_node); + + // only optional, result allowed + if (last_after_modifier != nodes::Modifier::OR_FALSE && + last_after_modifier != nodes::Modifier::OR_RETURN) { + last_after_modifier = nodes::Modifier::NONE; + } + } + + // update conditions if (last_annotation.has_value()) { at_least_one_argument_annotation_found = true; - at_least_one_argument_modifier_found = true; - } - if (last_reference_type != nodes::Modifier::NONE) { - at_least_one_argument_modifier_found = true; } - argument_annotations.push_back(last_annotation); - argument_reference_types.push_back(last_reference_type); - arguments.push_back(build_identifier(current_node)); - optional_arguments.push_back(!current_node.next_sibling().is_null() && - !current_node.next_sibling().is_named() && - current_node.next_sibling().get_value() == - "?"); - result_arguments.push_back(!current_node.next_sibling().is_null() && - !current_node.next_sibling().is_named() && - current_node.next_sibling().get_value() == - "!"); - if (optional_arguments.back() || result_arguments.back()) { - at_least_one_argument_modifier_found = true; - } + arguments.push_back(nodes::FunctionDefinition::Argument( + last_annotation, build_identifier(current_node), last_before_modifier, + last_after_modifier)); - last_reference_type = nodes::Modifier::NONE; last_annotation = std::nullopt; break; case tokens::Type::TYPE: - type_annotations.push_back(last_annotation); - type_reference_types.push_back(last_reference_type); - types.push_back(build_type(current_node, type_storage)); - last_reference_type = nodes::Modifier::NONE; + if (current_type_id >= arguments.size()) { + arguments.push_back(nodes::FunctionDefinition::Argument( + last_annotation, build_type(current_node, type_storage), + last_before_modifier)); + } else { + if (!arguments[current_type_id].add_type( + last_annotation, build_type(current_node, type_storage), + last_before_modifier)) { + error_handling::handle_parsing_error( + "It is impossible to use argument modifiers (annotations, " + "references, " + "optional markers, result markers) when types explicitely " + "defined. Use type annotations instead.", + current_node); + } + } + last_annotation = std::nullopt; + + ++current_type_id; break; default: if (expression_node.has_value()) { @@ -329,38 +344,32 @@ build_function_definition(parser::ParseTree::Node parser_node, current_node = current_node.next_named_sibling(); } - std::vector> *annotations = nullptr; - std::vector *reference_types = nullptr; + if (current_type_id > 0 && current_type_id < arguments.size()) { + error_handling::handle_parsing_error( + "Less types then arguments in function definition", parser_node); + } - bool is_annotations_same_to_names = - (!at_least_one_argument_annotation_found && types.empty()); + // automatic annotations + bool are_annotations_same_to_names = + (!at_least_one_argument_annotation_found && current_type_id == 0); - if (is_annotations_same_to_names) { - for (size_t i = 0; i < argument_annotations.size(); ++i) { - std::string argument_annotation = *arguments[i].get(); - argument_annotations[i] = - argument_annotation.substr(1, argument_annotation.size() - 1); + if (are_annotations_same_to_names) { + for (size_t i = 0; i < arguments.size(); ++i) { + std::string new_annotation = *arguments[i].get_name().value()->get(); + if (!arguments[i].add_annotation( + new_annotation.substr(1, new_annotation.size() - 1))) { + error_handling::handle_parsing_error( + "no annotations provided ( => all annotations same to names), but " + "can't add name annotation", + current_node); + } } } - if (types.empty()) { - annotations = &argument_annotations; - reference_types = &argument_reference_types; - } else if (at_least_one_argument_modifier_found) { - error_handling::handle_parsing_error( - "It is impossible to use argument modifiers (annotations, references, " - "optional markers, result markers) when types explicitely " - "defined. Use type annotations instead.", - parser_node); - } else { - annotations = &type_annotations; - reference_types = &type_reference_types; - } - std::unordered_set annotations_set; - for (auto &annotation : *annotations) { - if (annotation.has_value()) { - if (!annotations_set.insert(annotation.value()).second) { + for (auto &argument : arguments) { + if (argument.get_annotation().has_value()) { + if (!annotations_set.insert(*argument.get_annotation().value()).second) { error_handling::handle_parsing_error( "Two or more same annotations found in function definition", parser_node); @@ -372,15 +381,12 @@ build_function_definition(parser::ParseTree::Node parser_node, build_node(parser_node), build_symbol_docs(description_node, annotation_nodes, annotations_set), std::move(constraints), modifier, build_identifier(name_node), - std::move(*annotations), std::move(arguments), - std::move(*reference_types), std::move(types), - std::move(optional_arguments), std::move(result_arguments), - is_annotations_same_to_names, + std::move(arguments), are_annotations_same_to_names, expression_node.has_value() ? build_expression(expression_node.value(), expression_storage, type_storage) : std::optional()); -} // TODO: refactor ?? +} // definition_info? annotation_info* typeclass_identifier (':' // typeclass_identifier+)? ('{' function_definition* '}' | ';') diff --git a/src/statement_printers.cpp b/src/statement_printers.cpp index ce5c368..b3d2381 100644 --- a/src/statement_printers.cpp +++ b/src/statement_printers.cpp @@ -23,8 +23,19 @@ void print_import(const nodes::Import &statement, Printer &printer) { printer.print(" :"); for (size_t i = 0; i < statement.symbols_size(); ++i) { printer.space(); - // TODO: properly print operator identifier + + 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(";"); @@ -60,7 +71,7 @@ void print_statement_methods(const T &statement, Printer &printer) { void print_type_definition(const nodes::TypeDefinition &statement, Printer &printer) { - print_docs(*statement.get_docs(), printer); // TODO + print_docs(*statement.get_docs(), printer); if (statement.is_on_heap()) { printer.print("^"); @@ -90,7 +101,7 @@ void print_type_definition(const nodes::TypeDefinition &statement, void print_function_definition(const nodes::FunctionDefinition &statement, Printer &printer) { - print_docs(*statement.get_docs(), printer); // TODO + print_docs(*statement.get_docs(), printer); for (size_t i = 0; i < statement.get_constraints_size(); ++i) { print_constraint(*statement.get_constraint(i), printer); @@ -110,95 +121,65 @@ void print_function_definition(const nodes::FunctionDefinition &statement, break; } - bool operator_called_as_function = + bool identifier_is_operator = (statement.get_name()->get_type() == nodes::Identifier::OPERATOR); - if (operator_called_as_function) { + if (identifier_is_operator) { printer.print("( "); } print_identifier(*statement.get_name(), printer); - if (operator_called_as_function) { + if (identifier_is_operator) { printer.print(" )"); } - // 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(i)->get_name().has_value()) { + break; + } + printer.space(); - if (statement.get_argument_types_size() == 0) { - if (!statement.is_annotations_same_to_names() && - statement.get_argument_annotation(i).has_value()) { - print_annotation(*statement.get_argument_annotation(i).value(), + // 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(); } - 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_modifier(statement.get_argument(i)->get_before_modifier(), printer); } - print_identifier(*statement.get_argument(i), printer); + print_identifier(*statement.get_argument(i)->get_name().value(), 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("!"); - } + // 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); } } - if (statement.get_argument_types_size() > 0) { + // all arguments are typed or are untyped in the same time + if (statement.get_arguments_size() > 0 && + statement.get_argument(0)->get_type().has_value()) { + printer.print(" :"); - for (size_t i = 0; i < statement.get_argument_types_size(); ++i) { + + for (size_t i = 0; i < statement.get_arguments_size(); ++i) { printer.space(); - if (statement.get_argument_annotation(i).has_value()) { - print_annotation(*statement.get_argument_annotation(i).value(), + if (statement.get_argument(i)->get_annotation().has_value()) { + print_annotation(*statement.get_argument(i)->get_annotation().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_modifier(statement.get_argument(i)->get_before_modifier(), printer); - print_type(*statement.get_argument_type(i), printer); + print_type(*statement.get_argument(i)->get_type().value(), printer); } } @@ -218,7 +199,7 @@ void print_function_definition(const nodes::FunctionDefinition &statement, void print_typeclass_definition(const nodes::TypeclassDefinition &statement, Printer &printer) { - print_docs(*statement.get_docs(), printer); // TODO + print_docs(*statement.get_docs(), printer); print_identifier(*statement.get_name(), printer); @@ -234,5 +215,3 @@ void print_typeclass_definition(const nodes::TypeclassDefinition &statement, } // IN PROGRESS } // namespace printers - -// TODO: print operator in () diff --git a/src/type_builders.cpp b/src/type_builders.cpp index e632866..7982ff3 100644 --- a/src/type_builders.cpp +++ b/src/type_builders.cpp @@ -1,5 +1,6 @@ #include "type_builders.hpp" #include "basic_builders.hpp" +#include "basic_nodes.hpp" #include "tokens.hpp" namespace builders { @@ -15,12 +16,19 @@ nodes::TypeProxy build_type(parser::ParseTree::Node parse_node, bool is_on_heap = (!current_node.is_null() && !current_node.is_named() && current_node.get_value() == "^"); - current_node = name_node.next_sibling(); - bool is_optional = (!current_node.is_null() && !current_node.is_named() && - current_node.get_value() == "?"); + nodes::Modifier modifier = nodes::Modifier::NONE; - bool is_result = (!current_node.is_null() && !current_node.is_named() && - current_node.get_value() == "!"); + current_node = name_node.next_sibling(); + // update last after modifier + if (!current_node.is_null() && !current_node.is_named()) { + modifier = build_modifier(current_node); + + // only optional, result allowed + if (modifier != nodes::Modifier::OR_FALSE && + modifier != nodes::Modifier::OR_RETURN) { + modifier = nodes::Modifier::NONE; + } + } current_node = name_node.next_named_sibling(); while (!current_node.is_null()) { @@ -30,7 +38,7 @@ nodes::TypeProxy build_type(parser::ParseTree::Node parse_node, return type_storage.add_type( nodes::Type(build_node(parse_node), build_identifier(name_node), - std::move(parameters), is_on_heap, is_optional, is_result)); + std::move(parameters), is_on_heap, modifier)); } // '&'? annotation? type ('&' annotation? type)* diff --git a/src/type_nodes.cpp b/src/type_nodes.cpp index 5e171c0..af116a5 100644 --- a/src/type_nodes.cpp +++ b/src/type_nodes.cpp @@ -2,12 +2,8 @@ namespace nodes { -Type* TypeProxy::get() { - return type_storage_.get_type(id_); -} +Type *TypeProxy::get() { return type_storage_->get_type(id_); } -const Type* TypeProxy::get() const { - return type_storage_.get_type(id_); -} +const Type *TypeProxy::get() const { return type_storage_->get_type(id_); } }; // namespace nodes diff --git a/src/type_printers.cpp b/src/type_printers.cpp index 82e99be..206ceac 100644 --- a/src/type_printers.cpp +++ b/src/type_printers.cpp @@ -1,4 +1,5 @@ #include "type_printers.hpp" +#include "basic_nodes.hpp" #include "basic_printers.hpp" #include "type_nodes.hpp" @@ -11,13 +12,7 @@ void print_type(const nodes::Type &type, printers::Printer &printer) { print_identifier(*type.get_name(), printer); - if (type.is_optional()) { - printer.print("?"); - } - - if (type.is_result()) { - printer.print("!"); - } + print_modifier(type.get_modifier(), printer); if (type.get_parametrs_size() > 0) { printer.print("[");