type check: lambda fixes, name expression part

This commit is contained in:
ProgramSnail 2024-02-24 00:01:18 +03:00
parent d8ef39b2bd
commit 5afbaf06ae

View file

@ -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: deal with given ->(out) Args (type not expected, but passed into)
// TODO: check, if there is variable with this name // TODO: check, if there is variable with this name
// TODO: check var + fields
const auto maybe_function_definition = find_name_definition_handle_errors( const auto maybe_function_definition = find_name_definition_handle_errors(
*expression.get_name()->get(), expression, sources_manager); *expression.get_name()->get(), expression, sources_manager);
if (!maybe_function_definition.has_value()) { if (!maybe_function_definition.has_value()) {
@ -553,14 +554,24 @@ type_check_name_expression(const nodes::NameExpression &expression,
const nodes::FunctionDefinition *function_definition = const nodes::FunctionDefinition *function_definition =
maybe_function_definition.value(); maybe_function_definition.value();
// + 1 - returned type // TODO: count passed type, if needed
if (expression.arguments_size() + 1 != // TODO: manage situation with one out type at any position
function_definition // TODO + 1 - returned type - somtimes (can be ==)
->arguments_size()) { // other, when there is passed type 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( type_check_error(
"Number of function arguments is different from expected (" + "Number of function arguments is different from expected (" +
std::to_string(expression.arguments_size()) + " instead of " + std::to_string(arguments_given) + " instead of " +
std::to_string(function_definition->arguments_size()) + ")", std::to_string(arguments_defined) +
std::string{
arguments_defined > 0
? (" or " + std::to_string(
arguments_defined - 1))
: ""} +
")",
expression, sources_manager); expression, sources_manager);
return nodes::TypeCheckResult::construct_invalid_result(); return nodes::TypeCheckResult::construct_invalid_result();
// TODO: try return correct type (function return type), when possible // 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 // TODO: define types for generic function
std::vector<nodes::TypeCheckResult> function_argument_results; std::vector<nodes::TypeCheckResult> function_argument_results;
for (size_t i = 0; i < expression.arguments_size(); for (size_t i = 0; i < arguments_given;
++i) { // TODO: arguments reordering, based on annotations ++i) { // TODO: pass types with oud modifier
const nodes::FunctionDefinition::Argument *argument = const nodes::FunctionDefinition::Argument *argument =
function_definition->get_argument(i); function_definition->get_argument(i);
@ -613,7 +624,8 @@ type_check_name_expression(const nodes::NameExpression &expression,
return nodes::TypeCheckResult::construct_invalid_result(); return nodes::TypeCheckResult::construct_invalid_result();
} }
{ // TODO: check condition
if (arguments_given + 1 == arguments_defined) {
// returned type // returned type
const nodes::FunctionDefinition::Argument *returned = const nodes::FunctionDefinition::Argument *returned =
function_definition->get_argument( function_definition->get_argument(
@ -897,7 +909,8 @@ nodes::TypeCheckResult type_check_lambda(const nodes::Lambda &expression,
expression, sources_manager); 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 " type_check_error("Can't deduce type of lambda function from context; too "
"much possible types", "much possible types",
expression, sources_manager); expression, sources_manager);
@ -909,17 +922,44 @@ nodes::TypeCheckResult type_check_lambda(const nodes::Lambda &expression,
sources_manager); sources_manager);
} }
// TODO: define vars // TODO: deal with return type (+1 sometimes), etc
// TODO: expect returned type as type of internal expression const auto arguments_given = expression.arguments_size();
// TODO: merge returned and brought type const auto arguments_defined = expected_type.get()->parameters_size();
// TODO: add context if (arguments_given != arguments_defined) {
// auto returned_type = type_check_expression( type_check_error(
// *expression.get_expression(), sources_manager, state, Arguments{}); "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 ??) // TODO: needed ?? (only passed type check required ??)
return type_check_from_arguments( return type_check_from_arguments(expected_type, arguments, expression,
expected_type, arguments, expression, sources_manager);
sources_manager); // TODO: same to expected ??
} // IN PROGRESS } // IN PROGRESS
} // namespace type_check } // namespace type_check