From 5afbaf06ae5112b394d5fea8adb7c19cd4074477 Mon Sep 17 00:00:00 2001 From: ProgramSnail Date: Sat, 24 Feb 2024 00:01:18 +0300 Subject: [PATCH] type check: lambda fixes, name expression part --- src/expression_type_check.cpp | 78 ++++++++++++++++++++++++++--------- 1 file changed, 59 insertions(+), 19 deletions(-) diff --git a/src/expression_type_check.cpp b/src/expression_type_check.cpp index 7e89e1b..20bd5ba 100644 --- a/src/expression_type_check.cpp +++ b/src/expression_type_check.cpp @@ -545,6 +545,7 @@ type_check_name_expression(const nodes::NameExpression &expression, // TODO: deal with given ->(out) Args (type not expected, but passed into) // TODO: check, if there is variable with this name + // TODO: check var + fields const auto maybe_function_definition = find_name_definition_handle_errors( *expression.get_name()->get(), expression, sources_manager); if (!maybe_function_definition.has_value()) { @@ -553,14 +554,24 @@ type_check_name_expression(const nodes::NameExpression &expression, const nodes::FunctionDefinition *function_definition = maybe_function_definition.value(); - // + 1 - returned type - if (expression.arguments_size() + 1 != - function_definition - ->arguments_size()) { // other, when there is passed type + // TODO: count passed type, if needed + // TODO: manage situation with one out type at any position + // TODO + 1 - returned type - somtimes (can be ==) + const auto arguments_given = expression.arguments_size(); + const auto arguments_defined = function_definition->arguments_size(); + if (arguments_given + 1 < arguments_defined || + arguments_given > + arguments_defined) { // other, when there is passed type type_check_error( "Number of function arguments is different from expected (" + - std::to_string(expression.arguments_size()) + " instead of " + - std::to_string(function_definition->arguments_size()) + ")", + std::to_string(arguments_given) + " instead of " + + std::to_string(arguments_defined) + + std::string{ + arguments_defined > 0 + ? (" or " + std::to_string( + arguments_defined - 1)) + : ""} + + ")", expression, sources_manager); return nodes::TypeCheckResult::construct_invalid_result(); // TODO: try return correct type (function return type), when possible @@ -569,8 +580,8 @@ type_check_name_expression(const nodes::NameExpression &expression, // TODO: define types for generic function std::vector function_argument_results; - for (size_t i = 0; i < expression.arguments_size(); - ++i) { // TODO: arguments reordering, based on annotations + for (size_t i = 0; i < arguments_given; + ++i) { // TODO: pass types with oud modifier const nodes::FunctionDefinition::Argument *argument = function_definition->get_argument(i); @@ -613,7 +624,8 @@ type_check_name_expression(const nodes::NameExpression &expression, return nodes::TypeCheckResult::construct_invalid_result(); } - { + // TODO: check condition + if (arguments_given + 1 == arguments_defined) { // returned type const nodes::FunctionDefinition::Argument *returned = function_definition->get_argument( @@ -897,7 +909,8 @@ nodes::TypeCheckResult type_check_lambda(const nodes::Lambda &expression, expression, sources_manager); } - if (arguments.get_expected().size() != 1) { + if (arguments.get_expected().size() != + 1) { // TODO: check if only one function argument type_check_error("Can't deduce type of lambda function from context; too " "much possible types", expression, sources_manager); @@ -909,17 +922,44 @@ nodes::TypeCheckResult type_check_lambda(const nodes::Lambda &expression, sources_manager); } - // TODO: define vars - // TODO: expect returned type as type of internal expression - // TODO: merge returned and brought type - // TODO: add context - // auto returned_type = type_check_expression( - // *expression.get_expression(), sources_manager, state, Arguments{}); + // TODO: deal with return type (+1 sometimes), etc + const auto arguments_given = expression.arguments_size(); + const auto arguments_defined = expected_type.get()->parameters_size(); + if (arguments_given != arguments_defined) { + type_check_error( + "Number of function arguments is different from expected (" + + std::to_string(arguments_given) + " instead of " + + std::to_string(arguments_defined) + + std::string{ + arguments_defined > 0 + ? (" or " + std::to_string( + arguments_defined - 1)) + : ""} + + ")", + expression, sources_manager); + } + + // TODO: set another context (for expression typecheck and vars) + + for (size_t i = 0; i < arguments_given; ++i) { + if (!state.insert_variable(*expression.get_argument(i)->get(), + expected_type.get()->get_parameter_proxy(i), + nodes::NameDefinition::Modifier::LET)) { + // TODO: which modifier ?? + type_check_error("Variable is already defined in this context", + expression, sources_manager); + } + } + + // TODO: out type is can be not last + if (arguments_given + 1 == arguments_defined) { + type_check_expression(*expression.get_expression(), sources_manager, state, + Arguments{}.expect(expected_type.get()->get_parameter_proxy(arguments_defined - 1))); + } // TODO: needed ?? (only passed type check required ??) - return type_check_from_arguments( - expected_type, arguments, expression, - sources_manager); // TODO: same to expected ?? + return type_check_from_arguments(expected_type, arguments, expression, + sources_manager); } // IN PROGRESS } // namespace type_check