mirror of
https://codeberg.org/ProgramSnail/lang.git
synced 2025-12-06 06:58:46 +00:00
type check arguments added
This commit is contained in:
parent
3907da619e
commit
a2abb598ac
2 changed files with 38 additions and 71 deletions
|
|
@ -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 = {};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue