From ffa9c47107d6af91528cf25aacb6cdd89710be3f Mon Sep 17 00:00:00 2001 From: ProgramSnail Date: Wed, 3 Jan 2024 21:55:24 +0300 Subject: [PATCH] es_builtin for type, type utils state fixes --- include/nodes/type_nodes.hpp | 4 ++- include/type_check_utils.hpp | 63 ++++++++++++++++++++++++++--------- src/expression_type_check.cpp | 23 +++++++------ 3 files changed, 63 insertions(+), 27 deletions(-) diff --git a/include/nodes/type_nodes.hpp b/include/nodes/type_nodes.hpp index 1c546e5..8e7b9df 100644 --- a/include/nodes/type_nodes.hpp +++ b/include/nodes/type_nodes.hpp @@ -26,7 +26,7 @@ public: const Type *get() const; - bool operator==(const TypeProxy& other) const; + bool operator==(const TypeProxy &other) const; private: TypeProxy(TypeStorage &type_storage, size_t id) @@ -191,6 +191,8 @@ public: return builtin_type; } + bool is_builtin(builtin::types::Type type) { return to_builtin() == type; } + private: Identifier name_; std::vector parameters_; diff --git a/include/type_check_utils.hpp b/include/type_check_utils.hpp index d802a56..55e7e96 100644 --- a/include/type_check_utils.hpp +++ b/include/type_check_utils.hpp @@ -42,8 +42,8 @@ public: "Set brought type to contexts_ with zero elements in State"); } auto &brought_type = contexts_.back().brought_type; - if (brought_type.has_value() &&) { - // TODO + if (brought_type.has_value() && + type != brought_type.value()) { // check inheritance, etc ?? return false; } brought_type = type; @@ -56,8 +56,8 @@ public: "Set returned type to contexts_ with zero elements in State"); } auto &returned_type = contexts_.back().returned_type; - if (returned_type.has_value() &&) { - // TODO + if (returned_type.has_value() && + type != returned_type.value()) { // check inheritance, etc ?? return false; } returned_type = type; @@ -65,7 +65,10 @@ public: } private: - void enter_context(const nodes::Node &node) { contexts_.emplace_back(node); } + void enter_context(const nodes::Node &node, + error_handling::ErrorLog &error_log) { + contexts_.emplace_back(node, error_log); + } // returns brought type, return type is merged with next context or with // brought type in last context @@ -75,14 +78,33 @@ private: "Pop from contexts_ with zero elements in State"); } - const auto brought_type = contexts_.back().brought_type; - const auto returned_type = contexts_.back().returned_type; + auto context = std::move(contexts_.back()); contexts_.pop_back(); - if (contexts_.empty()) { - // TODO: merge returned and brought types - } else { - // TODO: merge to previous + auto &brought_type = context.brought_type; + const auto &returned_type = context.returned_type; + + if (returned_type.has_value()) { + if (contexts_.empty()) { + if (brought_type.has_value()) { + if (returned_type.value() != brought_type.value()) { + context.log_typecheck_error( + "Different returned and brought type in last context"); + } + } else { + brought_type = returned_type.value(); + } + } else { + auto &previous_returned_type = contexts_.back().returned_type; + if (previous_returned_type.has_value()) { + if (returned_type.value() != previous_returned_type.value()) { + context.log_typecheck_error( + "Different returned type in this context and previous one"); + } + } else { + previous_returned_type = returned_type.value(); + } + } } return brought_type; @@ -91,16 +113,25 @@ private: public: class Context { public: - Context(const nodes::Node &node) : node(node) {} + Context(const nodes::Node &node, error_handling::ErrorLog &error_log) + : node(node), error_log(error_log) {} + + void log_typecheck_error( + const std::string &message = "Context typecheck error") { + error_log.add_error(error_handling::ErrorLog::ErrorMessage( + node, message, error_handling::ErrorType::TYPE_CHECK)); + } public: nodes::MaybeTypeProxy brought_type; nodes::MaybeTypeProxy returned_type; std::unordered_map variables; + + private: const nodes::Node &node; + error_handling::ErrorLog &error_log; }; -private: std::vector contexts_ = {{}}; }; @@ -111,8 +142,10 @@ public: class ContextHolder { public: - ContextHolder(State &state, const nodes::Node &node) : state(state) { - state.enter_context(node); + ContextHolder(State &state, const nodes::Node &node, + error_handling::ErrorLog &error_log) + : state(state) { + state.enter_context(node, error_log); } ContextHolder(const ContextHolder &) = delete; diff --git a/src/expression_type_check.cpp b/src/expression_type_check.cpp index 4cfd69d..7bbe11d 100644 --- a/src/expression_type_check.cpp +++ b/src/expression_type_check.cpp @@ -120,8 +120,8 @@ nodes::TypeCheckResult type_check_loop(const nodes::Loop &expression, return condition_result.value(); } - if (condition_result.value().get().get()->to_builtin() != - builtin::types::Type::BOOL) { + if (!condition_result.value().get().get()->is_builtin( + builtin::types::Type::BOOL)) { sources_manager.get_error_log()->add_error( error_handling::ErrorLog::ErrorMessage( *expression.get_condition().value(), @@ -145,8 +145,9 @@ nodes::TypeCheckResult type_check_loop(const nodes::Loop &expression, } // // TODO ?? - // if (variable_result.value().get().get_type()->to_builtin() != - // builtin::types::Type::BOOL) { + // if + // (!variable_result.value().get().get_type()->is_builtin(builtin::types::Type::BOOL)) + // { // sources_manager.get_error_log()->add_error( // error_handling::ErrorLog::ErrorMessage( // *expression.get_condition().value(), @@ -156,8 +157,8 @@ nodes::TypeCheckResult type_check_loop(const nodes::Loop &expression, // } // TODO: ranges ?? - if (condition_result.value().get().get()->to_builtin() != - builtin::types::Type::ARRAY) { + if (!condition_result.value().get().get()->is_builtin( + builtin::types::Type::ARRAY)) { sources_manager.get_error_log()->add_error( error_handling::ErrorLog::ErrorMessage( *expression.get_condition().value(), @@ -231,10 +232,10 @@ nodes::TypeCheckResult type_check_container(const nodes::Container &expression, const Arguments &arguments) { switch (expression.get_type()) { case nodes::Container::ARRAY: - return type_check_array(expression, sources_manager, state); + return type_check_array(expression, sources_manager, state, arguments); case nodes::Container::BLOCK: return type_check_block(expression, sources_manager, - state); // TODO: check that expression brought + state, arguments); // TODO: check that expression brought // type are same, -> brought_type } } // IN PROGRESS @@ -303,7 +304,7 @@ nodes::TypeCheckResult type_check_array_access(const nodes::Access &expression, return value_result; } - if (index_result.get().get()->to_builtin() != builtin::types::Type::INDEX) { + if (!index_result.get().get()->is_builtin(builtin::types::Type::INDEX)) { sources_manager.get_error_log()->add_error( error_handling::ErrorLog::ErrorMessage( expression, "Can access only by Index", @@ -311,7 +312,7 @@ nodes::TypeCheckResult type_check_array_access(const nodes::Access &expression, return nodes::TypeCheckResult::construct_invalid_result(); } - if (value_result.get().get()->to_builtin() != builtin::types::Type::ARRAY) { + if (!value_result.get().get()->is_builtin(builtin::types::Type::ARRAY)) { sources_manager.get_error_log()->add_error( error_handling::ErrorLog::ErrorMessage( expression, "Can apply array access only to Array", @@ -342,7 +343,7 @@ nodes::TypeCheckResult type_check_tuple_access(const nodes::Access &expression, ->get() // Index type .value(); - if (value_result.get().get()->to_builtin() != builtin::types::Type::TUPLE) { + if (!value_result.get().get()->is_builtin(builtin::types::Type::TUPLE)) { sources_manager.get_error_log()->add_error( error_handling::ErrorLog::ErrorMessage( expression, "Can apply tuple access only to Tuple",