mirror of
https://codeberg.org/ProgramSnail/lang.git
synced 2025-12-05 22:48:43 +00:00
Arguments: change structure, pass in match (v0)
This commit is contained in:
parent
cf9311eb8b
commit
070b08dba4
2 changed files with 61 additions and 62 deletions
|
|
@ -142,44 +142,41 @@ public:
|
|||
|
||||
class Arguments {
|
||||
public:
|
||||
static Arguments expect_builtin(builtin::types::Type type,
|
||||
SourcesManager &sources_manager) {
|
||||
return Arguments(sources_manager.get_type_storage()->primitive_type(type),
|
||||
{});
|
||||
Arguments() = default;
|
||||
|
||||
Arguments expect_builtin(builtin::types::Type type,
|
||||
SourcesManager &sources_manager) const {
|
||||
Arguments copy(*this);
|
||||
copy.expected_type_ =
|
||||
sources_manager.get_type_storage()->primitive_type(type);
|
||||
}
|
||||
|
||||
static Arguments nothing() { return Arguments({}, {}); }
|
||||
|
||||
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, {});
|
||||
Arguments pass_builtin(builtin::types::Type type,
|
||||
SourcesManager &sources_manager) const {
|
||||
Arguments copy(*this);
|
||||
copy.passed_type_ =
|
||||
sources_manager.get_type_storage()->primitive_type(type);
|
||||
return copy;
|
||||
}
|
||||
|
||||
static Arguments maybe_pass(nodes::MaybeTypeProxy type) {
|
||||
return Arguments({}, type);
|
||||
Arguments expect(nodes::MaybeTypeProxy type) const {
|
||||
Arguments copy(*this);
|
||||
copy.expected_type_ = type;
|
||||
return copy;
|
||||
}
|
||||
|
||||
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);
|
||||
Arguments pass(nodes::MaybeTypeProxy type) const {
|
||||
Arguments copy(*this);
|
||||
copy.passed_type_ = type;
|
||||
return copy;
|
||||
}
|
||||
|
||||
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) {}
|
||||
// TODO: add check, that there is no passed type for some nodes ??
|
||||
// TODO: arguments builder ??
|
||||
|
||||
private:
|
||||
nodes::MaybeTypeProxy expected_type_ = {};
|
||||
|
|
|
|||
|
|
@ -86,8 +86,9 @@ nodes::TypeCheckResult type_check_match(const nodes::Match &expression,
|
|||
State &state,
|
||||
const Arguments &arguments) {
|
||||
nodes::TypeCheckResult value_result = type_check_expression(
|
||||
*expression.get_value(), sources_manager, state, Arguments::nothing());
|
||||
*expression.get_value(), sources_manager, state, Arguments{});
|
||||
|
||||
// x :=/=: ...
|
||||
if (value_result.is_invalid()) {
|
||||
sources_manager.get_error_log()->add_error(
|
||||
error_handling::ErrorLog::ErrorMessage(
|
||||
|
|
@ -100,27 +101,31 @@ nodes::TypeCheckResult type_check_match(const nodes::Match &expression,
|
|||
for (size_t i = 0; i < expression.cases_size(); ++i) {
|
||||
const nodes::Match::Case *current_case = expression.get_case(i);
|
||||
|
||||
// :=/=: x ...
|
||||
type_check_expression(
|
||||
*current_case->get_value(), sources_manager, state,
|
||||
Arguments::maybe_expect(value_result.is_invalid()
|
||||
? nodes::MaybeTypeProxy{}
|
||||
: expression_result.value().get()));
|
||||
Arguments{}
|
||||
.expect_builtin(builtin::types::Type::BOOL, sources_manager)
|
||||
.pass(value_result.is_invalid() ? nodes::MaybeTypeProxy{}
|
||||
: expression_result.value().get()));
|
||||
// TODO: work with case
|
||||
// TODO: use type modifiers
|
||||
|
||||
// ... ?? x ...
|
||||
if (current_case->get_condition().has_value()) {
|
||||
type_check_expression(*current_case->get_condition().value(),
|
||||
sources_manager, state,
|
||||
Arguments::expect_builtin(
|
||||
Arguments{}.expect_builtin(
|
||||
builtin::types::Type::BOOL, sources_manager));
|
||||
}
|
||||
|
||||
// ... -> x
|
||||
if (current_case->get_expression().has_value()) {
|
||||
nodes::TypeCheckResult case_result = type_check_expression(
|
||||
*current_case->get_condition().value(), sources_manager, state,
|
||||
Arguments::maybe_expect(expression_result.has_value()
|
||||
? expression_result.value().get()
|
||||
: nodes::MaybeTypeProxy{}));
|
||||
Arguments{}.expect(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);
|
||||
|
|
@ -150,15 +155,15 @@ nodes::TypeCheckResult type_check_condition(const nodes::Condition &expression,
|
|||
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));
|
||||
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::maybe_expect(expression_result.has_value()
|
||||
? expression_result.value().get()
|
||||
: nodes::MaybeTypeProxy{}));
|
||||
Arguments{}.expect(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);
|
||||
|
|
@ -168,9 +173,9 @@ nodes::TypeCheckResult type_check_condition(const nodes::Condition &expression,
|
|||
if (expression.get_else_case().has_value()) {
|
||||
type_check_expression(
|
||||
*expression.get_else_case().value(), sources_manager, state,
|
||||
Arguments::maybe_expect(expression_result.has_value()
|
||||
? expression_result.value().get()
|
||||
: nodes::MaybeTypeProxy{}));
|
||||
Arguments{}.expect(expression_result.has_value()
|
||||
? expression_result.value().get()
|
||||
: nodes::MaybeTypeProxy{}));
|
||||
}
|
||||
|
||||
if (!expression_result.has_value()) {
|
||||
|
|
@ -204,9 +209,8 @@ nodes::TypeCheckResult type_check_loop(const nodes::Loop &expression,
|
|||
|
||||
std::optional<nodes::TypeCheckResult> variable_result;
|
||||
|
||||
nodes::TypeCheckResult expression_result =
|
||||
type_check_expression(*expression.get_expression(), sources_manager,
|
||||
state, Arguments::nothing());
|
||||
nodes::TypeCheckResult expression_result = type_check_expression(
|
||||
*expression.get_expression(), sources_manager, state, Arguments{});
|
||||
|
||||
switch (expression.get_type()) {
|
||||
case nodes::Loop::LOOP: // infinity loop, no params
|
||||
|
|
@ -214,7 +218,8 @@ nodes::TypeCheckResult type_check_loop(const nodes::Loop &expression,
|
|||
case nodes::Loop::WHILE:
|
||||
/*condition_result = */ type_check_expression(
|
||||
*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));
|
||||
|
||||
// --- type check is independent from loop itself ---
|
||||
// if (condition_result.value().is_invalid()) {
|
||||
|
|
@ -237,8 +242,8 @@ nodes::TypeCheckResult type_check_loop(const nodes::Loop &expression,
|
|||
// TODO: expect range ??
|
||||
interval_result = type_check_expression(
|
||||
*expression.get_interval().value(), sources_manager, state,
|
||||
Arguments::expect_builtin(builtin::types::Type::ARRAY,
|
||||
sources_manager));
|
||||
Arguments{}.expect_builtin(builtin::types::Type::ARRAY,
|
||||
sources_manager));
|
||||
|
||||
if (interval_result.value().is_invalid()) {
|
||||
// --- type check is independent from loop itself ---
|
||||
|
|
@ -248,7 +253,7 @@ nodes::TypeCheckResult type_check_loop(const nodes::Loop &expression,
|
|||
|
||||
variable_result = type_check_expression(
|
||||
*expression.get_variable().value(), sources_manager, state,
|
||||
Arguments::expect(
|
||||
Arguments{}.expect(
|
||||
interval_result.value().get().get()->get_parameter_proxy(0)));
|
||||
|
||||
// --- type check is independent from loop itself ---
|
||||
|
|
@ -279,9 +284,8 @@ nodes::TypeCheckResult type_check_array(const nodes::Container &expression,
|
|||
|
||||
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(*expression.get_expression(i), sources_manager,
|
||||
state, Arguments::nothing());
|
||||
auto expression_result = type_check_expression(
|
||||
*expression.get_expression(i), sources_manager, state, Arguments{});
|
||||
|
||||
if (!last_expression_result.has_value()) {
|
||||
last_expression_result = expression_result;
|
||||
|
|
@ -341,9 +345,8 @@ nodes::TypeCheckResult type_check_return(const nodes::Return &expression,
|
|||
SourcesManager &sources_manager,
|
||||
State &state,
|
||||
const Arguments &arguments) {
|
||||
auto returned_result =
|
||||
type_check_expression(*expression.get_expression(), sources_manager,
|
||||
state, Arguments::nothing());
|
||||
auto returned_result = type_check_expression(
|
||||
*expression.get_expression(), sources_manager, state, Arguments{});
|
||||
|
||||
if (returned_result.is_invalid()) {
|
||||
return returned_result;
|
||||
|
|
@ -418,11 +421,11 @@ nodes::TypeCheckResult type_check_array_access(const nodes::Access &expression,
|
|||
|
||||
auto index_result = type_check_expression(
|
||||
*expression.get_index(), sources_manager, state,
|
||||
Arguments::expect_builtin(builtin::types::Type::INDEX, sources_manager));
|
||||
Arguments{}.expect_builtin(builtin::types::Type::INDEX, sources_manager));
|
||||
|
||||
auto value_result = type_check_expression(
|
||||
*expression.get_value(), sources_manager, state,
|
||||
Arguments::expect_builtin(builtin::types::Type::ARRAY, sources_manager));
|
||||
Arguments{}.expect_builtin(builtin::types::Type::ARRAY, sources_manager));
|
||||
|
||||
if (index_result.is_invalid()) {
|
||||
return index_result;
|
||||
|
|
@ -445,7 +448,7 @@ nodes::TypeCheckResult type_check_tuple_access(const nodes::Access &expression,
|
|||
const Arguments &arguments) {
|
||||
auto value_result = type_check_expression(
|
||||
*expression.get_value(), sources_manager, state,
|
||||
Arguments::expect_builtin(builtin::types::Type::TUPLE, sources_manager));
|
||||
Arguments{}.expect_builtin(builtin::types::Type::TUPLE, sources_manager));
|
||||
|
||||
if (value_result.is_invalid()) {
|
||||
return value_result;
|
||||
|
|
@ -492,9 +495,8 @@ nodes::TypeCheckResult
|
|||
type_check_modifier_expression(const nodes::ModifierExpression &expression,
|
||||
SourcesManager &sources_manager, State &state,
|
||||
const Arguments &arguments) {
|
||||
auto modified_result =
|
||||
type_check_expression(*expression.get_expression(), sources_manager,
|
||||
state, Arguments::nothing());
|
||||
auto modified_result = type_check_expression(
|
||||
*expression.get_expression(), sources_manager, state, Arguments{});
|
||||
|
||||
if (modified_result.is_invalid()) {
|
||||
return nodes::TypeCheckResult::construct_invalid_result();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue