mirror of
https://codeberg.org/ProgramSnail/lang.git
synced 2025-12-06 15:08:48 +00:00
type check utils cpp, part of expressions type check, name tree type/name definitions extraction
This commit is contained in:
parent
512d011f72
commit
4f04dd9995
4 changed files with 99 additions and 20 deletions
|
|
@ -46,12 +46,20 @@ set(
|
||||||
src/printers/statement_printers.cpp
|
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
|
add_executable(lang src/main.cpp
|
||||||
src/name_tree.cpp
|
src/name_tree.cpp
|
||||||
|
|
||||||
${NODES}
|
${NODES}
|
||||||
${BUILDERS}
|
${BUILDERS}
|
||||||
${PRINTERS}
|
${PRINTERS}
|
||||||
|
# ${TYPECHECK}
|
||||||
|
|
||||||
include/tree_sitter_wrapper.hpp
|
include/tree_sitter_wrapper.hpp
|
||||||
deps/tree-sitter-lang/src/tree_sitter/parser.h
|
deps/tree-sitter-lang/src/tree_sitter/parser.h
|
||||||
|
|
|
||||||
|
|
@ -171,4 +171,19 @@ private:
|
||||||
State &state;
|
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
|
} // namespace type_check
|
||||||
|
|
|
||||||
|
|
@ -12,25 +12,6 @@
|
||||||
|
|
||||||
namespace type_check {
|
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
|
nodes::TypeCheckResult
|
||||||
type_check_expression(const nodes::Expression &expression,
|
type_check_expression(const nodes::Expression &expression,
|
||||||
SourcesManager &sources_manager, State &state,
|
SourcesManager &sources_manager, State &state,
|
||||||
|
|
@ -455,7 +436,14 @@ nodes::TypeCheckResult
|
||||||
type_check_constructor(const nodes::Constructor &expression,
|
type_check_constructor(const nodes::Constructor &expression,
|
||||||
SourcesManager &sources_manager, State &state,
|
SourcesManager &sources_manager, State &state,
|
||||||
const Arguments &arguments) {
|
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) {
|
for (size_t i = 0; i < expression.arguments_size(); ++i) {
|
||||||
const auto annotation = expression.get_argument_annotation(i);
|
const auto annotation = expression.get_argument_annotation(i);
|
||||||
auto argument_type = type_check_expression(
|
auto argument_type = type_check_expression(
|
||||||
|
|
|
||||||
68
src/type_check_utils.cpp
Normal file
68
src/type_check_utils.cpp
Normal 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
|
||||||
Loading…
Add table
Add a link
Reference in a new issue