diff --git a/include/basic_type_check.hpp b/include/basic_type_check.hpp index 27867de..e5ceb82 100644 --- a/include/basic_type_check.hpp +++ b/include/basic_type_check.hpp @@ -7,9 +7,7 @@ namespace type_check { // IN PROGRESS: modifiers ?? -nodes::TypeCheckResult -type_check_literal(const nodes::Literal &literal, - SourcesManager &sources_manager, - const Arguments& arguments); +Result check(const nodes::Literal &literal, SourcesManager &sources_manager, + State &state, const Arguments &arguments); } // namespace type_check diff --git a/include/builtin_types.hpp b/include/builtin_types.hpp index 4b3835a..c3bccbf 100644 --- a/include/builtin_types.hpp +++ b/include/builtin_types.hpp @@ -5,7 +5,33 @@ #include "basic_nodes.hpp" -namespace builtin::types { +namespace builtin { + +enum class Type { + // -- containers + TUPLE, + VARIANT, + FUNCTION, + ARRAY, + OPTIONAL, + RESULT, + ERROR, + // -- basic types + FLOAT, + DOUBLE, + INT, + LONG, + INDEX, + CHAR, + UNICODE, + BOOL, + UNIT, + NULL_OPTION, + // -- none + NONE, +}; + +namespace types { // -- containers @@ -50,30 +76,6 @@ const static std::string NULL_OPTION_IDENTIFIER = "Null"; // -enum class Type { - // -- containers - TUPLE, - VARIANT, - FUNCTION, - ARRAY, - OPTIONAL, - RESULT, - ERROR, - // -- basic types - FLOAT, - DOUBLE, - INT, - LONG, - INDEX, - CHAR, - UNICODE, - BOOL, - UNIT, - NULL_OPTION, - // -- none - NONE, -}; - inline std::string to_string(Type type) { switch (type) { // -- containers @@ -202,4 +204,6 @@ inline std::optional get_parameters_count(Type type) { exit(1); // unreachable } -} // namespace builtin::types +} // namespace types + +} // namespace builtin diff --git a/include/expression_type_check.hpp b/include/expression_type_check.hpp index 9bb7894..12c937a 100644 --- a/include/expression_type_check.hpp +++ b/include/expression_type_check.hpp @@ -12,77 +12,66 @@ namespace type_check { -nodes::TypeCheckResult -type_check_expression(const nodes::Expression &expression, - SourcesManager &sources_manager, State &state, - const Arguments &arguments); +Result check(const nodes::Expression &expression, + SourcesManager &sources_manager, State &state, + const Arguments &arguments); // --- flow control -nodes::TypeCheckResult type_check_match(const nodes::Match &expression, - SourcesManager &sources_manager, - State &state, - const Arguments &arguments); +Result check(const nodes::Match &expression, SourcesManager &sources_manager, + State &state, const Arguments &arguments); -nodes::TypeCheckResult type_check_condition(const nodes::Condition &expression, - SourcesManager &sources_manager, - State &state, - const Arguments &arguments); +Result check(const nodes::Condition &expression, + SourcesManager &sources_manager, State &state, + const Arguments &arguments); -nodes::TypeCheckResult type_check_loop(const nodes::Loop &expression, - SourcesManager &sources_manager, - State &state, - const Arguments &arguments); +Result check(const nodes::Loop &expression, SourcesManager &sources_manager, + State &state, const Arguments &arguments); // --- containers -nodes::TypeCheckResult type_check_container(const nodes::Container &expression, - SourcesManager &sources_manager, - State &state, - const Arguments &arguments); +Result check(const nodes::Container &expression, + SourcesManager &sources_manager, State &state, + const Arguments &arguments); // --- modifiers -nodes::TypeCheckResult type_check_return(const nodes::Return &expression, - SourcesManager &sources_manager, - State &state, - const Arguments &arguments); +Result check(const nodes::Return &expression, SourcesManager &sources_manager, + State &state, const Arguments &arguments); -nodes::TypeCheckResult -type_check_name_definition(const nodes::NameDefinition &expression, - SourcesManager &sources_manager, State &state, - const Arguments &arguments); +Result check(const nodes::NameDefinition &expression, + SourcesManager &sources_manager, State &state, + const Arguments &arguments); -nodes::TypeCheckResult type_check_access(const nodes::Access &expression, - SourcesManager &sources_manager, - State &state, - const Arguments &arguments); +Result check(const nodes::Access &expression, SourcesManager &sources_manager, + State &state, const Arguments &arguments); -nodes::TypeCheckResult -type_check_loop_control(const nodes::LoopControl &expression, - SourcesManager &sources_manager, State &state, - const Arguments &arguments); +Result check(const nodes::LoopControl &expression, + SourcesManager &sources_manager, State &state, + const Arguments &arguments); -nodes::TypeCheckResult -type_check_modifier_expression(const nodes::ModifierExpression &expression, - SourcesManager &sources_manager, State &state, - const Arguments &arguments); +Result check(const nodes::ModifierExpression &expression, + SourcesManager &sources_manager, State &state, + const Arguments &arguments); // --- other -nodes::TypeCheckResult -type_check_name_expression(const nodes::NameExpression &expression, - SourcesManager &sources_manager, State &state, - const Arguments &arguments); +Result check(const nodes::NameExpression &expression, + SourcesManager &sources_manager, State &state, + const Arguments &arguments); -nodes::TypeCheckResult -type_check_constructor(const nodes::Constructor &expression, - SourcesManager &sources_manager, State &state, - const Arguments &arguments); +Result check(const nodes::Constructor &expression, + SourcesManager &sources_manager, State &state, + const Arguments &arguments); -nodes::TypeCheckResult type_check_lambda(const nodes::Lambda &expression, - SourcesManager &sources_manager, - State &state, - const Arguments &arguments); +Result check(const nodes::Lambda &expression, SourcesManager &sources_manager, + State &state, const Arguments &arguments); + +Result check(const nodes::Extra &expression, SourcesManager &sources_manager, + State &state, const Arguments &arguments); + +Result check(const nodes::EmptyLines &expression, + SourcesManager &sources_manager, State &state, + const Arguments &arguments); } // namespace type_check diff --git a/include/nodes/type_nodes.hpp b/include/nodes/type_nodes.hpp index 9fc3390..fe6211b 100644 --- a/include/nodes/type_nodes.hpp +++ b/include/nodes/type_nodes.hpp @@ -217,7 +217,7 @@ public: bool operator>=(const Type &other) const { return !operator<(other); } // is parameters count check necessary ?? - builtin::types::Type to_builtin() const { + builtin::Type to_builtin() const { auto builtin_type = builtin::types::to_type(*name_.get()); auto builtin_type_parameters_count = @@ -226,15 +226,13 @@ public: // for fixed parameter counts if (builtin_type_parameters_count.has_value() && builtin_type_parameters_count.value() != parameters_.size()) { - return builtin::types::Type::NONE; + return builtin::Type::NONE; } return builtin_type; } - bool is_builtin(builtin::types::Type type) const { - return to_builtin() == type; - } + bool is_builtin(builtin::Type type) const { return to_builtin() == type; } private: Identifier name_; @@ -247,7 +245,7 @@ class TypeStorage { friend TypeProxy; public: - TypeProxy primitive_type(builtin::types::Type type) { + TypeProxy primitive(builtin::Type type) { auto iter = primitive_type_ids_.find(type); if (iter != primitive_type_ids_.end()) { return TypeProxy(*this, iter->second); @@ -289,7 +287,7 @@ public: } nodes::TypeProxy add_container_of(std::vector &¶meters, - builtin::types::Type container, + builtin::Type container, Node node = Node()) { for (auto ¶meter : parameters) { if (parameter.type_storage_ != this) { @@ -343,7 +341,7 @@ public: if (type.is_generic()) { auto iter = resolved_generic_names_.find(*type.get_name()->get()); - // because of undefined order sone types can became resolved earlir + // because of undefined order some types can became resolved earlir // wirking correctly because each generic type has <= 1 successor, no // cyclic deps allowed (do check ??) if (iter != resolved_generic_names_.end()) { @@ -471,7 +469,7 @@ private: private: // check is builtin type instaniated - std::unordered_map primitive_type_ids_; + std::unordered_map primitive_type_ids_; // deal with generic types and generic names std::unordered_map resolved_generic_names_; @@ -485,46 +483,4 @@ private: std::vector storage_; }; -class TypeCheckResult { -public: - // for invalid type - static TypeCheckResult construct_invalid_result() { - return TypeCheckResult(); - } - - explicit TypeCheckResult(nodes::TypeProxy type) : type_(type) {} - - // - - TypeProxy &get() { - if (!type_.has_value()) { - error_handling::handle_general_error( - "Access to invalid type in TypeCheckResult"); - } - - return type_.value(); - } - - const TypeProxy &get() const { - if (!type_.has_value()) { - error_handling::handle_general_error( - "Access to invalid type in TypeCheckResult"); - } - - return type_.value(); - } - - void set(TypeProxy type) { type_ = type; } - - // - - bool is_invalid() const { return !type_.has_value(); } - -private: - TypeCheckResult() = default; - -private: - nodes::MaybeTypeProxy type_; -}; - } // namespace nodes diff --git a/include/printers/basic_printers.hpp b/include/printers/basic_printers.hpp index f9673ec..9b48f6b 100644 --- a/include/printers/basic_printers.hpp +++ b/include/printers/basic_printers.hpp @@ -124,17 +124,24 @@ private: size_t indentation_level_ = 0; }; -void print_modifier(const nodes::Modifier &modifier, Printer &printer, - bool const_is_none = false); +void print(const nodes::Modifier &modifier, Printer &printer, + bool const_is_none = false); -void print_literal(const nodes::Literal &literal, Printer &printer); +void print(const nodes::Literal &literal, Printer &printer); -void print_identifier(const nodes::Identifier &identifier, Printer &printer); +void print(const nodes::Identifier &identifier, Printer &printer); void print_annotation(const std::string &annotation, Printer &printer); -void print_extra(const nodes::Extra &extra, Printer &printer); +void print(const nodes::Extra &extra, Printer &printer); -void print_empty_lines(const nodes::EmptyLines &empty_lines, Printer &printer); +void print(const nodes::EmptyLines &empty_lines, Printer &printer); + +template +inline void print(const std::vector &nodes, Printer &printer) { + for (const auto &node : nodes) { + print(node, printer); + } +} } // namespace printers diff --git a/include/printers/doc_printers.hpp b/include/printers/doc_printers.hpp index 3ffbe04..234bc51 100644 --- a/include/printers/doc_printers.hpp +++ b/include/printers/doc_printers.hpp @@ -5,6 +5,6 @@ namespace printers { -void print_docs(const nodes::SymbolDocs &docs, Printer &printer); +void print(const nodes::SymbolDocs &docs, Printer &printer); } // namespace printers diff --git a/include/printers/expression_printers.hpp b/include/printers/expression_printers.hpp index 293a01d..2a6836b 100644 --- a/include/printers/expression_printers.hpp +++ b/include/printers/expression_printers.hpp @@ -4,48 +4,41 @@ #include "expression_nodes.hpp" namespace printers { -void print_expression(const nodes::Expression &expression, - printers::Printer &printer); +void print(const nodes::Expression &expression, printers::Printer &printer); // --- flow control -void print_case(const nodes::Match::Case &expression, Printer &printer); +void print(const nodes::Match::Case &expression, Printer &printer); -void print_match(const nodes::Match &expression, printers::Printer &printer); +void print(const nodes::Match &expression, printers::Printer &printer); -void print_condition(const nodes::Condition &expression, - printers::Printer &printer); +void print(const nodes::Condition &expression, printers::Printer &printer); -void print_loop(const nodes::Loop &expression, printers::Printer &printer); +void print(const nodes::Loop &expression, printers::Printer &printer); // --- containers -void print_container(const nodes::Container &expression, - printers::Printer &printer); +void print(const nodes::Container &expression, printers::Printer &printer); // --- modifiers -void print_return(const nodes::Return &expression, printers::Printer &printer); +void print(const nodes::Return &expression, printers::Printer &printer); -void print_name_definition(const nodes::NameDefinition &expression, - printers::Printer &printer); +void print(const nodes::NameDefinition &expression, printers::Printer &printer); -void print_access(const nodes::Access &expression, printers::Printer &printer); +void print(const nodes::Access &expression, printers::Printer &printer); -void print_loop_control(const nodes::LoopControl &expression, - printers::Printer &printer); +void print(const nodes::LoopControl &expression, printers::Printer &printer); -void print_modifier_expression(const nodes::ModifierExpression &expression, - printers::Printer &printer); +void print(const nodes::ModifierExpression &expression, + printers::Printer &printer); // --- other -void print_name_expression(const nodes::NameExpression &expression, - printers::Printer &printer); +void print(const nodes::NameExpression &expression, printers::Printer &printer); -void print_constructor(const nodes::Constructor &expression, - printers::Printer &printer); +void print(const nodes::Constructor &expression, printers::Printer &printer); -void print_lambda(const nodes::Lambda &expression, printers::Printer &printer); +void print(const nodes::Lambda &expression, printers::Printer &printer); } // namespace printers diff --git a/include/printers/statement_printers.hpp b/include/printers/statement_printers.hpp index 7e0c61a..7fd745c 100644 --- a/include/printers/statement_printers.hpp +++ b/include/printers/statement_printers.hpp @@ -7,19 +7,17 @@ namespace printers { -void print_source_file(const std::vector &statements, - Printer &printer); +// void print_source_file(const std::vector &statements, +// Printer &printer); -void print_statement(const nodes::Statement &statements, Printer &printer); +void print(const nodes::Statement &statements, Printer &printer); -void print_import(const nodes::Import &statement, Printer &printer); +void print(const nodes::Import &statement, Printer &printer); -void print_constraint(const nodes::Constraint &statement, Printer &printer); +void print(const nodes::Constraint &statement, Printer &printer); -void print_type_definition(const nodes::TypeDefinition &statement, - Printer &printer); +void print(const nodes::TypeDefinition &statement, Printer &printer); -void print_function_definition(const nodes::FunctionDefinition &statement, - Printer &printer); +void print(const nodes::FunctionDefinition &statement, Printer &printer); } // namespace printers diff --git a/include/printers/type_printers.hpp b/include/printers/type_printers.hpp index 08cb7ce..840d67a 100644 --- a/include/printers/type_printers.hpp +++ b/include/printers/type_printers.hpp @@ -5,7 +5,7 @@ namespace printers { -void print_type(const nodes::Type &type, printers::Printer &printer); +void print(const nodes::Type &type, printers::Printer &printer); // void print_tuple_type(const nodes::TupleType &type, printers::Printer // &printer); diff --git a/include/sources_manager.hpp b/include/sources_manager.hpp index 26d078b..77cdc1a 100644 --- a/include/sources_manager.hpp +++ b/include/sources_manager.hpp @@ -49,44 +49,42 @@ public: void print(std::ostream &out) { printers::Printer printer(out, 2, 80, true); - printers::print_source_file(statements_, printer); + printers::print(statements_, printer); } // - nodes::ExpressionStorage *get_expression_storage() { - return &expression_storage_; - } + nodes::ExpressionStorage *expressions() { return &expression_storage_; } - const nodes::ExpressionStorage *get_expression_storage() const { + const nodes::ExpressionStorage *expressions() const { return &expression_storage_; } // - nodes::TypeStorage *get_type_storage() { return &type_storage_; } + nodes::TypeStorage *types() { return &type_storage_; } - const nodes::TypeStorage *get_type_storage() const { return &type_storage_; } + const nodes::TypeStorage *types() const { return &type_storage_; } // - names::NameTree *get_name_tree() { return &name_tree_; } + names::NameTree *names() { return &name_tree_; } - const names::NameTree *get_name_tree() const { return &name_tree_; } + const names::NameTree *names() const { return &name_tree_; } // - error_handling::ErrorLog *get_error_log() { return &error_log_; } + error_handling::ErrorLog *errors() { return &error_log_; } - const error_handling::ErrorLog *get_error_log() const { return &error_log_; } + const error_handling::ErrorLog *errors() const { return &error_log_; } // size_t statements_size() const { return statements_.size(); } - nodes::Statement *get_statement(size_t id) { return &statements_.at(id); } + nodes::Statement *statement(size_t id) { return &statements_.at(id); } - const nodes::Statement *get_statement(size_t id) const { + const nodes::Statement *statement(size_t id) const { return &statements_.at(id); } diff --git a/include/type_check_utils.hpp b/include/type_check_utils.hpp index 66e25d3..c3d076f 100644 --- a/include/type_check_utils.hpp +++ b/include/type_check_utils.hpp @@ -145,23 +145,23 @@ public: std::vector contexts_ = {{}}; }; +// + class Arguments { public: Arguments() = default; - Arguments expect_builtin(builtin::types::Type type, + Arguments expect_builtin(builtin::Type type, SourcesManager &sources_manager) const { Arguments copy(*this); - copy.expected_types_ = { - sources_manager.get_type_storage()->primitive_type(type)}; + copy.expected_types_ = {sources_manager.types()->primitive(type)}; return copy; } - Arguments pass_builtin(builtin::types::Type type, + Arguments pass_builtin(builtin::Type type, SourcesManager &sources_manager) const { Arguments copy(*this); - copy.passed_type_ = - sources_manager.get_type_storage()->primitive_type(type); + copy.passed_type_ = sources_manager.types()->primitive(type); return copy; } @@ -208,6 +208,8 @@ private: nodes::MaybeTypeProxy passed_type_; }; +// + class ContextHolder { public: ContextHolder(State &state, const nodes::Node &node, @@ -236,6 +238,52 @@ private: nodes::MaybeTypeProxy *context_exit_type_; }; +// + +class Result { +public: + // for invalid type + static Result invalid() { return Result(); } + + explicit Result(nodes::TypeProxy type) : type_(type) {} + + // + + nodes::TypeProxy &get() { + if (!type_.has_value()) { + error_handling::handle_general_error( + "Access to invalid type in TypeCheckResult"); + } + + return type_.value(); + } + + const nodes::TypeProxy &get() const { + if (!type_.has_value()) { + error_handling::handle_general_error( + "Access to invalid type in TypeCheckResult"); + } + + return type_.value(); + } + + void set(nodes::TypeProxy type) { type_ = type; } + + // + + bool is_invalid() const { return !type_.has_value(); } + +private: + Result() = default; + +private: + nodes::MaybeTypeProxy type_; +}; + +using MaybeResult = std::optional; + +// + nodes::TypeProxy check_same_to_pass_type_in_arguments( nodes::TypeProxy type, const Arguments &arguments, const nodes::Node &node, SourcesManager &sources_manager, @@ -247,15 +295,17 @@ nodes::TypeProxy check_same_to_pass_type_in_arguments( // SourcesManager &sources_manager, // const std::string &message = "Type can't be passed to this node"); -nodes::TypeCheckResult type_same_to_expected( +Result type_same_to_expected( nodes::TypeProxy type, const Arguments &argumensr, const nodes::Node &node, SourcesManager &sources_manager, const std::string &message = "Different type with expected one", bool handle_errors = true); -nodes::TypeCheckResult type_check_from_arguments( - nodes::TypeProxy type, const Arguments &arguments, const nodes::Node &node, - SourcesManager &sources_manager, bool handle_errors = true); +Result type_check_from_arguments(nodes::TypeProxy type, + const Arguments &arguments, + const nodes::Node &node, + SourcesManager &sources_manager, + bool handle_errors = true); std::optional find_type_definition(const std::string &name, const nodes::Node &node, @@ -267,15 +317,16 @@ find_name_definition(const std::string &name, const nodes::Node &node, SourcesManager &sources_manager, bool handle_errors = true); -std::optional -unfold_user_defined_type(nodes::TypeProxy type, const nodes::Node &node, - SourcesManager &sources_manager, - bool handle_errors = true); +nodes::MaybeTypeProxy unfold_user_defined_type(nodes::TypeProxy type, + const nodes::Node &node, + SourcesManager &sources_manager, + bool handle_errors = true); -std::optional -get_field_type_by_name(nodes::TypeProxy type, const std::string &field, - const nodes::Node &node, SourcesManager &sources_manager, - bool handle_errors = true); +nodes::MaybeTypeProxy get_field_type_by_name(nodes::TypeProxy type, + const std::string &field, + const nodes::Node &node, + SourcesManager &sources_manager, + bool handle_errors = true); void type_check_error(const std::string &message, const nodes::Node &node, SourcesManager &sources_manager, diff --git a/src/basic_type_check.cpp b/src/basic_type_check.cpp index a0a536d..f199229 100644 --- a/src/basic_type_check.cpp +++ b/src/basic_type_check.cpp @@ -6,52 +6,39 @@ nodes::TypeProxy get_literal_type(const nodes::Literal &literal, SourcesManager &sources_manager) { switch (literal.get_any()->index()) { case 0: // float - return sources_manager.get_type_storage()->primitive_type( - builtin::types::Type::FLOAT); + return sources_manager.types()->primitive(builtin::Type::FLOAT); case 1: // double - return sources_manager.get_type_storage()->primitive_type( - builtin::types::Type::DOUBLE); + return sources_manager.types()->primitive(builtin::Type::DOUBLE); case 2: // int32_t - return sources_manager.get_type_storage()->primitive_type( - builtin::types::Type::INT); + return sources_manager.types()->primitive(builtin::Type::INT); case 3: // int64_t - return sources_manager.get_type_storage()->primitive_type( - builtin::types::Type::LONG); + return sources_manager.types()->primitive(builtin::Type::LONG); case 4: // size_t - return sources_manager.get_type_storage()->primitive_type( - builtin::types::Type::INDEX); + return sources_manager.types()->primitive(builtin::Type::INDEX); case 5: // std::string - return sources_manager.get_type_storage()->add_array_of( - sources_manager.get_type_storage()->primitive_type( - builtin::types::Type::CHAR)); + return sources_manager.types()->add_array_of( + sources_manager.types()->primitive(builtin::Type::CHAR)); case 6: // unicode_string - return sources_manager.get_type_storage()->add_array_of( - sources_manager.get_type_storage()->primitive_type( - builtin::types::Type::UNICODE)); + return sources_manager.types()->add_array_of( + sources_manager.types()->primitive(builtin::Type::UNICODE)); case 7: // char - return sources_manager.get_type_storage()->primitive_type( - builtin::types::Type::CHAR); + return sources_manager.types()->primitive(builtin::Type::CHAR); case 8: // unicode - return sources_manager.get_type_storage()->primitive_type( - builtin::types::Type::UNICODE); + return sources_manager.types()->primitive(builtin::Type::UNICODE); case 9: // bool - return sources_manager.get_type_storage()->primitive_type( - builtin::types::Type::BOOL); + return sources_manager.types()->primitive(builtin::Type::BOOL); case 10: // unit - return sources_manager.get_type_storage()->primitive_type( - builtin::types::Type::UNIT); + return sources_manager.types()->primitive(builtin::Type::UNIT); case 11: // null - return sources_manager.get_type_storage()->primitive_type( - builtin::types::Type::NULL_OPTION); + return sources_manager.types()->primitive(builtin::Type::NULL_OPTION); } error_handling::handle_general_error("Unreachable"); exit(1); // unreachable } -nodes::TypeCheckResult type_check_literal(const nodes::Literal &literal, - SourcesManager &sources_manager, - const Arguments &arguments) { +Result check(const nodes::Literal &literal, SourcesManager &sources_manager, + State &, const Arguments &arguments) { auto const type = get_literal_type(literal, sources_manager); return type_same_to_expected(type, arguments, literal, sources_manager); } diff --git a/src/builders/type_builders.cpp b/src/builders/type_builders.cpp index 78dc6d3..352b995 100644 --- a/src/builders/type_builders.cpp +++ b/src/builders/type_builders.cpp @@ -63,7 +63,7 @@ collect_parameters(parser::ParseTree::Node first_node, nodes::TypeProxy build_container_type(parser::ParseTree::Node parser_node, nodes::TypeStorage &type_storage, - builtin::types::Type container) { + builtin::Type container) { std::vector parameters = collect_parameters(parser_node.nth_named_child(0), type_storage); @@ -75,14 +75,13 @@ nodes::TypeProxy build_container_type(parser::ParseTree::Node parser_node, nodes::TypeProxy build_variant_type(parser::ParseTree::Node parser_node, nodes::TypeStorage &type_storage) { return build_container_type(parser_node, type_storage, - builtin::types::Type::VARIANT); + builtin::Type::VARIANT); } // '&'? annotation? type ('&' annotation? type)+ nodes::TypeProxy build_tuple_type(parser::ParseTree::Node parser_node, nodes::TypeStorage &type_storage) { - return build_container_type(parser_node, type_storage, - builtin::types::Type::TUPLE); + return build_container_type(parser_node, type_storage, builtin::Type::TUPLE); } // _reference_ type diff --git a/src/expression_type_check.cpp b/src/expression_type_check.cpp index e6a8d97..890550f 100644 --- a/src/expression_type_check.cpp +++ b/src/expression_type_check.cpp @@ -1,5 +1,4 @@ #include "expression_type_check.hpp" - #include "basic_nodes.hpp" #include "basic_type_check.hpp" #include "builtin_types.hpp" @@ -15,89 +14,29 @@ namespace type_check { -nodes::TypeCheckResult -type_check_expression(const nodes::Expression &expression, - SourcesManager &sources_manager, State &state, - const Arguments &arguments) { - switch (expression.get_any()->index()) { - // --- flow control - case 0: // Match - return type_check_match(*expression.get().value(), - sources_manager, state, arguments); - case 1: // Condition - return type_check_condition(*expression.get().value(), - sources_manager, state, arguments); - case 2: // Loop - return type_check_loop(*expression.get().value(), - sources_manager, state, arguments); - // --- containers - case 3: // Container - return type_check_container(*expression.get().value(), - sources_manager, state, arguments); - // --- modifiers - case 4: // Return - return type_check_return(*expression.get().value(), - sources_manager, state, arguments); - case 5: // NameDefinition - return type_check_name_definition( - *expression.get().value(), sources_manager, - state, arguments); - case 6: // Access - return type_check_access(*expression.get().value(), - sources_manager, state, arguments); - case 7: // LoopControl - return type_check_loop_control( - *expression.get().value(), sources_manager, state, - arguments); - case 8: // ModifierExpression - return type_check_modifier_expression( - *expression.get().value(), sources_manager, - state, arguments); - // --- other - case 9: // NameExpression - return type_check_name_expression( - *expression.get().value(), sources_manager, - state, arguments); - case 10: // Constructor - return type_check_constructor(*expression.get().value(), - sources_manager, state, arguments); - case 11: // Lambda - return type_check_lambda(*expression.get().value(), - sources_manager, state, arguments); - // --- literal - case 12: // Literal - // TODO - return type_check_literal(*expression.get().value(), - sources_manager, arguments); - // --- empty lines - case 13: // Extra - return nodes::TypeCheckResult( - sources_manager.get_type_storage()->primitive_type( - builtin::types::Type::UNIT)); - case 14: // EmptyLines - return nodes::TypeCheckResult( - sources_manager.get_type_storage()->primitive_type( - builtin::types::Type::UNIT)); - } - - utils::unreachable(); +Result type_check_expression(const nodes::Expression &expression, + SourcesManager &sources_manager, State &state, + const Arguments &arguments) { + return std::visit( + [&sources_manager, &state, &arguments](const auto &arg) -> Result { + return check(arg, sources_manager, state, arguments); + }, + *expression.get_any()); } // --- flow control -nodes::TypeCheckResult type_check_match(const nodes::Match &expression, - SourcesManager &sources_manager, - State &state, - const Arguments &arguments) { - nodes::TypeCheckResult value_result = type_check_expression( - *expression.get_value(), sources_manager, state, Arguments{}); +Result check(const nodes::Match &expression, SourcesManager &sources_manager, + State &state, const Arguments &arguments) { + Result value_result = + check(*expression.get_value(), sources_manager, state, Arguments{}); // x :=/=: ... if (value_result.is_invalid()) { type_check_error("Match value is invalid", expression, sources_manager); } - std::optional expression_result; + MaybeResult expression_result; bool at_least_one_case_with_expression = false; bool at_least_one_case_without_expression = false; @@ -106,30 +45,28 @@ nodes::TypeCheckResult type_check_match(const nodes::Match &expression, const nodes::Match::Case *current_case = expression.get_case(i); // :=/=: x ... - type_check_expression( - *current_case->get_value(), sources_manager, state, - Arguments{} - .expect_builtin(builtin::types::Type::BOOL, sources_manager) - .pass(value_result.is_invalid() ? nodes::MaybeTypeProxy{} - : expression_result.value().get())); + check(*current_case->get_value(), sources_manager, state, + Arguments{} + .expect_builtin(builtin::Type::BOOL, sources_manager) + .pass(value_result.is_invalid() + ? nodes::MaybeTypeProxy{} + : expression_result.value().get())); // TODO: use type modifiers ?? // ... ?? x ... if (current_case->get_condition().has_value()) { - type_check_expression(*current_case->get_condition().value(), - sources_manager, state, - Arguments{}.expect_builtin( - builtin::types::Type::BOOL, sources_manager)); + check(*current_case->get_condition().value(), sources_manager, state, + Arguments{}.expect_builtin(builtin::Type::BOOL, sources_manager)); } // ... -> x if (current_case->get_expression().has_value()) { at_least_one_case_with_expression = true; - nodes::TypeCheckResult case_result = type_check_expression( - *current_case->get_condition().value(), sources_manager, state, - Arguments{}.expect(expression_result.has_value() - ? expression_result.value().get() - : nodes::MaybeTypeProxy{})); + Result case_result = + check(*current_case->get_condition().value(), sources_manager, state, + Arguments{}.expect(expression_result.has_value() + ? expression_result.value().get() + : nodes::MaybeTypeProxy{})); if (!expression_result.has_value() && !case_result.is_invalid()) { expression_result = std::move(case_result); @@ -144,38 +81,33 @@ nodes::TypeCheckResult type_check_match(const nodes::Match &expression, type_check_error( "All cases should be with or without expression at the same time", expression, sources_manager); - expression_result = nodes::TypeCheckResult::construct_invalid_result(); + expression_result = Result::invalid(); } if (!expression_result.has_value()) { - expression_result = nodes::TypeCheckResult{ - sources_manager.get_type_storage()->primitive_type( - builtin::types::Type::UNIT)}; + expression_result = + Result{sources_manager.types()->primitive(builtin::Type::UNIT)}; } return type_check_from_arguments( - sources_manager.get_type_storage()->add_array_of( - expression_result.value().get()), + sources_manager.types()->add_array_of(expression_result.value().get()), arguments, expression, sources_manager); } -nodes::TypeCheckResult type_check_condition(const nodes::Condition &expression, - SourcesManager &sources_manager, - State &state, - const Arguments &arguments) { - - std::optional expression_result; +Result check(const nodes::Condition &expression, + SourcesManager &sources_manager, State &state, + const Arguments &arguments) { + MaybeResult expression_result; for (size_t i = 0; i < expression.cases_size(); ++i) { - type_check_expression(*expression.get_case(i).first, sources_manager, state, - Arguments{}.expect_builtin(builtin::types::Type::BOOL, - sources_manager)); + check(*expression.get_case(i).first, sources_manager, state, + Arguments{}.expect_builtin(builtin::Type::BOOL, sources_manager)); - nodes::TypeCheckResult case_result = type_check_expression( - *expression.get_case(i).first, sources_manager, state, - Arguments{}.expect(expression_result.has_value() - ? expression_result.value().get() - : nodes::MaybeTypeProxy{})); + Result case_result = + check(*expression.get_case(i).first, sources_manager, state, + Arguments{}.expect(expression_result.has_value() + ? expression_result.value().get() + : nodes::MaybeTypeProxy{})); if (!expression_result.has_value() && !case_result.is_invalid()) { expression_result = std::move(case_result); @@ -183,46 +115,40 @@ nodes::TypeCheckResult type_check_condition(const nodes::Condition &expression, } if (expression.get_else_case().has_value()) { - type_check_expression( - *expression.get_else_case().value(), sources_manager, state, - Arguments{}.expect(expression_result.has_value() - ? expression_result.value().get() - : nodes::MaybeTypeProxy{})); + check(*expression.get_else_case().value(), sources_manager, state, + Arguments{}.expect(expression_result.has_value() + ? expression_result.value().get() + : nodes::MaybeTypeProxy{})); } if (!expression_result.has_value()) { type_check_error("There should be at least one case in if statement", expression, sources_manager); - expression_result = nodes::TypeCheckResult::construct_invalid_result(); + expression_result = Result::invalid(); } return type_check_from_arguments( - sources_manager.get_type_storage()->add_array_of( - expression_result.value().get()), + sources_manager.types()->add_array_of(expression_result.value().get()), arguments, expression, sources_manager); } -nodes::TypeCheckResult type_check_loop(const nodes::Loop &expression, - SourcesManager &sources_manager, - State &state, - const Arguments &arguments) { +Result check(const nodes::Loop &expression, SourcesManager &sources_manager, + State &state, const Arguments &arguments) { // TODO: ranges ?? - std::optional interval_result; + MaybeResult interval_result; - std::optional variable_result; + MaybeResult variable_result; - nodes::TypeCheckResult expression_result = type_check_expression( - *expression.get_expression(), sources_manager, state, Arguments{}); + Result expression_result = + check(*expression.get_expression(), sources_manager, state, Arguments{}); switch (expression.get_type()) { case nodes::Loop::LOOP: // infinity loop, no params break; case nodes::Loop::WHILE: - type_check_expression(*expression.get_condition().value(), sources_manager, - state, - Arguments{}.expect_builtin(builtin::types::Type::BOOL, - sources_manager)); + check(*expression.get_condition().value(), sources_manager, state, + Arguments{}.expect_builtin(builtin::Type::BOOL, sources_manager)); // --- type check is independent from loop itself --- // if (condition_result.value().is_invalid()) { @@ -232,10 +158,9 @@ nodes::TypeCheckResult type_check_loop(const nodes::Loop &expression, break; case nodes::Loop::FOR: // TODO: expect range ?? - interval_result = type_check_expression( + interval_result = check( *expression.get_interval().value(), sources_manager, state, - Arguments{}.expect_builtin(builtin::types::Type::ARRAY, - sources_manager)); + Arguments{}.expect_builtin(builtin::Type::ARRAY, sources_manager)); if (interval_result.value().is_invalid()) { // --- type check is independent from loop itself --- @@ -243,10 +168,10 @@ nodes::TypeCheckResult type_check_loop(const nodes::Loop &expression, break; } - variable_result = type_check_expression( - *expression.get_variable().value(), sources_manager, state, - Arguments{}.expect( - interval_result.value().get().get()->get_parameter_proxy(0))); + variable_result = + check(*expression.get_variable().value(), sources_manager, state, + Arguments{}.expect( + interval_result.value().get().get()->get_parameter_proxy(0))); // --- type check is independent from loop itself --- // if (variable_result.value().is_invalid()) { @@ -262,22 +187,21 @@ nodes::TypeCheckResult type_check_loop(const nodes::Loop &expression, // TODO: modifier checks ??, modifiers ?? return type_check_from_arguments( - sources_manager.get_type_storage()->add_array_of(expression_result.get()), - arguments, expression, sources_manager); + sources_manager.types()->add_array_of(expression_result.get()), arguments, + expression, sources_manager); } // IN PROGRESS // --- containers -nodes::TypeCheckResult type_check_array(const nodes::Container &expression, - SourcesManager &sources_manager, - State &state, - const Arguments &arguments) { - std::optional last_expression_result; +Result type_check_array(const nodes::Container &expression, + SourcesManager &sources_manager, State &state, + const Arguments &arguments) { + MaybeResult last_expression_result; for (size_t i = 0; i < expression.expressions_size(); ++i) { // elements should have same type, but type is not expected - auto expression_result = type_check_expression( - *expression.get_expression(i), sources_manager, state, Arguments{}); + auto expression_result = check(*expression.get_expression(i), + sources_manager, state, Arguments{}); if (!last_expression_result.has_value()) { last_expression_result = expression_result; @@ -285,7 +209,7 @@ nodes::TypeCheckResult type_check_array(const nodes::Container &expression, if (last_expression_result.value().get() != expression_result.get()) { type_check_error("Elements in array should have same type", *expression.get_expression(i), sources_manager); - // return nodes::TypeCheckResult::construct_invalid_result(); // max + // return TypeCheckResult::construct_invalid_result(); // max // possible checks, so no return } } @@ -293,50 +217,43 @@ nodes::TypeCheckResult type_check_array(const nodes::Container &expression, if (!last_expression_result.has_value()) { type_check_error("Array with zero elements", expression, sources_manager); - return nodes::TypeCheckResult::construct_invalid_result(); + return Result::invalid(); } - return type_check_from_arguments( - sources_manager.get_type_storage()->add_array_of( - last_expression_result.value().get()), - arguments, expression, sources_manager); + return type_check_from_arguments(sources_manager.types()->add_array_of( + last_expression_result.value().get()), + arguments, expression, sources_manager); } -nodes::TypeCheckResult type_check_block(const nodes::Container &expression, - SourcesManager &sources_manager, - State &state, - const Arguments &arguments) { +Result type_check_block(const nodes::Container &expression, + SourcesManager &sources_manager, State &state, + const Arguments &arguments) { nodes::MaybeTypeProxy context_exit_type; { ContextHolder context_holder( - state, expression, *sources_manager.get_error_log(), + state, expression, *sources_manager.errors(), &context_exit_type); // TODO: is brought type returned for (size_t i = 0; i < expression.expressions_size(); ++i) { // result types in block are discarded - type_check_expression(*expression.get_expression(i), sources_manager, - state, Arguments{}); + check(*expression.get_expression(i), sources_manager, state, Arguments{}); } } - nodes::TypeCheckResult block_brought_type = + Result block_brought_type = context_exit_type.has_value() - ? nodes::TypeCheckResult(context_exit_type.value()) - : nodes::TypeCheckResult( - sources_manager.get_type_storage()->primitive_type( - builtin::types::Type::UNIT)); + ? Result(context_exit_type.value()) + : Result(sources_manager.types()->primitive(builtin::Type::UNIT)); return type_check_from_arguments( - sources_manager.get_type_storage()->add_array_of( - block_brought_type.get()), + sources_manager.types()->add_array_of(block_brought_type.get()), arguments, expression, sources_manager); } -nodes::TypeCheckResult type_check_container(const nodes::Container &expression, - SourcesManager &sources_manager, - State &state, - const Arguments &arguments) { +Result check(const nodes::Container &expression, + SourcesManager &sources_manager, State &state, + const Arguments &arguments) { switch (expression.get_type()) { case nodes::Container::ARRAY: return type_check_array(expression, sources_manager, state, arguments); @@ -347,12 +264,10 @@ nodes::TypeCheckResult type_check_container(const nodes::Container &expression, // --- modifiers -nodes::TypeCheckResult type_check_return(const nodes::Return &expression, - SourcesManager &sources_manager, - State &state, - const Arguments &arguments) { - auto returned_result = type_check_expression( - *expression.get_expression(), sources_manager, state, Arguments{}); +Result check(const nodes::Return &expression, SourcesManager &sources_manager, + State &state, const Arguments &arguments) { + auto returned_result = + check(*expression.get_expression(), sources_manager, state, Arguments{}); if (returned_result.is_invalid()) { return returned_result; @@ -363,29 +278,27 @@ nodes::TypeCheckResult type_check_return(const nodes::Return &expression, if (state.bring_type(returned_result.get())) { type_check_error("Different brought type to current one", expression, sources_manager); - return nodes::TypeCheckResult::construct_invalid_result(); + return Result::invalid(); } break; case nodes::Return::RETURN: if (!state.return_type(returned_result.get())) { type_check_error("Different returned type to current one", expression, sources_manager); - return nodes::TypeCheckResult::construct_invalid_result(); + return Result::invalid(); } break; } return type_check_from_arguments( - sources_manager.get_type_storage()->primitive_type( - builtin::types::Type::UNIT), - arguments, expression, sources_manager); + sources_manager.types()->primitive(builtin::Type::UNIT), arguments, + expression, sources_manager); } // TODO: warning if name is same to package prefix, function prefix, etc. ?? -nodes::TypeCheckResult -type_check_name_definition(const nodes::NameDefinition &expression, - SourcesManager &sources_manager, State &state, - const Arguments &arguments) { +Result check(const nodes::NameDefinition &expression, + SourcesManager &sources_manager, State &state, + const Arguments &arguments) { if (!arguments.get_passed().has_value()) { type_check_error("Can't deduce type of new variable from context", expression, sources_manager); @@ -401,8 +314,8 @@ type_check_name_definition(const nodes::NameDefinition &expression, } // variable accessible by reference by default ?? - sources_manager.get_type_storage()->add_modification_of(variable_type, - nodes::Modifier::REF); + sources_manager.types()->add_modification_of(variable_type, + nodes::Modifier::REF); if (!state.insert_variable(*expression.get_name()->get(), variable_type, expression.get_modifier())) { @@ -412,23 +325,20 @@ type_check_name_definition(const nodes::NameDefinition &expression, // Return BOOL as any := / =: expression return type_check_from_arguments( - sources_manager.get_type_storage()->primitive_type( - builtin::types::Type::BOOL), - arguments, expression, sources_manager); + sources_manager.types()->primitive(builtin::Type::BOOL), arguments, + expression, sources_manager); } -nodes::TypeCheckResult type_check_array_access(const nodes::Access &expression, - SourcesManager &sources_manager, - State &state, - const Arguments &arguments) { +Result type_check_array_access(const nodes::Access &expression, + SourcesManager &sources_manager, State &state, + const Arguments &arguments) { + auto index_result = + check(*expression.get_index(), sources_manager, state, + Arguments{}.expect_builtin(builtin::Type::INDEX, sources_manager)); - auto index_result = type_check_expression( - *expression.get_index(), sources_manager, state, - Arguments{}.expect_builtin(builtin::types::Type::INDEX, sources_manager)); - - auto value_result = type_check_expression( - *expression.get_value(), sources_manager, state, - Arguments{}.expect_builtin(builtin::types::Type::ARRAY, sources_manager)); + auto value_result = + check(*expression.get_value(), sources_manager, state, + Arguments{}.expect_builtin(builtin::Type::ARRAY, sources_manager)); if (index_result.is_invalid()) { return index_result; @@ -445,13 +355,12 @@ nodes::TypeCheckResult type_check_array_access(const nodes::Access &expression, sources_manager); } -nodes::TypeCheckResult type_check_tuple_access(const nodes::Access &expression, - SourcesManager &sources_manager, - State &state, - const Arguments &arguments) { - auto value_result = type_check_expression( - *expression.get_value(), sources_manager, state, - Arguments{}.expect_builtin(builtin::types::Type::TUPLE, sources_manager)); +Result type_check_tuple_access(const nodes::Access &expression, + SourcesManager &sources_manager, State &state, + const Arguments &arguments) { + auto value_result = + check(*expression.get_value(), sources_manager, state, + Arguments{}.expect_builtin(builtin::Type::TUPLE, sources_manager)); if (value_result.is_invalid()) { return value_result; @@ -470,10 +379,8 @@ nodes::TypeCheckResult type_check_tuple_access(const nodes::Access &expression, expression, sources_manager); } -nodes::TypeCheckResult type_check_access(const nodes::Access &expression, - SourcesManager &sources_manager, - State &state, - const Arguments &arguments) { +Result check(const nodes::Access &expression, SourcesManager &sources_manager, + State &state, const Arguments &arguments) { switch (expression.get_type()) { case nodes::Access::ARRAY: return type_check_array_access(expression, sources_manager, state, @@ -484,48 +391,47 @@ nodes::TypeCheckResult type_check_access(const nodes::Access &expression, } } -nodes::TypeCheckResult -type_check_loop_control(const nodes::LoopControl &expression, - SourcesManager &sources_manager, State &, - const Arguments &arguments) { +Result check(const nodes::LoopControl &expression, + SourcesManager &sources_manager, State &, + const Arguments &arguments) { return type_check_from_arguments( - sources_manager.get_type_storage()->primitive_type( - builtin::types::Type::UNIT), - arguments, expression, sources_manager); + sources_manager.types()->primitive(builtin::Type::UNIT), arguments, + expression, sources_manager); } -nodes::TypeCheckResult -type_check_modifier_expression(const nodes::ModifierExpression &expression, - SourcesManager &sources_manager, State &state, - const Arguments &arguments) { - auto modified_result = type_check_expression( - *expression.get_expression(), sources_manager, state, Arguments{}); +Result check(const nodes::ModifierExpression &expression, + SourcesManager &sources_manager, State &state, + const Arguments &arguments) { + auto modified_result = + check(*expression.get_expression(), sources_manager, state, Arguments{}); if (modified_result.is_invalid()) { - return nodes::TypeCheckResult::construct_invalid_result(); + return Result::invalid(); } if (nodes::utils::is_suffix_modifier( expression.get_modifier())) { // optional, result - // '?' - open optional / result in -> (execute or not execute pattern - // matching expression) / (value / return) (TODO: alternative for bring) + // '?' - open optional / result in -> + // (execute or not execute pattern + // matching expression) / (value / + // return) (TODO: alternative for bring) // '!' - open optional / result -> value / panic switch (modified_result.get().get()->to_builtin()) { - case builtin::types::Type::OPTIONAL: - case builtin::types::Type::RESULT: + case builtin::Type::OPTIONAL: + case builtin::Type::RESULT: // TODO: how to unwrap external modifier ?? modified_result.set(modified_result.get().get()->get_parameter_proxy(0)); break; default: type_check_error("Can unwrap only Optional or Result", expression, sources_manager); - return nodes::TypeCheckResult::construct_invalid_result(); + return Result::invalid(); } } else { // TODO: check that modifier can be applied - modified_result.set(sources_manager.get_type_storage()->add_modification_of( + modified_result.set(sources_manager.types()->add_modification_of( modified_result.get(), expression.get_modifier())); } @@ -536,10 +442,9 @@ type_check_modifier_expression(const nodes::ModifierExpression &expression, // --- other // TODO -nodes::TypeCheckResult -type_check_name_expression(const nodes::NameExpression &expression, - SourcesManager &sources_manager, State &state, - const Arguments &arguments) { +Result check(const nodes::NameExpression &expression, + SourcesManager &sources_manager, State &state, + const Arguments &arguments) { // TODO: constraints ?? const auto name = expression.get_name(); @@ -565,10 +470,11 @@ type_check_name_expression(const nodes::NameExpression &expression, if (maybe_variable.has_value()) { auto &type = maybe_variable.value().type; for (size_t j = i + 1; j < fragments.size(); ++i) { - - if (j + 1 == fragments.size()) { // then this can be method call - // TODO: try to find method or local function - // if found, search to field (without error handling) + if (j + 1 == + fragments + .size()) { // then this can be method call + // TODO: try to find method or local function + // if found, search to field (without error handling) } // TODO: fields from several fragments ? (not acceptable fors methods / @@ -600,10 +506,10 @@ type_check_name_expression(const nodes::NameExpression &expression, // TODO: check, if there is variable with this name // TODO: check var + fields - const auto maybe_function_definition = find_name_definition_handle_errors( - *name->get(), expression, sources_manager); + const auto maybe_function_definition = + find_name_definition(*name->get(), expression, sources_manager); if (!maybe_function_definition.has_value()) { - return nodes::TypeCheckResult::construct_invalid_result(); + return Result::invalid(); } const nodes::FunctionDefinition *function_definition = maybe_function_definition.value(); @@ -624,13 +530,13 @@ type_check_name_expression(const nodes::NameExpression &expression, : ""} + ")", expression, sources_manager); - return nodes::TypeCheckResult::construct_invalid_result(); + return Result::invalid(); // TODO: try return correct type (function return type), when possible } // TODO: define types for generic function - std::vector function_argument_results; + std::vector function_argument_results; for (size_t i = 0; i < arguments_given; ++i) { // TODO: pass types with oud modifier const nodes::FunctionDefinition::Argument *argument = @@ -647,7 +553,6 @@ type_check_name_expression(const nodes::NameExpression &expression, const auto expected_annotation = argument->get_annotation(); if (annotation.has_value() != expected_annotation.has_value()) { - type_check_error("Wrong function argument annotation: should be " + std::string{expected_annotation.has_value() ? *expected_annotation.value() @@ -663,16 +568,16 @@ type_check_name_expression(const nodes::NameExpression &expression, *expression.get_argument_value(i), sources_manager); } - function_argument_results.push_back(type_check_expression( - *expression.get_argument_value(i), sources_manager, state, - Arguments{}.expect(argument->get_type_proxy().value()))); + function_argument_results.push_back( + check(*expression.get_argument_value(i), sources_manager, state, + Arguments{}.expect(argument->get_type_proxy().value()))); } if (function_definition->arguments_size() == 0) { type_check_error( "Function arguments size is zero. Returned type is not defined", expression, sources_manager); - return nodes::TypeCheckResult::construct_invalid_result(); + return Result::invalid(); } // TODO: check condition @@ -687,7 +592,7 @@ type_check_name_expression(const nodes::NameExpression &expression, type_check_error( "Function argument type is not defined for returned type", expression, sources_manager); - return nodes::TypeCheckResult::construct_invalid_result(); + return Result::invalid(); } // TODO: invert modifier ?? @@ -697,20 +602,21 @@ type_check_name_expression(const nodes::NameExpression &expression, } // checks for universal call syntax ?? + + // TODO: riturn result } // IN PROGRESS // TODO -nodes::TypeCheckResult -type_check_constructor(const nodes::Constructor &expression, - SourcesManager &sources_manager, State &state, - const Arguments &arguments) { +Result check(const nodes::Constructor &expression, + SourcesManager &sources_manager, State &state, + const Arguments &arguments) { // TODO: constraints ?? // TODO: use pass type - const auto maybe_type_definition = find_type_definition_handle_errors( + const auto maybe_type_definition = find_type_definition( *expression.get_type()->get_name()->get(), expression, sources_manager); if (!maybe_type_definition.has_value()) { - return nodes::TypeCheckResult::construct_invalid_result(); + return Result::invalid(); } const nodes::TypeDefinition *type_definition = maybe_type_definition.value(); @@ -718,7 +624,7 @@ type_check_constructor(const nodes::Constructor &expression, type_check_error( "Type defenition for constructor type not found (declaration only)", expression, sources_manager); - return nodes::TypeCheckResult::construct_invalid_result(); + return Result::invalid(); } // TODO: deal with anniotations, recursive annotations @@ -732,7 +638,7 @@ type_check_constructor(const nodes::Constructor &expression, if (expression.arguments_size() == 0) { type_check_error("Number of type constructor arguments should be > 0", expression, sources_manager); - return nodes::TypeCheckResult::construct_invalid_result(); + return Result::invalid(); // TODO: try return correct type (constructor's type), when possible (not // generic) } @@ -743,7 +649,7 @@ type_check_constructor(const nodes::Constructor &expression, { // check arguments size, ets. switch (builtin_type) { - case builtin::types::Type::TUPLE: + case builtin::Type::TUPLE: if (expression.arguments_size() != type.get()->parameters_size()) { type_check_error( "Number of type constructor arguments is different from expected " @@ -751,23 +657,23 @@ type_check_constructor(const nodes::Constructor &expression, std::to_string(expression.arguments_size()) + " instead of " + std::to_string(type.get()->parameters_size()) + ")", expression, sources_manager); - return nodes::TypeCheckResult::construct_invalid_result(); + return Result::invalid(); // TODO: try return correct type (constructor's type), when possible // (not generic) } break; - case builtin::types::Type::VARIANT: - case builtin::types::Type::OPTIONAL: - case builtin::types::Type::RESULT: - case builtin::types::Type::ERROR: - case builtin::types::Type::FUNCTION: - case builtin::types::Type::NONE: + case builtin::Type::VARIANT: + case builtin::Type::OPTIONAL: + case builtin::Type::RESULT: + case builtin::Type::ERROR: + case builtin::Type::FUNCTION: + case builtin::Type::NONE: if (expression.arguments_size() != 1) { // TODO: better to_string type_check_error("Number of type constructor arguments should be = 1 " "(builtin type " + std::to_string(uint(builtin_type)) + ")", expression, sources_manager); - return nodes::TypeCheckResult::construct_invalid_result(); + return Result::invalid(); // TODO: try return correct type (constructor's type), when possible // (not generic) } @@ -776,13 +682,13 @@ type_check_constructor(const nodes::Constructor &expression, break; } - if (get_parameters_count(builtin_type).has_value() && + if (builtin::types::get_parameters_count(builtin_type).has_value() && type.get()->parameters_size() != - get_parameters_count(builtin_type).value()) { + builtin::types::get_parameters_count(builtin_type).value()) { type_check_error("Wrong amount of parametars for builtin type", expression, sources_manager); - return nodes::TypeCheckResult::construct_invalid_result(); + return Result::invalid(); // TODO: try return correct type (constructor's type), when possible (not // generic) } @@ -841,13 +747,13 @@ type_check_constructor(const nodes::Constructor &expression, }; switch (builtin_type) { - case builtin::types::Type::TUPLE: + case builtin::Type::TUPLE: for (size_t i = 0; i < expression.arguments_size(); ++i) { check_same_annotation(i, type.get()->get_parameter(i)->get_annotation(), true /*log errors*/); } break; - case builtin::types::Type::VARIANT: + case builtin::Type::VARIANT: // more then one same annotation ?? for (size_t i = 0; i < type.get()->parameters_size(); ++i) { if (check_same_annotation( @@ -865,14 +771,14 @@ type_check_constructor(const nodes::Constructor &expression, *expression.get_argument_value(0), sources_manager); } break; - case builtin::types::Type::ERROR: // no anotations ?? + case builtin::Type::ERROR: // no anotations ?? check_same_annotation(0, type.get()->get_parameter(0)->get_annotation(), true /*log errors*/); break; - case builtin::types::Type::OPTIONAL: - case builtin::types::Type::RESULT: - case builtin::types::Type::FUNCTION: - case builtin::types::Type::NONE: + case builtin::Type::OPTIONAL: + case builtin::Type::RESULT: + case builtin::Type::FUNCTION: + case builtin::Type::NONE: check_no_annotation(0, true /*log errors*/); break; default: // array, basic types @@ -882,58 +788,51 @@ type_check_constructor(const nodes::Constructor &expression, { // type check arguments switch (builtin_type) { - case builtin::types::Type::TUPLE: + case builtin::Type::TUPLE: for (size_t i = 0; i < expression.arguments_size(); ++i) { - type_check_expression( - *expression.get_argument_value(i), sources_manager, state, - Arguments{}.expect(type.get()->get_parameter_proxy(i))); + check(*expression.get_argument_value(i), sources_manager, state, + Arguments{}.expect(type.get()->get_parameter_proxy(i))); } break; - case builtin::types::Type::VARIANT: + case builtin::Type::VARIANT: if (chosen_variant_option.has_value()) { - type_check_expression( - *expression.get_argument_value(0), sources_manager, state, - Arguments{}.expect(type.get()->get_parameter_proxy( - chosen_variant_option.value()))); + check(*expression.get_argument_value(0), sources_manager, state, + Arguments{}.expect(type.get()->get_parameter_proxy( + chosen_variant_option.value()))); } else { // TODO: error, if there is more then one possible variant in // answer nodes::TypeProxies possible_options; for (size_t i = 0; i < type.get()->parameters_size(); ++i) { possible_options.push_back(type.get()->get_parameter_proxy(i)); } - type_check_expression(*expression.get_argument_value(0), - sources_manager, state, - Arguments{}.expect(possible_options)); + check(*expression.get_argument_value(0), sources_manager, state, + Arguments{}.expect(possible_options)); } break; - case builtin::types::Type::OPTIONAL: + case builtin::Type::OPTIONAL: // first parameter or NULL - type_check_expression( - *expression.get_argument_value(0), sources_manager, state, - Arguments{}.expect( - {type.get()->get_parameter_proxy(0), - sources_manager.get_type_storage()->primitive_type( - builtin::types::Type::NULL_OPTION)})); + check(*expression.get_argument_value(0), sources_manager, state, + Arguments{}.expect({type.get()->get_parameter_proxy(0), + sources_manager.types()->primitive( + builtin::Type::NULL_OPTION)})); break; - case builtin::types::Type::RESULT: + case builtin::Type::RESULT: // first parameter or ERROR[second parameter] - type_check_expression( - *expression.get_argument_value(0), sources_manager, state, - Arguments{}.expect({type.get()->get_parameter_proxy(0), - sources_manager.get_type_storage()->add_error_of( - type.get()->get_parameter_proxy(1))})); + check(*expression.get_argument_value(0), sources_manager, state, + Arguments{}.expect({type.get()->get_parameter_proxy(0), + sources_manager.types()->add_error_of( + type.get()->get_parameter_proxy(1))})); break; - case builtin::types::Type::ERROR: + case builtin::Type::ERROR: // first parameter - type_check_expression( - *expression.get_argument_value(0), sources_manager, state, - Arguments{}.expect(type.get()->get_parameter_proxy(0))); + check(*expression.get_argument_value(0), sources_manager, state, + Arguments{}.expect(type.get()->get_parameter_proxy(0))); break; - case builtin::types::Type::FUNCTION: - case builtin::types::Type::NONE: + case builtin::Type::FUNCTION: + case builtin::Type::NONE: // type itself - type_check_expression(*expression.get_argument_value(0), sources_manager, - state, Arguments{}.expect(type)); + check(*expression.get_argument_value(0), sources_manager, state, + Arguments{}.expect(type)); break; default: // array, basic types type_check_error("Type can't be constructed", expression, @@ -950,10 +849,8 @@ type_check_constructor(const nodes::Constructor &expression, } // IN PROGRESS // TODO -nodes::TypeCheckResult type_check_lambda(const nodes::Lambda &expression, - SourcesManager &sources_manager, - State &state, - const Arguments &arguments) { +Result check(const nodes::Lambda &expression, SourcesManager &sources_manager, + State &state, const Arguments &arguments) { if (arguments.get_expected().empty()) { type_check_error("Can't deduce type of lambda function from context: no " "one type expected", @@ -968,7 +865,7 @@ nodes::TypeCheckResult type_check_lambda(const nodes::Lambda &expression, } const auto expected_type = arguments.get_expected().front(); - if (!expected_type.get()->is_builtin(builtin::types::Type::FUNCTION)) { + if (!expected_type.get()->is_builtin(builtin::Type::FUNCTION)) { type_check_error("Type of lambda function should be function", expression, sources_manager); } @@ -1002,10 +899,9 @@ nodes::TypeCheckResult type_check_lambda(const nodes::Lambda &expression, // TODO: out type is can be not last if (arguments_given + 1 == arguments_defined) { - type_check_expression( - *expression.get_expression(), sources_manager, state, - Arguments{}.expect( - expected_type.get()->get_parameter_proxy(arguments_defined - 1))); + check(*expression.get_expression(), sources_manager, state, + Arguments{}.expect( + expected_type.get()->get_parameter_proxy(arguments_defined - 1))); } // TODO: needed ?? (only passed type check required ??) @@ -1013,4 +909,16 @@ nodes::TypeCheckResult type_check_lambda(const nodes::Lambda &expression, sources_manager); } // IN PROGRESS +Result check(const nodes::Extra &, SourcesManager &sources_manager, State &, + const Arguments &) { + + return Result(sources_manager.types()->primitive(builtin::Type::UNIT)); +} + +Result check(const nodes::EmptyLines &, SourcesManager &sources_manager, + State &, const Arguments &) { + + return Result(sources_manager.types()->primitive(builtin::Type::UNIT)); +} + } // namespace type_check diff --git a/src/printers/basic_printers.cpp b/src/printers/basic_printers.cpp index 8b39a3b..de018d6 100644 --- a/src/printers/basic_printers.cpp +++ b/src/printers/basic_printers.cpp @@ -7,8 +7,8 @@ namespace printers { -void print_modifier(const nodes::Modifier &modifier, Printer &printer, - bool const_is_none) { +void print(const nodes::Modifier &modifier, Printer &printer, + bool const_is_none) { switch (modifier) { case nodes::Modifier::IN: printer.print(printer.print_words_instead_of_symbols() ? "in " : "<- "); @@ -85,7 +85,7 @@ void print_modifier(const nodes::Modifier &modifier, Printer &printer, } } -void print_literal(const nodes::Literal &literal, Printer &printer) { +void print(const nodes::Literal &literal, Printer &printer) { switch (literal.get_any()->index()) { case 0: // float printer.print(std::to_string(*literal.get().value())); @@ -141,7 +141,7 @@ void print_literal(const nodes::Literal &literal, Printer &printer) { exit(1); // unreachable } -void print_identifier(const nodes::Identifier &identifier, Printer &printer) { +void print(const nodes::Identifier &identifier, Printer &printer) { printer.print(*identifier.get()); } @@ -150,11 +150,11 @@ void print_annotation(const std::string &annotation, Printer &printer) { printer.print(annotation); } -void print_extra(const nodes::Extra &extra, Printer &printer) { +void print(const nodes::Extra &extra, Printer &printer) { printer.print(*extra.content()); } -void print_empty_lines(const nodes::EmptyLines &empty_lines, Printer &printer) { +void print(const nodes::EmptyLines &empty_lines, Printer &printer) { for (size_t i = 0; i < empty_lines.line_count(); ++i) { printer.new_indent_line(); } diff --git a/src/printers/doc_printers.cpp b/src/printers/doc_printers.cpp index 4f23c9f..e596978 100644 --- a/src/printers/doc_printers.cpp +++ b/src/printers/doc_printers.cpp @@ -6,7 +6,7 @@ namespace printers { // TODO -void print_docs(const nodes::SymbolDocs &docs, Printer &printer) { +void print(const nodes::SymbolDocs &docs, Printer &printer) { auto description = docs.get_description(); if (description.has_value()) { diff --git a/src/printers/expression_printers.cpp b/src/printers/expression_printers.cpp index 3b9beeb..659e2f1 100644 --- a/src/printers/expression_printers.cpp +++ b/src/printers/expression_printers.cpp @@ -16,68 +16,13 @@ bool is_block_expression(const nodes::Expression &expression) { } // namespace utils -void print_expression(const nodes::Expression &expression, - printers::Printer &printer) { +void print(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; - // --- empty lines - case 13: // Extra - print_extra(*expression.get().value(), printer); - break; - case 14: // EmptyLines - print_empty_lines(*expression.get().value(), printer); - break; - } + std::visit([&printer](const auto &arg) -> void { print(arg, printer); }, + *expression.get_any()); if (expression.is_scoped()) { printer.print(")"); @@ -86,7 +31,7 @@ void print_expression(const nodes::Expression &expression, // --- flow control -void print_case(const nodes::Match::Case &expression, Printer &printer) { +void print(const nodes::Match::Case &expression, Printer &printer) { switch (expression.case_type()) { case nodes::Match::Case::PATTERN_VALUE: @@ -99,21 +44,21 @@ void print_case(const nodes::Match::Case &expression, Printer &printer) { printer.space(); - print_expression(*expression.get_value(), printer); + print(*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); + print(*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); + print(*expression.get_expression().value(), printer); } } // IN PROGRESS -void print_match(const nodes::Match &expression, printers::Printer &printer) { - print_expression(*expression.get_value(), printer); +void print(const nodes::Match &expression, printers::Printer &printer) { + print(*expression.get_value(), printer); printer.space(); @@ -122,7 +67,7 @@ void print_match(const nodes::Match &expression, printers::Printer &printer) { printer.set_indentation_level(printer.current_position()); for (size_t i = 0; i < expression.cases_size(); ++i) { - print_case(*expression.get_case(i), printer); + print(*expression.get_case(i), printer); if (i + 1 < expression.cases_size()) { printer.new_indent_line(); @@ -133,8 +78,7 @@ void print_match(const nodes::Match &expression, printers::Printer &printer) { } // IN PROGRESS -void print_condition(const nodes::Condition &expression, - printers::Printer &printer) { +void print(const nodes::Condition &expression, printers::Printer &printer) { for (size_t i = 0; i < expression.cases_size(); ++i) { if (i > 0) { @@ -151,11 +95,11 @@ void print_condition(const nodes::Condition &expression, printer.print(printer.print_words_instead_of_symbols() ? "elif " : "!! "); } - print_expression(*expression.get_case(i).first, printer); + print(*expression.get_case(i).first, printer); printer.print(printer.print_words_instead_of_symbols() ? " do " : " => "); - print_expression(*expression.get_case(i).second, printer); + print(*expression.get_case(i).second, printer); } if (expression.cases_size() == 0) { @@ -171,11 +115,11 @@ void print_condition(const nodes::Condition &expression, printer.new_indent_line(); } printer.print(printer.print_words_instead_of_symbols() ? "else " : "!!=> "); - print_expression(*expression.get_else_case().value(), printer); + print(*expression.get_else_case().value(), printer); } } -void print_loop(const nodes::Loop &expression, printers::Printer &printer) { +void print(const nodes::Loop &expression, printers::Printer &printer) { printer.print(printer.print_words_instead_of_symbols() ? "for" : "@"); switch (expression.get_type()) { @@ -184,27 +128,26 @@ void print_loop(const nodes::Loop &expression, printers::Printer &printer) { break; case nodes::Loop::WHILE: printer.space(); - print_expression(*expression.get_condition().value(), printer); + print(*expression.get_condition().value(), printer); printer.space(); break; case nodes::Loop::FOR: printer.space(); - print_expression(*expression.get_variable().value(), printer); + print(*expression.get_variable().value(), printer); printer.print(" : "); - print_expression(*expression.get_interval().value(), printer); + print(*expression.get_interval().value(), printer); printer.space(); break; } printer.print(printer.print_words_instead_of_symbols() ? "do " : "=> "); - print_expression(*expression.get_expression(), printer); + print(*expression.get_expression(), printer); } // IN PROGRESS // --- containers -void print_container(const nodes::Container &expression, - printers::Printer &printer) { +void print(const nodes::Container &expression, printers::Printer &printer) { bool is_array = expression.get_type() == nodes::Container::ARRAY; if (is_array) { @@ -224,7 +167,7 @@ void print_container(const nodes::Container &expression, if (!is_array && !is_empty_lines) { printer.new_indent_line(); } - print_expression(*expression.get_expression(i), printer); + print(*expression.get_expression(i), printer); if (is_array) { if (i + 1 < expression.expressions_size()) { printer.space(); @@ -247,7 +190,7 @@ void print_container(const nodes::Container &expression, // --- modifiers -void print_return(const nodes::Return &expression, printers::Printer &printer) { +void print(const nodes::Return &expression, printers::Printer &printer) { switch (expression.get_type()) { case nodes::Return::RETURN: @@ -260,11 +203,11 @@ void print_return(const nodes::Return &expression, printers::Printer &printer) { break; } - print_expression(*expression.get_expression(), printer); + print(*expression.get_expression(), printer); } -void print_name_definition(const nodes::NameDefinition &expression, - printers::Printer &printer) { +void print(const nodes::NameDefinition &expression, + printers::Printer &printer) { if (printer.print_words_instead_of_symbols()) { switch (expression.get_modifier()) { @@ -290,11 +233,11 @@ void print_name_definition(const nodes::NameDefinition &expression, } } - print_identifier(*expression.get_name(), printer); + print(*expression.get_name(), printer); } -void print_access(const nodes::Access &expression, printers::Printer &printer) { - print_expression(*expression.get_value(), printer); +void print(const nodes::Access &expression, printers::Printer &printer) { + print(*expression.get_value(), printer); switch (expression.get_type()) { case nodes::Access::ARRAY: @@ -307,7 +250,7 @@ void print_access(const nodes::Access &expression, printers::Printer &printer) { break; } - print_expression(*expression.get_index(), printer); + print(*expression.get_index(), printer); switch (expression.get_type()) { case nodes::Access::ARRAY: @@ -320,8 +263,7 @@ void print_access(const nodes::Access &expression, printers::Printer &printer) { } } -void print_loop_control(const nodes::LoopControl &expression, - printers::Printer &printer) { +void print(const nodes::LoopControl &expression, printers::Printer &printer) { switch (expression.get_type()) { case nodes::LoopControl::BREAK: printer.print("break"); @@ -334,30 +276,30 @@ void print_loop_control(const nodes::LoopControl &expression, } } -void print_modifier_expression(const nodes::ModifierExpression &expression, - printers::Printer &printer) { +void print(const nodes::ModifierExpression &expression, + printers::Printer &printer) { if (expression.get_modifier() != nodes::Modifier::OPTIONAL && expression.get_modifier() != nodes::Modifier::RESULT) { - print_modifier(expression.get_modifier(), printer); + print(expression.get_modifier(), printer); } - print_expression(*expression.get_expression(), printer); + print(*expression.get_expression(), printer); if (expression.get_modifier() == nodes::Modifier::OPTIONAL || expression.get_modifier() == nodes::Modifier::RESULT) { - print_modifier(expression.get_modifier(), printer); + print(expression.get_modifier(), printer); } } // --- other -void print_name_expression(const nodes::NameExpression &expression, - printers::Printer &printer) { +void print(const nodes::NameExpression &expression, + printers::Printer &printer) { bool is_comma_operator = (*expression.get_name()->get() == ","); bool is_range_operator = (*expression.get_name()->get() == ".."); if (expression.is_operator_call() || expression.is_point_call()) { - print_expression(*expression.get_argument_value(0), printer); + print(*expression.get_argument_value(0), printer); if (expression.is_point_call()) { printer.print("."); @@ -366,7 +308,7 @@ void print_name_expression(const nodes::NameExpression &expression, printer.space(); } } else if (expression.get_prefix().has_value()) { - print_type(*expression.get_prefix().value(), printer); + print(*expression.get_prefix().value(), printer); printer.print("."); } @@ -380,7 +322,7 @@ void print_name_expression(const nodes::NameExpression &expression, printer.print("( "); } - print_identifier(*expression.get_name(), printer); + print(*expression.get_name(), printer); if (operator_called_as_function) { printer.print(" )"); @@ -399,14 +341,13 @@ void print_name_expression(const nodes::NameExpression &expression, print_annotation(*expression.get_argument_annotation(i).value(), printer); printer.space(); } - print_expression(*expression.get_argument_value(i), printer); + print(*expression.get_argument_value(i), printer); } } // IN PROGRESS -void print_constructor(const nodes::Constructor &expression, - printers::Printer &printer) { - print_type(*expression.get_type(), printer); +void print(const nodes::Constructor &expression, printers::Printer &printer) { + print(*expression.get_type(), printer); for (size_t i = 0; i < expression.arguments_size(); ++i) { printer.space(); @@ -416,22 +357,22 @@ void print_constructor(const nodes::Constructor &expression, printer.space(); } - print_expression(*expression.get_argument_value(i), printer); + print(*expression.get_argument_value(i), printer); } } // IN PROGRESS -void print_lambda(const nodes::Lambda &expression, printers::Printer &printer) { +void print(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); + print(*expression.get_argument(i), printer); printer.space(); } printer.print(printer.print_words_instead_of_symbols() ? "do " : "=> "); - print_expression(*expression.get_expression(), printer); + print(*expression.get_expression(), printer); } // IN PROGRESS diff --git a/src/printers/statement_printers.cpp b/src/printers/statement_printers.cpp index 3be4d18..1b2083f 100644 --- a/src/printers/statement_printers.cpp +++ b/src/printers/statement_printers.cpp @@ -10,48 +10,27 @@ namespace printers { -void print_source_file(const std::vector &statements, - Printer &printer) { - for (auto &statement : statements) { - print_statement(statement, printer); - } +// void print_source_file(const std::vector &statements, +// Printer &printer) { +// for (const auto &statement : statements) { +// print(statement, printer); +// } +// } + +void print(const nodes::Statement &statement, Printer &printer) { + std::visit([&printer](const auto &arg) -> void { print(arg, printer); }, + *statement.get_any()); } -void print_statement(const nodes::Statement &statement, Printer &printer) { - switch (statement.get_any()->index()) { - case 0: // Import - print_import(*statement.get().value(), printer); - printer.new_indent_line(); - break; - case 1: // TypeDefinition - print_type_definition(*statement.get().value(), - printer); - printer.new_indent_line(); - break; - case 2: // FunctionDefinition - print_function_definition( - *statement.get().value(), printer); - printer.new_indent_line(); - break; - case 3: // Extra - print_extra(*statement.get().value(), printer); - printer.new_indent_line(); - break; - case 4: // EmptyLines - print_empty_lines(*statement.get().value(), printer); - break; - } -} - -void print_import(const nodes::Import &statement, Printer &printer) { +void print(const nodes::Import &statement, Printer &printer) { printer.print(":: "); - print_identifier(*statement.get_import_name(), printer); + print(*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); + print(*statement.get_module_name(), printer); } if (statement.symbols_size() > 0) { @@ -66,7 +45,7 @@ void print_import(const nodes::Import &statement, Printer &printer) { printer.print("( "); } - print_identifier(*statement.get_symbol(i), printer); + print(*statement.get_symbol(i), printer); if (identifier_is_operator) { printer.print(" )"); @@ -76,25 +55,24 @@ void print_import(const nodes::Import &statement, Printer &printer) { printer.print(";"); } // IN PROGRESS -void print_constraint(const nodes::Constraint &statement, Printer &printer) { +void print(const nodes::Constraint &statement, Printer &printer) { printer.print("? "); - print_expression(*statement.get_expression(), printer); + print(*statement.get_expression(), printer); printer.print(";"); } -void print_type_definition(const nodes::TypeDefinition &statement, - Printer &printer) { - print_docs(*statement.get_docs(), printer); +void print(const nodes::TypeDefinition &statement, Printer &printer) { + print(*statement.get_docs(), printer); if (statement.is_on_heap()) { printer.print("<> "); } - print_identifier(*statement.get_name(), printer); + print(*statement.get_name(), printer); for (size_t i = 0; i < statement.arguments_size(); ++i) { printer.space(); - print_identifier(*statement.get_argument(i), printer); + print(*statement.get_argument(i), printer); } if (statement.get_type().has_value()) { @@ -104,7 +82,7 @@ void print_type_definition(const nodes::TypeDefinition &statement, printer.set_indentation_level(printer.get_current_position() - 2); - print_type(*statement.get_type().value().get(), printer); + print(*statement.get_type().value().get(), printer); printer.set_indentation_level(previous_indentation_level); } @@ -112,12 +90,11 @@ void print_type_definition(const nodes::TypeDefinition &statement, } // IN PROGRESS // TODO: do not print prefix type for names -void print_function_definition(const nodes::FunctionDefinition &statement, - Printer &printer) { - print_docs(*statement.get_docs(), printer); +void print(const nodes::FunctionDefinition &statement, Printer &printer) { + print(*statement.get_docs(), printer); for (size_t i = 0; i < statement.constraints_size(); ++i) { - print_constraint(*statement.get_constraint(i), printer); + print(*statement.get_constraint(i), printer); printer.new_indent_line(); } @@ -132,13 +109,13 @@ void print_function_definition(const nodes::FunctionDefinition &statement, printer.print("( "); } - print_identifier(*statement.get_name(), printer); + print(*statement.get_name(), printer); if (identifier_is_operator) { printer.print(" )"); } - print_modifier(statement.get_return_modifier(), printer); // ! or ? + print(statement.get_return_modifier(), printer); // ! or ? for (size_t i = 0; i < statement.arguments_size(); ++i) { if (!statement.get_argument(i)->get_name().has_value()) { @@ -158,15 +135,14 @@ void print_function_definition(const nodes::FunctionDefinition &statement, printer.space(); } - print_modifier(statement.get_argument(i)->get_before_modifier(), printer, - true); + print(statement.get_argument(i)->get_before_modifier(), printer, true); } - print_identifier(*statement.get_argument(i)->get_name().value(), printer); + print(*statement.get_argument(i)->get_name().value(), printer); // 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); + print(statement.get_argument(i)->get_after_modifier(), printer); } } @@ -184,10 +160,9 @@ void print_function_definition(const nodes::FunctionDefinition &statement, printer.space(); } - print_modifier(statement.get_argument(i)->get_before_modifier(), printer, - true); + print(statement.get_argument(i)->get_before_modifier(), printer, true); - print_type(*statement.get_argument(i)->get_type().value(), printer); + print(*statement.get_argument(i)->get_type().value(), printer); } } @@ -201,7 +176,7 @@ void print_function_definition(const nodes::FunctionDefinition &statement, if (!expression_is_container) { printer.set_indentation_level(printer.current_position()); } - print_expression(*statement.get_expression().value(), printer); + print(*statement.get_expression().value(), printer); if (!expression_is_container) { printer.set_indentation_level(previous_indentation_level); printer.print(";"); diff --git a/src/printers/type_printers.cpp b/src/printers/type_printers.cpp index 75b6ad3..4d0ad1e 100644 --- a/src/printers/type_printers.cpp +++ b/src/printers/type_printers.cpp @@ -6,22 +6,22 @@ namespace printers { // TODO: better printing format for builtin types -void print_type(const nodes::Type &type, printers::Printer &printer) { +void print(const nodes::Type &type, printers::Printer &printer) { if (type.has_annotation()) { print_annotation(*type.get_annotation().value(), printer); printer.space(); } if (type.get_modifier() != nodes::Modifier::CONST) { - print_modifier(type.get_modifier(), printer); + print(type.get_modifier(), printer); } - print_identifier(*type.get_name(), printer); + print(*type.get_name(), printer); if (type.parameters_size() > 0) { printer.print("["); for (size_t i = 0; i < type.parameters_size(); ++i) { - print_type(*type.get_parameter(i), printer); + print(*type.get_parameter(i), printer); if (i + 1 < type.parameters_size()) { printer.space(); } diff --git a/src/type_check_utils.cpp b/src/type_check_utils.cpp index 7eb9ef7..be09626 100644 --- a/src/type_check_utils.cpp +++ b/src/type_check_utils.cpp @@ -18,8 +18,7 @@ nodes::TypeProxy check_same_to_pass_type_in_arguments( type_check_error(message, node, sources_manager, handle_errors); } - return sources_manager.get_type_storage()->primitive_type( - builtin::types::Type::BOOL); + return sources_manager.types()->primitive(builtin::Type::BOOL); } bool check_no_pass_type_in_arguments(const Arguments &arguments, @@ -35,14 +34,14 @@ bool check_no_pass_type_in_arguments(const Arguments &arguments, return true; } -nodes::TypeCheckResult -type_same_to_expected(nodes::TypeProxy type, const Arguments &arguments, - const nodes::Node &node, SourcesManager &sources_manager, - const std::string &message, bool handle_errors) { +Result type_same_to_expected(nodes::TypeProxy type, const Arguments &arguments, + const nodes::Node &node, + SourcesManager &sources_manager, + const std::string &message, bool handle_errors) { const auto &expected = arguments.get_expected(); if (expected.empty()) { - return nodes::TypeCheckResult{type}; + return Result{type}; } // TODO: use 'can cast to' (for modifiers), instead '==' @@ -53,15 +52,15 @@ type_same_to_expected(nodes::TypeProxy type, const Arguments &arguments, type_check_error(message, node, sources_manager, handle_errors); } - return nodes::TypeCheckResult{expected.front()}; // any can be choosen + return Result{expected.front()}; // any can be choosen } template -std::optional find_statement_handle_errors( +std::optional find_statement( const std::string &name, const nodes::Node &node, SourcesManager &sources_manager, const std::string &message_not_found, const std::string &message_different_statement, bool handle_errors) { - const auto maybe_any_statement = sources_manager.get_name_tree()->find(name); + const auto maybe_any_statement = sources_manager.names()->find(name); if (!maybe_any_statement.has_value()) { type_check_error(message_not_found, node, sources_manager, handle_errors); return std::nullopt; @@ -77,28 +76,26 @@ std::optional find_statement_handle_errors( return maybe_statement.value(); } -std::optional find_type_definition_handle_errors( - const std::string &name, const nodes::Node &node, - SourcesManager &sources_manager, bool handle_errors) { +std::optional +find_type_definition(const std::string &name, const nodes::Node &node, + SourcesManager &sources_manager, bool handle_errors) { return find_statement_handle_errors( name, node, sources_manager, "No type definition found in name tree", "Node in name tree is not type definition", handle_errors); } std::optional -find_name_definition_handle_errors(const std::string &name, - const nodes::Node &node, - SourcesManager &sources_manager, - bool handle_errors) { +find_name_definition(const std::string &name, const nodes::Node &node, + SourcesManager &sources_manager, bool handle_errors) { return find_statement_handle_errors( name, node, sources_manager, "No name definition found in name tree", "Node in name tree is not name definition", handle_errors); } -std::optional unfold_user_defined_type_handle_errors( - nodes::TypeProxy type, const nodes::Node &node, - SourcesManager &sources_manager, bool handle_errors) { - const auto maybe_type_definition = find_type_definition_handle_errors( +std::optional +unfold_user_defined_type(nodes::TypeProxy type, const nodes::Node &node, + SourcesManager &sources_manager, bool handle_errors) { + const auto maybe_type_definition = find_type_definition( *type.get()->get_name()->get(), node, sources_manager, handle_errors); if (!maybe_type_definition.has_value()) { @@ -120,11 +117,12 @@ std::optional unfold_user_defined_type_handle_errors( return maybe_type_definition.value()->get_type().value(); } -std::optional get_field_type_by_name_handle_errors( - nodes::TypeProxy type, const std::string &field, const nodes::Node &node, - SourcesManager &sources_manager, bool handle_errors) { +std::optional +get_field_type_by_name(nodes::TypeProxy type, const std::string &field, + const nodes::Node &node, SourcesManager &sources_manager, + bool handle_errors) { switch (type.get()->to_builtin()) { - case builtin::types::Type::TUPLE: { // access field + case builtin::Type::TUPLE: { // access field const auto maybe_field = type.get()->get_parameter_proxy_by_name(field); @@ -136,19 +134,18 @@ std::optional get_field_type_by_name_handle_errors( } return maybe_field.value(); } - case builtin::types::Type::NONE: { // user defined type, trying to unfold, and - // then repeat access + case builtin::Type::NONE: { // user defined type, trying to unfold, and + // then repeat access // remove recursion ?? - const auto maybe_internal_type = unfold_user_defined_type_handle_errors( - type, node, sources_manager, handle_errors); + const auto maybe_internal_type = + unfold_user_defined_type(type, node, sources_manager, handle_errors); if (!maybe_internal_type.has_value()) { return std::nullopt; } - return get_field_type_by_name_handle_errors(maybe_internal_type.value(), - field, node, sources_manager, - handle_errors); + return get_field_type_by_name(maybe_internal_type.value(), field, node, + sources_manager, handle_errors); } default: // variant, function, optional, result, error (TODO: add message // field?), array (TODO: add length field ?), basic types @@ -167,9 +164,8 @@ void type_check_error(const std::string &message, const nodes::Node &node, return; } - sources_manager.get_error_log()->add_error( - error_handling::ErrorLog::ErrorMessage( - node, message, error_handling::ErrorType::TYPE_CHECK)); + sources_manager.errors()->add_error(error_handling::ErrorLog::ErrorMessage( + node, message, error_handling::ErrorType::TYPE_CHECK)); } } // namespace type_check