mirror of
https://codeberg.org/ProgramSnail/lang.git
synced 2025-12-07 15:38:49 +00:00
fixes, conditions typecheck
This commit is contained in:
parent
fe652bc1c2
commit
63d0335188
2 changed files with 70 additions and 21 deletions
|
|
@ -28,6 +28,8 @@ public:
|
||||||
|
|
||||||
bool operator==(const TypeProxy &other) const;
|
bool operator==(const TypeProxy &other) const;
|
||||||
|
|
||||||
|
bool operator!=(const TypeProxy&) const = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TypeProxy(TypeStorage &type_storage, size_t id)
|
TypeProxy(TypeStorage &type_storage, size_t id)
|
||||||
: type_storage_(&type_storage), id_(id) {}
|
: type_storage_(&type_storage), id_(id) {}
|
||||||
|
|
|
||||||
|
|
@ -87,13 +87,54 @@ nodes::TypeCheckResult type_check_match(const nodes::Match &expression,
|
||||||
const Arguments &arguments) {
|
const Arguments &arguments) {
|
||||||
} // IN PROGRESS
|
} // IN PROGRESS
|
||||||
|
|
||||||
// TODO
|
|
||||||
nodes::TypeCheckResult type_check_condition(const nodes::Condition &expression,
|
nodes::TypeCheckResult type_check_condition(const nodes::Condition &expression,
|
||||||
SourcesManager &sources_manager,
|
SourcesManager &sources_manager,
|
||||||
State &state,
|
State &state,
|
||||||
const Arguments &arguments) {
|
const Arguments &arguments) {
|
||||||
// TODO: extract functiona argument names
|
|
||||||
|
std::optional<nodes::TypeCheckResult> expression_result;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < expression.cases_size(); ++i) {
|
||||||
|
type_check_expression(
|
||||||
|
*expression.get_case(i).first, sources_manager, state,
|
||||||
|
Arguments::expect_builtin(builtin::types::Type::BOOL, sources_manager));
|
||||||
|
|
||||||
|
nodes::TypeCheckResult case_result = type_check_expression(
|
||||||
|
*expression.get_case(i).first, sources_manager, state,
|
||||||
|
Arguments{expression_result.has_value()
|
||||||
|
? expression_result.value().get()
|
||||||
|
: nodes::MaybeTypeProxy{}});
|
||||||
|
|
||||||
|
if (!expression_result.has_value() && !case_result.is_invalid()) {
|
||||||
|
expression_result = std::move(case_result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expression.get_else_case().has_value()) {
|
||||||
|
type_check_expression(*expression.get_else_case().value(), sources_manager,
|
||||||
|
state,
|
||||||
|
Arguments{expression_result.has_value()
|
||||||
|
? expression_result.value().get()
|
||||||
|
: nodes::MaybeTypeProxy{}});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!expression_result.has_value()) {
|
||||||
|
sources_manager.get_error_log()->add_error(
|
||||||
|
error_handling::ErrorLog::ErrorMessage(
|
||||||
|
expression, "There should be at least one case in if statement",
|
||||||
|
error_handling::ErrorType::TYPE_CHECK));
|
||||||
|
expression_result = nodes::TypeCheckResult::construct_invalid_result();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ??????????????????????????
|
||||||
|
// TODO: extract function argument names
|
||||||
// typecheck in statements ??
|
// typecheck in statements ??
|
||||||
|
// ??????????????????????????
|
||||||
|
|
||||||
|
return type_same_to_expected(sources_manager.get_type_storage()->add_array_of(
|
||||||
|
expression_result.value().get()),
|
||||||
|
arguments.expected_type, expression,
|
||||||
|
*sources_manager.get_error_log());
|
||||||
} // IN PROGRESS
|
} // IN PROGRESS
|
||||||
|
|
||||||
nodes::TypeCheckResult type_check_loop(const nodes::Loop &expression,
|
nodes::TypeCheckResult type_check_loop(const nodes::Loop &expression,
|
||||||
|
|
@ -102,7 +143,7 @@ nodes::TypeCheckResult type_check_loop(const nodes::Loop &expression,
|
||||||
const Arguments &arguments) {
|
const Arguments &arguments) {
|
||||||
// TODO: ranges ??
|
// TODO: ranges ??
|
||||||
|
|
||||||
std::optional<nodes::TypeCheckResult> condition_result;
|
// std::optional<nodes::TypeCheckResult> condition_result;
|
||||||
|
|
||||||
std::optional<nodes::TypeCheckResult> interval_result;
|
std::optional<nodes::TypeCheckResult> interval_result;
|
||||||
|
|
||||||
|
|
@ -115,23 +156,26 @@ nodes::TypeCheckResult type_check_loop(const nodes::Loop &expression,
|
||||||
case nodes::Loop::LOOP: // infinity loop, no params
|
case nodes::Loop::LOOP: // infinity loop, no params
|
||||||
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::expect_builtin(builtin::types::Type::BOOL, sources_manager));
|
Arguments::expect_builtin(builtin::types::Type::BOOL, sources_manager));
|
||||||
|
|
||||||
if (condition_result.value().is_invalid()) {
|
// --- type check is independent from loop itself ---
|
||||||
return condition_result.value();
|
// if (condition_result.value().is_invalid()) {
|
||||||
}
|
// return condition_result.value();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// --- done in expect ---
|
||||||
|
// if (!condition_result.value().get().get()->is_builtin(
|
||||||
|
// builtin::types::Type::BOOL)) {
|
||||||
|
// sources_manager.get_error_log()->add_error(
|
||||||
|
// error_handling::ErrorLog::ErrorMessage(
|
||||||
|
// *expression.get_condition().value(),
|
||||||
|
// "While loop condition should have type Bool",
|
||||||
|
// error_handling::ErrorType::TYPE_CHECK));
|
||||||
|
// return nodes::TypeCheckResult::construct_invalid_result();
|
||||||
|
// }
|
||||||
|
|
||||||
if (!condition_result.value().get().get()->is_builtin(
|
|
||||||
builtin::types::Type::BOOL)) {
|
|
||||||
sources_manager.get_error_log()->add_error(
|
|
||||||
error_handling::ErrorLog::ErrorMessage(
|
|
||||||
*expression.get_condition().value(),
|
|
||||||
"While loop condition should have type Bool",
|
|
||||||
error_handling::ErrorType::TYPE_CHECK));
|
|
||||||
return nodes::TypeCheckResult::construct_invalid_result();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case nodes::Loop::FOR:
|
case nodes::Loop::FOR:
|
||||||
// TODO: expect range ??
|
// TODO: expect range ??
|
||||||
|
|
@ -141,20 +185,23 @@ nodes::TypeCheckResult type_check_loop(const nodes::Loop &expression,
|
||||||
sources_manager));
|
sources_manager));
|
||||||
|
|
||||||
if (interval_result.value().is_invalid()) {
|
if (interval_result.value().is_invalid()) {
|
||||||
return interval_result.value();
|
// --- type check is independent from loop itself ---
|
||||||
|
// return interval_result.value();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
variable_result = type_check_expression(
|
variable_result = type_check_expression(
|
||||||
*expression.get_variable().value(), sources_manager, state,
|
*expression.get_variable().value(), sources_manager, state,
|
||||||
Arguments{interval_result.value().get().get()->get_parameter_proxy(0)});
|
Arguments{interval_result.value().get().get()->get_parameter_proxy(0)});
|
||||||
|
|
||||||
if (variable_result.value().is_invalid()) {
|
// --- type check is independent from loop itself ---
|
||||||
return variable_result.value();
|
// if (variable_result.value().is_invalid()) {
|
||||||
}
|
// return variable_result.value();
|
||||||
|
// }
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expression_result.is_invalid()) {
|
if (expression_result.is_invalid()) { // TODO: log invalid
|
||||||
return expression_result;
|
return expression_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue