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: 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<nodes::TypeCheckResult> 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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue