From 070b08dba406068c55bcb799ca6f827450a45fdd Mon Sep 17 00:00:00 2001 From: ProgramSnail Date: Mon, 12 Feb 2024 23:43:43 +0300 Subject: [PATCH] Arguments: change structure, pass in match (v0) --- include/type_check_utils.hpp | 49 +++++++++++------------ src/expression_type_check.cpp | 74 ++++++++++++++++++----------------- 2 files changed, 61 insertions(+), 62 deletions(-) diff --git a/include/type_check_utils.hpp b/include/type_check_utils.hpp index ae0abb1..a4b5b24 100644 --- a/include/type_check_utils.hpp +++ b/include/type_check_utils.hpp @@ -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_ = {}; diff --git a/src/expression_type_check.cpp b/src/expression_type_check.cpp index 2bb01c7..dc8baf5 100644 --- a/src/expression_type_check.cpp +++ b/src/expression_type_check.cpp @@ -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 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 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();