mirror of
https://codeberg.org/ProgramSnail/lang.git
synced 2025-12-05 22:48:43 +00:00
type check: lambda fixes, name expression part
This commit is contained in:
parent
d8ef39b2bd
commit
5afbaf06ae
1 changed files with 59 additions and 19 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue