type check utils cpp, part of expressions type check, name tree type/name definitions extraction

This commit is contained in:
ProgramSnail 2024-01-04 17:06:09 +03:00
parent 512d011f72
commit 4f04dd9995
4 changed files with 99 additions and 20 deletions

View file

@ -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

View file

@ -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<const nodes::TypeDefinition *>
find_type_definition_handle_errors(const std::string &name,
const nodes::Node &node,
SourcesManager &sources_manager);
std::optional<const nodes::NameDefinition *>
find_name_definition_handle_errors(const std::string &name,
const nodes::Node &node,
SourcesManager &sources_manager);
} // namespace type_check

View file

@ -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(

68
src/type_check_utils.cpp Normal file
View file

@ -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 <typename T>
std::optional<const T *>
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<T>();
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<const nodes::TypeDefinition *>
find_type_definition_handle_errors(const std::string &name,
const nodes::Node &node,
SourcesManager &sources_manager) {
return find_statement_handle_errors<nodes::TypeDefinition>(
name, node, sources_manager, "No type definition found in name tree",
"Node in name tree is not type definition");
}
std::optional<const nodes::NameDefinition *>
find_name_definition_handle_errors(const std::string &name,
const nodes::Node &node,
SourcesManager &sources_manager) {
return find_statement_handle_errors<nodes::NameDefinition>(
name, node, sources_manager, "No name definition found in name tree",
"Node in name tree is not name definition");
}
} // namespace type_check