type check expressions: type_check_name_expression and type_check_constructor parts

This commit is contained in:
ProgramSnail 2024-02-20 23:25:51 +03:00
parent ed4b984b81
commit a5fc0c7ee7
4 changed files with 149 additions and 22 deletions

View file

@ -219,6 +219,13 @@ public:
return std::nullopt;
}
std::optional<TypeProxy> get_type_proxy() const {
if (type_.has_value()) {
return type_.value();
}
return std::nullopt;
}
//
Modifier get_before_modifier() const { return before_modifier_; }

View file

@ -221,7 +221,7 @@ find_type_definition_handle_errors(const std::string &name,
const nodes::Node &node,
SourcesManager &sources_manager);
std::optional<const nodes::NameDefinition *>
std::optional<const nodes::FunctionDefinition *>
find_name_definition_handle_errors(const std::string &name,
const nodes::Node &node,
SourcesManager &sources_manager);

View file

@ -538,15 +538,112 @@ type_check_modifier_expression(const nodes::ModifierExpression &expression,
nodes::TypeCheckResult
type_check_name_expression(const nodes::NameExpression &expression,
SourcesManager &sources_manager, State &state,
const Arguments &arguments) {} // IN PROGRESS
const Arguments &arguments) {
// TODO: constraints ??
// TODO: deal with passed type
// TODO: check, if there is variable with this name
const auto maybe_function_definition = find_name_definition_handle_errors(
*expression.get_name()->get(), expression, sources_manager);
if (!maybe_function_definition.has_value()) {
return nodes::TypeCheckResult::construct_invalid_result();
}
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
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()) + ")",
expression, sources_manager);
return nodes::TypeCheckResult::construct_invalid_result();
// TODO: try return correct type (function return type), when possible
}
// 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
const nodes::FunctionDefinition::Argument *argument =
function_definition->get_argument(i);
if (!argument->get_type().has_value()) {
type_check_error("Function argument type is not defined for argument " +
std::to_string(i),
expression, sources_manager);
continue;
}
const auto annotation = expression.get_argument_annotation(i);
const auto expected_annotation = argument->get_annotation();
if (annotation.has_value() != expected_annotation.has_value()) {
type_check_error("Wrong function argument annotation: should be " +
std::string{expected_annotation.has_value()
? *expected_annotation.value()
: "[none]"},
*expression.get_argument_value(i), sources_manager);
}
if (annotation.has_value() &&
*annotation.value() != *expected_annotation.value()) {
type_check_error(
"Wrong function argument type annotation: " + *annotation.value() +
" instead of " + *expected_annotation.value(),
*expression.get_argument_value(i), sources_manager);
}
function_argument_results.push_back(type_check_expression(
*expression.get_argument_value(i), sources_manager, state,
Arguments{}.expect(argument->get_type_proxy().value())));
}
if (function_definition->arguments_size() == 0) {
type_check_error(
"Function arguments size is zero. Returned type is not defined",
expression, sources_manager);
return nodes::TypeCheckResult::construct_invalid_result();
}
{
// returned type
const nodes::FunctionDefinition::Argument *returned =
function_definition->get_argument(
function_definition->arguments_size() - 1);
// TODO: invert modifier ??
if (!returned->get_type().has_value()) {
type_check_error(
"Function argument type is not defined for returned type", expression,
sources_manager);
return nodes::TypeCheckResult::construct_invalid_result();
}
// TODO: invert modifier ??
// TODO: generic types should be deduced from arguments
return type_same_to_expected(returned->get_type_proxy().value(),
arguments.get_expected(), expression,
*sources_manager.get_error_log());
}
// checks for universal call syntax ??
} // IN PROGRESS
// TODO
nodes::TypeCheckResult
type_check_constructor(const nodes::Constructor &expression,
SourcesManager &sources_manager, State &state,
const Arguments &arguments) {
check_no_pass_type_in_arguments(arguments, expression, sources_manager);
// TODO: constraints ??
// TODO: use pass type
const auto maybe_type_definition = find_type_definition_handle_errors(
*expression.get_type()->get_name()->get(), expression, sources_manager);
if (!maybe_type_definition.has_value()) {
@ -561,37 +658,60 @@ type_check_constructor(const nodes::Constructor &expression,
return nodes::TypeCheckResult::construct_invalid_result();
}
// TODO: chack that is not typeclass ??
// TODO: deal with anniotations, recursive annotations
// TODO: type arguments substitution (deduce argument type values ??)
for (size_t i = 0; i < type_definition->arguments_size(); ++i) {
// TODO: ...
}
// TODO: check that is not typeclass ??
nodes::TypeProxy type = type_definition->get_type().value();
// TODO: work with different parametric types: tuple, variant, ...
if (type.get()->parameters_size() != expression.arguments_size()) {
type_check_error("Constructor arguments count is " +
std::string{expression.arguments_size() <
type.get()->parameters_size()
? "less"
: "more"} +
" then type fields count",
if (expression.arguments_size() !=
type.get()->parameters_size()) { // other, when there is passed type
type_check_error(
"Number of type constructor arguments is different from expected (" +
std::to_string(expression.arguments_size()) + " instead of " +
std::to_string(type.get()->parameters_size()) + ")",
expression, sources_manager);
return nodes::TypeCheckResult::construct_invalid_result();
// TODO: try return correct type (constructor's type), when possible (not
// generic)
}
// TODO: work with generics (type_definition->arguments, ...)
// for tuple
for (size_t i = 0; i < expression.arguments_size(); ++i) {
for (size_t i = 0; i < expression.arguments_size();
++i) { // TODO: deduce order by annotations
const auto annotation = expression.get_argument_annotation(i);
const auto expected_annotation =
type.get()->get_parameter(i)->get_annotation();
auto argument_type = type_check_expression(
*expression.get_argument_value(i), sources_manager, state,
/* TODO: type from definition by annotation */);
if (annotation.has_value() != expected_annotation.has_value()) {
type_check_error(
"Wrong type constructor argument annotation: should be " +
std::string{expected_annotation.has_value()
? *expected_annotation.value()
: "[none]"},
*expression.get_argument_value(i), sources_manager);
}
// TODO: expect types of arguments by type definition
if (annotation.has_value() &&
*annotation.value() != *expected_annotation.value()) {
type_check_error(
"Wrong function argument type annotation: " + *annotation.value() +
" instead of " + *expected_annotation.value(),
*expression.get_argument_value(i), sources_manager);
}
type_check_expression(
*expression.get_argument_value(i), sources_manager, state,
Arguments{}.expect(type.get()->get_parameter_proxy(i)));
// TODO: do something with argument type ??
}
// TODO: deduce generic parts in type
return type_same_to_expected(expression.get_type_proxy(),
arguments.get_expected(), expression,
*sources_manager.get_error_log());

View file

@ -56,11 +56,11 @@ find_type_definition_handle_errors(const std::string &name,
"Node in name tree is not type definition");
}
std::optional<const nodes::NameDefinition *>
std::optional<const nodes::FunctionDefinition *>
find_name_definition_handle_errors(const std::string &name,
const nodes::Node &node,
SourcesManager &sources_manager) {
return find_statement_handle_errors<nodes::NameDefinition>(
return find_statement_handle_errors<nodes::FunctionDefinition>(
name, node, sources_manager, "No name definition found in name tree",
"Node in name tree is not name definition");
}