From 4f04dd99953d3b0af87c7906eeb4e5335d1f04d7 Mon Sep 17 00:00:00 2001 From: ProgramSnail Date: Thu, 4 Jan 2024 17:06:09 +0300 Subject: [PATCH] type check utils cpp, part of expressions type check, name tree type/name definitions extraction --- CMakeLists.txt | 8 +++++ include/type_check_utils.hpp | 15 ++++++++ src/expression_type_check.cpp | 28 +++++---------- src/type_check_utils.cpp | 68 +++++++++++++++++++++++++++++++++++ 4 files changed, 99 insertions(+), 20 deletions(-) create mode 100644 src/type_check_utils.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index b7d0b64..990cc9c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,12 +46,20 @@ set( src/printers/statement_printers.cpp ) +set( + PRINTERS + src/basic_type_check.cpp + src/expression_type_check.cpp + src/type_check_utils.cpp +) + add_executable(lang src/main.cpp src/name_tree.cpp ${NODES} ${BUILDERS} ${PRINTERS} + # ${TYPECHECK} include/tree_sitter_wrapper.hpp deps/tree-sitter-lang/src/tree_sitter/parser.h diff --git a/include/type_check_utils.hpp b/include/type_check_utils.hpp index b49df23..e77734b 100644 --- a/include/type_check_utils.hpp +++ b/include/type_check_utils.hpp @@ -171,4 +171,19 @@ private: State &state; }; +nodes::TypeCheckResult type_same_to_expected( + nodes::TypeProxy type, nodes::MaybeTypeProxy expected_type, + const nodes::Node &node, error_handling::ErrorLog &error_log, + const std::string &message = "Different type with expected one"); + +std::optional +find_type_definition_handle_errors(const std::string &name, + const nodes::Node &node, + SourcesManager &sources_manager); + +std::optional +find_name_definition_handle_errors(const std::string &name, + const nodes::Node &node, + SourcesManager &sources_manager); + } // namespace type_check diff --git a/src/expression_type_check.cpp b/src/expression_type_check.cpp index 97599df..e223b0e 100644 --- a/src/expression_type_check.cpp +++ b/src/expression_type_check.cpp @@ -12,25 +12,6 @@ namespace type_check { -nodes::TypeCheckResult type_same_to_expected( - nodes::TypeProxy type, nodes::MaybeTypeProxy expected_type, - const nodes::Node &node, error_handling::ErrorLog &error_log, - const std::string &message = "Different type with expected one") { - if (!expected_type.has_value()) { - return nodes::TypeCheckResult{type}; - } - - if (type != expected_type.value()) { - error_log.add_error(error_handling::ErrorLog::ErrorMessage( - node, message, error_handling::ErrorType::TYPE_CHECK)); - - return nodes::TypeCheckResult::construct_invalid_result(); - } - // TODO: use 'can cast to' (for modifiers), instead '==' - return nodes::TypeCheckResult{ - expected_type.value()}; // TODO: retern type or expected type ?? -} - nodes::TypeCheckResult type_check_expression(const nodes::Expression &expression, SourcesManager &sources_manager, State &state, @@ -455,7 +436,14 @@ nodes::TypeCheckResult type_check_constructor(const nodes::Constructor &expression, SourcesManager &sources_manager, State &state, const Arguments &arguments) { - // TODO: find definition + const auto maybe_type_definition = find_type_definition_handle_errors( + *expression.get_type()->get_name()->get(), expression, sources_manager); + if (!maybe_type_definition.has_value()) { + return nodes::TypeCheckResult::construct_invalid_result(); + } + const nodes::TypeDefinition *type_definition = maybe_type_definition.value(); + + // TODO: extract types from definition for (size_t i = 0; i < expression.arguments_size(); ++i) { const auto annotation = expression.get_argument_annotation(i); auto argument_type = type_check_expression( diff --git a/src/type_check_utils.cpp b/src/type_check_utils.cpp new file mode 100644 index 0000000..1bcff70 --- /dev/null +++ b/src/type_check_utils.cpp @@ -0,0 +1,68 @@ +#include "type_check_utils.hpp" + +namespace type_check { + +nodes::TypeCheckResult type_same_to_expected( + nodes::TypeProxy type, nodes::MaybeTypeProxy expected_type, + const nodes::Node &node, error_handling::ErrorLog &error_log, + const std::string &message) { + if (!expected_type.has_value()) { + return nodes::TypeCheckResult{type}; + } + + if (type != expected_type.value()) { + error_log.add_error(error_handling::ErrorLog::ErrorMessage( + node, message, error_handling::ErrorType::TYPE_CHECK)); + + return nodes::TypeCheckResult::construct_invalid_result(); + } + // TODO: use 'can cast to' (for modifiers), instead '==' + return nodes::TypeCheckResult{ + expected_type.value()}; // TODO: retern type or expected type ?? +} + +template +std::optional +find_statement_handle_errors(const std::string &name, const nodes::Node &node, + SourcesManager &sources_manager, + const std::string &message_not_found, + const std::string &message_different_statement) { + const auto maybe_any_statement = sources_manager.get_name_tree()->find(name); + if (!maybe_any_statement.has_value()) { + sources_manager.get_error_log()->add_error( + error_handling::ErrorLog::ErrorMessage( + node, message_not_found, error_handling::ErrorType::TYPE_CHECK)); + return std::nullopt; + } + + const auto maybe_statement = maybe_any_statement.value().get()->get(); + if (!maybe_statement.has_value()) { + sources_manager.get_error_log()->add_error( + error_handling::ErrorLog::ErrorMessage( + node, message_different_statement, + error_handling::ErrorType::TYPE_CHECK)); + return std::nullopt; + } + + return maybe_statement.value(); +} + +std::optional +find_type_definition_handle_errors(const std::string &name, + const nodes::Node &node, + SourcesManager &sources_manager) { + return find_statement_handle_errors( + name, node, sources_manager, "No type definition found in name tree", + "Node in name tree is not type definition"); +} + +std::optional +find_name_definition_handle_errors(const std::string &name, + const nodes::Node &node, + SourcesManager &sources_manager) { + return find_statement_handle_errors( + name, node, sources_manager, "No name definition found in name tree", + "Node in name tree is not name definition"); +} + +} // namespace type_check