type check arguments added

This commit is contained in:
ProgramSnail 2024-01-04 11:44:48 +03:00
parent 3907da619e
commit a2abb598ac
2 changed files with 38 additions and 71 deletions

View file

@ -136,6 +136,12 @@ public:
}; };
class Arguments { class Arguments {
public:
static Arguments expect_builtin(builtin::types::Type type,
SourcesManager &sources_manager) {
return {{sources_manager.get_type_storage()->primitive_type(type)}};
}
public: public:
nodes::MaybeTypeProxy expected_type = {}; nodes::MaybeTypeProxy expected_type = {};
}; };

View file

@ -121,22 +121,21 @@ nodes::TypeCheckResult type_check_loop(const nodes::Loop &expression,
std::optional<nodes::TypeCheckResult> condition_result; std::optional<nodes::TypeCheckResult> condition_result;
std::optional<nodes::TypeCheckResult> variable_result;
std::optional<nodes::TypeCheckResult> interval_result; std::optional<nodes::TypeCheckResult> interval_result;
nodes::TypeCheckResult expression_result = type_check_expression( std::optional<nodes::TypeCheckResult> variable_result;
*expression.get_expression(), sources_manager, state);
nodes::TypeCheckResult expression_result = type_check_expression(
*expression.get_expression(), sources_manager, state, {});
// detect maximum amount of errors
switch (expression.get_type()) { switch (expression.get_type()) {
case nodes::Loop::LOOP: case nodes::Loop::LOOP: // infinity loop, no params
// TODO
break; break;
case nodes::Loop::WHILE: case nodes::Loop::WHILE:
condition_result = type_check_expression( condition_result = type_check_expression(
*expression.get_condition().value(), sources_manager, state, *expression.get_condition().value(), sources_manager, state,
Arguments{{sources_manager.get_type_storage()->primitive_type( Arguments::expect_builtin(builtin::types::Type::BOOL, sources_manager));
builtin::types::Type::BOOL)}});
if (condition_result.value().is_invalid()) { if (condition_result.value().is_invalid()) {
return condition_result.value(); return condition_result.value();
@ -153,40 +152,22 @@ nodes::TypeCheckResult type_check_loop(const nodes::Loop &expression,
} }
break; break;
case nodes::Loop::FOR: case nodes::Loop::FOR:
variable_result = type_check_expression(*expression.get_variable().value(), // TODO: expect range ??
sources_manager, state); interval_result = type_check_expression(
interval_result = type_check_expression(*expression.get_interval().value(), *expression.get_interval().value(), sources_manager, state,
sources_manager, state); Arguments::expect_builtin(builtin::types::Type::ARRAY,
sources_manager));
if (variable_result.value().is_invalid()) {
return variable_result.value();
}
if (interval_result.value().is_invalid()) { if (interval_result.value().is_invalid()) {
return interval_result.value(); return interval_result.value();
} }
// // TODO ?? variable_result = type_check_expression(
// if *expression.get_variable().value(), sources_manager, state,
// (!variable_result.value().get().get_type()->is_builtin(builtin::types::Type::BOOL)) Arguments{interval_result.value().get().get()->get_parameter_proxy(0)});
// {
// sources_manager.get_error_log()->add_error(
// error_handling::ErrorLog::ErrorMessage(
// *expression.get_condition().value(),
// "For loop variable should have type ...",
// error_handling::ErrorType::TYPE_CHECK));
// return nodes::TypeCheckResult::construct_invalid_result();
// }
// TODO: ranges ?? if (variable_result.value().is_invalid()) {
if (!condition_result.value().get().get()->is_builtin( return variable_result.value();
builtin::types::Type::ARRAY)) {
sources_manager.get_error_log()->add_error(
error_handling::ErrorLog::ErrorMessage(
*expression.get_condition().value(),
"For loop interval should have type Array",
error_handling::ErrorType::TYPE_CHECK));
return nodes::TypeCheckResult::construct_invalid_result();
} }
break; break;
} }
@ -211,8 +192,9 @@ nodes::TypeCheckResult type_check_array(const nodes::Container &expression,
std::optional<nodes::TypeCheckResult> last_expression_result; std::optional<nodes::TypeCheckResult> last_expression_result;
for (size_t i = 0; i < expression.expressions_size(); ++i) { 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( auto expression_result = type_check_expression(
*expression.get_expression(i), sources_manager, state); *expression.get_expression(i), sources_manager, state, Arguments{});
if (!last_expression_result.has_value()) { if (!last_expression_result.has_value()) {
last_expression_result = expression_result; last_expression_result = expression_result;
@ -269,8 +251,8 @@ nodes::TypeCheckResult type_check_return(const nodes::Return &expression,
SourcesManager &sources_manager, SourcesManager &sources_manager,
State &state, State &state,
const Arguments &arguments) { const Arguments &arguments) {
auto returned_result = type_check_expression(*expression.get_expression(), auto returned_result = type_check_expression(
sources_manager, state); *expression.get_expression(), sources_manager, state, Arguments{});
if (returned_result.is_invalid()) { if (returned_result.is_invalid()) {
return returned_result; return returned_result;
@ -314,11 +296,13 @@ nodes::TypeCheckResult type_check_array_access(const nodes::Access &expression,
State &state, State &state,
const Arguments &arguments) { const Arguments &arguments) {
auto index_result = auto index_result = type_check_expression(
type_check_expression(*expression.get_index(), sources_manager, state); *expression.get_index(), sources_manager, state,
Arguments::expect_builtin(builtin::types::Type::INDEX, sources_manager));
auto value_result = auto value_result = type_check_expression(
type_check_expression(*expression.get_value(), sources_manager, state); *expression.get_value(), sources_manager, state,
Arguments::expect_builtin(builtin::types::Type::ARRAY, sources_manager));
if (index_result.is_invalid()) { if (index_result.is_invalid()) {
return index_result; return index_result;
@ -328,22 +312,6 @@ nodes::TypeCheckResult type_check_array_access(const nodes::Access &expression,
return value_result; return value_result;
} }
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",
error_handling::ErrorType::TYPE_CHECK));
return nodes::TypeCheckResult::construct_invalid_result();
}
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",
error_handling::ErrorType::TYPE_CHECK));
return nodes::TypeCheckResult::construct_invalid_result();
}
// TODO: modifier checks ?? // TODO: modifier checks ??
return type_same_to_expected(value_result.get().get()->get_parameter_proxy(0), return type_same_to_expected(value_result.get().get()->get_parameter_proxy(0),
@ -355,8 +323,9 @@ nodes::TypeCheckResult type_check_tuple_access(const nodes::Access &expression,
SourcesManager &sources_manager, SourcesManager &sources_manager,
State &state, State &state,
const Arguments &arguments) { const Arguments &arguments) {
auto value_result = auto value_result = type_check_expression(
type_check_expression(*expression.get_value(), sources_manager, state); *expression.get_value(), sources_manager, state,
Arguments::expect_builtin(builtin::types::Type::TUPLE, sources_manager));
if (value_result.is_invalid()) { if (value_result.is_invalid()) {
return value_result; return value_result;
@ -368,14 +337,6 @@ nodes::TypeCheckResult type_check_tuple_access(const nodes::Access &expression,
->get<size_t>() // Index type ->get<size_t>() // Index type
.value(); .value();
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",
error_handling::ErrorType::TYPE_CHECK));
return nodes::TypeCheckResult::construct_invalid_result();
}
// TODO: modifier checks ?? // TODO: modifier checks ??
return type_same_to_expected( return type_same_to_expected(
@ -411,8 +372,8 @@ nodes::TypeCheckResult
type_check_modifier_expression(const nodes::ModifierExpression &expression, type_check_modifier_expression(const nodes::ModifierExpression &expression,
SourcesManager &sources_manager, State &state, SourcesManager &sources_manager, State &state,
const Arguments &arguments) { const Arguments &arguments) {
auto modified_result = type_check_expression(*expression.get_expression(), auto modified_result = type_check_expression(
sources_manager, state); *expression.get_expression(), sources_manager, state, Arguments{});
if (modified_result.is_invalid()) { if (modified_result.is_invalid()) {
return nodes::TypeCheckResult::construct_invalid_result(); return nodes::TypeCheckResult::construct_invalid_result();