mirror of
https://codeberg.org/ProgramSnail/lang.git
synced 2025-12-05 22:48:43 +00:00
refactor type check Arguments, add posibility to pass type into arguments
This commit is contained in:
parent
0da0c9f6f5
commit
cf9311eb8b
2 changed files with 86 additions and 46 deletions
|
|
@ -144,11 +144,46 @@ class Arguments {
|
||||||
public:
|
public:
|
||||||
static Arguments expect_builtin(builtin::types::Type type,
|
static Arguments expect_builtin(builtin::types::Type type,
|
||||||
SourcesManager &sources_manager) {
|
SourcesManager &sources_manager) {
|
||||||
return {{sources_manager.get_type_storage()->primitive_type(type)}};
|
return Arguments(sources_manager.get_type_storage()->primitive_type(type),
|
||||||
|
{});
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
static Arguments nothing() { return Arguments({}, {}); }
|
||||||
nodes::MaybeTypeProxy expected_type = {};
|
|
||||||
|
static Arguments expect(nodes::TypeProxy type) { return Arguments(type, {}); }
|
||||||
|
|
||||||
|
static Arguments pass(nodes::TypeProxy type) { return Arguments({}, type); }
|
||||||
|
|
||||||
|
static Arguments maybe_expect(nodes::MaybeTypeProxy type) {
|
||||||
|
return Arguments(type, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
static Arguments maybe_pass(nodes::MaybeTypeProxy type) {
|
||||||
|
return Arguments({}, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Arguments expect_and_pass(nodes::TypeProxy expected_type,
|
||||||
|
nodes::TypeProxy passed_type) {
|
||||||
|
return Arguments(expected_type, passed_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Arguments maybe_expect_and_pass(nodes::MaybeTypeProxy expected_type,
|
||||||
|
nodes::MaybeTypeProxy passed_type) {
|
||||||
|
return Arguments(expected_type, passed_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
nodes::MaybeTypeProxy get_expected() const { return expected_type_; };
|
||||||
|
|
||||||
|
nodes::MaybeTypeProxy get_passed() const { return passed_type_; };
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit Arguments(nodes::MaybeTypeProxy expected_type = {},
|
||||||
|
nodes::MaybeTypeProxy passed_type = {})
|
||||||
|
: expected_type_(expected_type), passed_type_(passed_type) {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
nodes::MaybeTypeProxy expected_type_ = {};
|
||||||
|
nodes::MaybeTypeProxy passed_type_ = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
class ContextHolder {
|
class ContextHolder {
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ type_check_expression(const nodes::Expression &expression,
|
||||||
case 12: // Literal
|
case 12: // Literal
|
||||||
// TODO
|
// TODO
|
||||||
return type_check_literal(*expression.get<nodes::Literal>().value(),
|
return type_check_literal(*expression.get<nodes::Literal>().value(),
|
||||||
sources_manager, arguments.expected_type);
|
sources_manager, arguments.get_expected());
|
||||||
// --- empty lines
|
// --- empty lines
|
||||||
case 13: // Extra
|
case 13: // Extra
|
||||||
return nodes::TypeCheckResult(
|
return nodes::TypeCheckResult(
|
||||||
|
|
@ -86,14 +86,13 @@ nodes::TypeCheckResult type_check_match(const nodes::Match &expression,
|
||||||
State &state,
|
State &state,
|
||||||
const Arguments &arguments) {
|
const Arguments &arguments) {
|
||||||
nodes::TypeCheckResult value_result = type_check_expression(
|
nodes::TypeCheckResult value_result = type_check_expression(
|
||||||
*expression.get_value(), sources_manager, state, {});
|
*expression.get_value(), sources_manager, state, Arguments::nothing());
|
||||||
|
|
||||||
if (value_result.is_invalid()) {
|
if (value_result.is_invalid()) {
|
||||||
sources_manager.get_error_log()->add_error(
|
sources_manager.get_error_log()->add_error(
|
||||||
error_handling::ErrorLog::ErrorMessage(
|
error_handling::ErrorLog::ErrorMessage(
|
||||||
expression, "Match value is invalid",
|
expression, "Match value is invalid",
|
||||||
error_handling::ErrorType::TYPE_CHECK));
|
error_handling::ErrorType::TYPE_CHECK));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<nodes::TypeCheckResult> expression_result;
|
std::optional<nodes::TypeCheckResult> expression_result;
|
||||||
|
|
@ -103,24 +102,25 @@ nodes::TypeCheckResult type_check_match(const nodes::Match &expression,
|
||||||
|
|
||||||
type_check_expression(
|
type_check_expression(
|
||||||
*current_case->get_value(), sources_manager, state,
|
*current_case->get_value(), sources_manager, state,
|
||||||
Arguments{value_result.is_invalid() ? nodes::MaybeTypeProxy{}
|
Arguments::maybe_expect(value_result.is_invalid()
|
||||||
: expression_result.value().get()
|
? nodes::MaybeTypeProxy{}
|
||||||
});
|
: expression_result.value().get()));
|
||||||
// TODO: work with case
|
// TODO: work with case
|
||||||
// TODO: use type modifiers
|
// TODO: use type modifiers
|
||||||
|
|
||||||
if (current_case->get_condition().has_value()) {
|
if (current_case->get_condition().has_value()) {
|
||||||
type_check_expression(
|
type_check_expression(*current_case->get_condition().value(),
|
||||||
*current_case->get_condition().value(), sources_manager, state,
|
sources_manager, state,
|
||||||
Arguments::expect_builtin(builtin::types::Type::BOOL, sources_manager));
|
Arguments::expect_builtin(
|
||||||
|
builtin::types::Type::BOOL, sources_manager));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current_case->get_expression().has_value()) {
|
if (current_case->get_expression().has_value()) {
|
||||||
nodes::TypeCheckResult case_result = type_check_expression(
|
nodes::TypeCheckResult case_result = type_check_expression(
|
||||||
*current_case->get_condition().value(), sources_manager, state,
|
*current_case->get_condition().value(), sources_manager, state,
|
||||||
Arguments{expression_result.has_value()
|
Arguments::maybe_expect(expression_result.has_value()
|
||||||
? expression_result.value().get()
|
? expression_result.value().get()
|
||||||
: nodes::MaybeTypeProxy{}});
|
: nodes::MaybeTypeProxy{}));
|
||||||
|
|
||||||
if (!expression_result.has_value() && !case_result.is_invalid()) {
|
if (!expression_result.has_value() && !case_result.is_invalid()) {
|
||||||
expression_result = std::move(case_result);
|
expression_result = std::move(case_result);
|
||||||
|
|
@ -138,7 +138,7 @@ nodes::TypeCheckResult type_check_match(const nodes::Match &expression,
|
||||||
|
|
||||||
return type_same_to_expected(sources_manager.get_type_storage()->add_array_of(
|
return type_same_to_expected(sources_manager.get_type_storage()->add_array_of(
|
||||||
expression_result.value().get()),
|
expression_result.value().get()),
|
||||||
arguments.expected_type, expression,
|
arguments.get_expected(), expression,
|
||||||
*sources_manager.get_error_log());
|
*sources_manager.get_error_log());
|
||||||
} // IN PROGRESS
|
} // IN PROGRESS
|
||||||
|
|
||||||
|
|
@ -156,9 +156,9 @@ nodes::TypeCheckResult type_check_condition(const nodes::Condition &expression,
|
||||||
|
|
||||||
nodes::TypeCheckResult case_result = type_check_expression(
|
nodes::TypeCheckResult case_result = type_check_expression(
|
||||||
*expression.get_case(i).first, sources_manager, state,
|
*expression.get_case(i).first, sources_manager, state,
|
||||||
Arguments{expression_result.has_value()
|
Arguments::maybe_expect(expression_result.has_value()
|
||||||
? expression_result.value().get()
|
? expression_result.value().get()
|
||||||
: nodes::MaybeTypeProxy{}});
|
: nodes::MaybeTypeProxy{}));
|
||||||
|
|
||||||
if (!expression_result.has_value() && !case_result.is_invalid()) {
|
if (!expression_result.has_value() && !case_result.is_invalid()) {
|
||||||
expression_result = std::move(case_result);
|
expression_result = std::move(case_result);
|
||||||
|
|
@ -166,11 +166,11 @@ nodes::TypeCheckResult type_check_condition(const nodes::Condition &expression,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expression.get_else_case().has_value()) {
|
if (expression.get_else_case().has_value()) {
|
||||||
type_check_expression(*expression.get_else_case().value(), sources_manager,
|
type_check_expression(
|
||||||
state,
|
*expression.get_else_case().value(), sources_manager, state,
|
||||||
Arguments{expression_result.has_value()
|
Arguments::maybe_expect(expression_result.has_value()
|
||||||
? expression_result.value().get()
|
? expression_result.value().get()
|
||||||
: nodes::MaybeTypeProxy{}});
|
: nodes::MaybeTypeProxy{}));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!expression_result.has_value()) {
|
if (!expression_result.has_value()) {
|
||||||
|
|
@ -188,7 +188,7 @@ nodes::TypeCheckResult type_check_condition(const nodes::Condition &expression,
|
||||||
|
|
||||||
return type_same_to_expected(sources_manager.get_type_storage()->add_array_of(
|
return type_same_to_expected(sources_manager.get_type_storage()->add_array_of(
|
||||||
expression_result.value().get()),
|
expression_result.value().get()),
|
||||||
arguments.expected_type, expression,
|
arguments.get_expected(), expression,
|
||||||
*sources_manager.get_error_log());
|
*sources_manager.get_error_log());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -204,8 +204,9 @@ nodes::TypeCheckResult type_check_loop(const nodes::Loop &expression,
|
||||||
|
|
||||||
std::optional<nodes::TypeCheckResult> variable_result;
|
std::optional<nodes::TypeCheckResult> variable_result;
|
||||||
|
|
||||||
nodes::TypeCheckResult expression_result = type_check_expression(
|
nodes::TypeCheckResult expression_result =
|
||||||
*expression.get_expression(), sources_manager, state, {});
|
type_check_expression(*expression.get_expression(), sources_manager,
|
||||||
|
state, Arguments::nothing());
|
||||||
|
|
||||||
switch (expression.get_type()) {
|
switch (expression.get_type()) {
|
||||||
case nodes::Loop::LOOP: // infinity loop, no params
|
case nodes::Loop::LOOP: // infinity loop, no params
|
||||||
|
|
@ -247,7 +248,8 @@ nodes::TypeCheckResult type_check_loop(const nodes::Loop &expression,
|
||||||
|
|
||||||
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::expect(
|
||||||
|
interval_result.value().get().get()->get_parameter_proxy(0)));
|
||||||
|
|
||||||
// --- type check is independent from loop itself ---
|
// --- type check is independent from loop itself ---
|
||||||
// if (variable_result.value().is_invalid()) {
|
// if (variable_result.value().is_invalid()) {
|
||||||
|
|
@ -264,7 +266,7 @@ nodes::TypeCheckResult type_check_loop(const nodes::Loop &expression,
|
||||||
|
|
||||||
return type_same_to_expected(
|
return type_same_to_expected(
|
||||||
sources_manager.get_type_storage()->add_array_of(expression_result.get()),
|
sources_manager.get_type_storage()->add_array_of(expression_result.get()),
|
||||||
arguments.expected_type, expression, *sources_manager.get_error_log());
|
arguments.get_expected(), expression, *sources_manager.get_error_log());
|
||||||
} // IN PROGRESS
|
} // IN PROGRESS
|
||||||
|
|
||||||
// --- containers
|
// --- containers
|
||||||
|
|
@ -277,8 +279,9 @@ nodes::TypeCheckResult type_check_array(const nodes::Container &expression,
|
||||||
|
|
||||||
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
|
// elements should have same type, but type is not expected
|
||||||
auto expression_result = type_check_expression(
|
auto expression_result =
|
||||||
*expression.get_expression(i), sources_manager, state, Arguments{});
|
type_check_expression(*expression.get_expression(i), sources_manager,
|
||||||
|
state, Arguments::nothing());
|
||||||
|
|
||||||
if (!last_expression_result.has_value()) {
|
if (!last_expression_result.has_value()) {
|
||||||
last_expression_result = expression_result;
|
last_expression_result = expression_result;
|
||||||
|
|
@ -304,7 +307,7 @@ nodes::TypeCheckResult type_check_array(const nodes::Container &expression,
|
||||||
|
|
||||||
return type_same_to_expected(sources_manager.get_type_storage()->add_array_of(
|
return type_same_to_expected(sources_manager.get_type_storage()->add_array_of(
|
||||||
last_expression_result.value().get()),
|
last_expression_result.value().get()),
|
||||||
arguments.expected_type, expression,
|
arguments.get_expected(), expression,
|
||||||
*sources_manager.get_error_log());
|
*sources_manager.get_error_log());
|
||||||
} // IN PROGRESS
|
} // IN PROGRESS
|
||||||
|
|
||||||
|
|
@ -338,8 +341,9 @@ 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(
|
auto returned_result =
|
||||||
*expression.get_expression(), sources_manager, state, Arguments{});
|
type_check_expression(*expression.get_expression(), sources_manager,
|
||||||
|
state, Arguments::nothing());
|
||||||
|
|
||||||
if (returned_result.is_invalid()) {
|
if (returned_result.is_invalid()) {
|
||||||
return returned_result;
|
return returned_result;
|
||||||
|
|
@ -369,7 +373,7 @@ nodes::TypeCheckResult type_check_return(const nodes::Return &expression,
|
||||||
return type_same_to_expected(
|
return type_same_to_expected(
|
||||||
sources_manager.get_type_storage()->primitive_type(
|
sources_manager.get_type_storage()->primitive_type(
|
||||||
builtin::types::Type::UNIT),
|
builtin::types::Type::UNIT),
|
||||||
arguments.expected_type, expression, *sources_manager.get_error_log());
|
arguments.get_expected(), expression, *sources_manager.get_error_log());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
|
|
@ -377,7 +381,7 @@ nodes::TypeCheckResult
|
||||||
type_check_name_definition(const nodes::NameDefinition &expression,
|
type_check_name_definition(const nodes::NameDefinition &expression,
|
||||||
SourcesManager &sources_manager, State &state,
|
SourcesManager &sources_manager, State &state,
|
||||||
const Arguments &arguments) {
|
const Arguments &arguments) {
|
||||||
if (!arguments.expected_type.has_value()) {
|
if (!arguments.get_expected().has_value()) {
|
||||||
sources_manager.get_error_log()->add_error(
|
sources_manager.get_error_log()->add_error(
|
||||||
error_handling::ErrorLog::ErrorMessage(
|
error_handling::ErrorLog::ErrorMessage(
|
||||||
expression, "Can't deduce type of new variable from context",
|
expression, "Can't deduce type of new variable from context",
|
||||||
|
|
@ -386,7 +390,7 @@ type_check_name_definition(const nodes::NameDefinition &expression,
|
||||||
|
|
||||||
// defined name modifier should be -> (or contain -> ??)
|
// defined name modifier should be -> (or contain -> ??)
|
||||||
// TODO: deal with ...|...|... modifiers
|
// TODO: deal with ...|...|... modifiers
|
||||||
const auto &expected_type = arguments.expected_type.value();
|
const auto expected_type = arguments.get_expected().value();
|
||||||
if (!expected_type.get()->is_modifier(
|
if (!expected_type.get()->is_modifier(
|
||||||
nodes::Modifier::OUT)) { // TODO: utils::modifier_contains_OUT
|
nodes::Modifier::OUT)) { // TODO: utils::modifier_contains_OUT
|
||||||
sources_manager.get_error_log()->add_error(
|
sources_manager.get_error_log()->add_error(
|
||||||
|
|
@ -431,7 +435,7 @@ nodes::TypeCheckResult type_check_array_access(const nodes::Access &expression,
|
||||||
// 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),
|
||||||
arguments.expected_type, expression,
|
arguments.get_expected(), expression,
|
||||||
*sources_manager.get_error_log());
|
*sources_manager.get_error_log());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -457,7 +461,7 @@ nodes::TypeCheckResult type_check_tuple_access(const nodes::Access &expression,
|
||||||
|
|
||||||
return type_same_to_expected(
|
return type_same_to_expected(
|
||||||
value_result.get().get()->get_parameter_proxy(index),
|
value_result.get().get()->get_parameter_proxy(index),
|
||||||
arguments.expected_type, expression, *sources_manager.get_error_log());
|
arguments.get_expected(), expression, *sources_manager.get_error_log());
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes::TypeCheckResult type_check_access(const nodes::Access &expression,
|
nodes::TypeCheckResult type_check_access(const nodes::Access &expression,
|
||||||
|
|
@ -481,15 +485,16 @@ type_check_loop_control(const nodes::LoopControl &expression,
|
||||||
return type_same_to_expected(
|
return type_same_to_expected(
|
||||||
sources_manager.get_type_storage()->primitive_type(
|
sources_manager.get_type_storage()->primitive_type(
|
||||||
builtin::types::Type::UNIT),
|
builtin::types::Type::UNIT),
|
||||||
arguments.expected_type, expression, *sources_manager.get_error_log());
|
arguments.get_expected(), expression, *sources_manager.get_error_log());
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes::TypeCheckResult
|
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(
|
auto modified_result =
|
||||||
*expression.get_expression(), sources_manager, state, Arguments{});
|
type_check_expression(*expression.get_expression(), sources_manager,
|
||||||
|
state, Arguments::nothing());
|
||||||
|
|
||||||
if (modified_result.is_invalid()) {
|
if (modified_result.is_invalid()) {
|
||||||
return nodes::TypeCheckResult::construct_invalid_result();
|
return nodes::TypeCheckResult::construct_invalid_result();
|
||||||
|
|
@ -521,7 +526,7 @@ type_check_modifier_expression(const nodes::ModifierExpression &expression,
|
||||||
modified_result.get(), expression.get_modifier()));
|
modified_result.get(), expression.get_modifier()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return type_same_to_expected(modified_result.get(), arguments.expected_type,
|
return type_same_to_expected(modified_result.get(), arguments.get_expected(),
|
||||||
expression, *sources_manager.get_error_log());
|
expression, *sources_manager.get_error_log());
|
||||||
} // IN PROGRESS
|
} // IN PROGRESS
|
||||||
|
|
||||||
|
|
@ -589,7 +594,7 @@ type_check_constructor(const nodes::Constructor &expression,
|
||||||
}
|
}
|
||||||
// TODO: expect types of arguments by type definition
|
// TODO: expect types of arguments by type definition
|
||||||
return type_same_to_expected(expression.get_type_proxy(),
|
return type_same_to_expected(expression.get_type_proxy(),
|
||||||
arguments.expected_type, expression,
|
arguments.get_expected(), expression,
|
||||||
*sources_manager.get_error_log());
|
*sources_manager.get_error_log());
|
||||||
// TODO: add <- modifiier to type ??
|
// TODO: add <- modifiier to type ??
|
||||||
|
|
||||||
|
|
@ -600,14 +605,14 @@ nodes::TypeCheckResult type_check_lambda(const nodes::Lambda &expression,
|
||||||
SourcesManager &sources_manager,
|
SourcesManager &sources_manager,
|
||||||
State &state,
|
State &state,
|
||||||
const Arguments &arguments) {
|
const Arguments &arguments) {
|
||||||
if (!arguments.expected_type.has_value()) {
|
if (!arguments.get_expected().has_value()) {
|
||||||
sources_manager.get_error_log()->add_error(
|
sources_manager.get_error_log()->add_error(
|
||||||
error_handling::ErrorLog::ErrorMessage(
|
error_handling::ErrorLog::ErrorMessage(
|
||||||
expression, "Can't deduce type of lambda function from context",
|
expression, "Can't deduce type of lambda function from context",
|
||||||
error_handling::ErrorType::TYPE_CHECK));
|
error_handling::ErrorType::TYPE_CHECK));
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto &expected_type = arguments.expected_type.value();
|
const auto expected_type = arguments.get_expected().value();
|
||||||
if (!expected_type.get()->is_builtin(builtin::types::Type::FUNCTION)) {
|
if (!expected_type.get()->is_builtin(builtin::types::Type::FUNCTION)) {
|
||||||
sources_manager.get_error_log()->add_error(
|
sources_manager.get_error_log()->add_error(
|
||||||
error_handling::ErrorLog::ErrorMessage(
|
error_handling::ErrorLog::ErrorMessage(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue