mirror of
https://codeberg.org/ProgramSnail/lang.git
synced 2025-12-06 15:08:48 +00:00
ERROR type, check of passed type, many expected types in Arguments
This commit is contained in:
parent
a5fc0c7ee7
commit
005fb6aaf3
7 changed files with 200 additions and 112 deletions
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "basic_nodes.hpp"
|
#include "basic_nodes.hpp"
|
||||||
#include "sources_manager.hpp"
|
#include "sources_manager.hpp"
|
||||||
|
#include "type_check_utils.hpp"
|
||||||
|
|
||||||
namespace type_check {
|
namespace type_check {
|
||||||
|
|
||||||
|
|
@ -9,6 +10,6 @@ namespace type_check {
|
||||||
nodes::TypeCheckResult
|
nodes::TypeCheckResult
|
||||||
type_check_literal(const nodes::Literal &literal,
|
type_check_literal(const nodes::Literal &literal,
|
||||||
SourcesManager &sources_manager,
|
SourcesManager &sources_manager,
|
||||||
nodes::MaybeTypeProxy expected_type);
|
const Arguments& arguments);
|
||||||
|
|
||||||
} // namespace type_check
|
} // namespace type_check
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ const static std::string OPTIONAL_IDENTIFIER = "Optional";
|
||||||
|
|
||||||
const static std::string RESULT_IDENTIFIER = "Result";
|
const static std::string RESULT_IDENTIFIER = "Result";
|
||||||
|
|
||||||
|
const static std::string ERROR_IDENTIFIER = "Error";
|
||||||
|
|
||||||
// -- basic types
|
// -- basic types
|
||||||
|
|
||||||
const static std::string FLOAT_IDENTIFIER = "Float";
|
const static std::string FLOAT_IDENTIFIER = "Float";
|
||||||
|
|
@ -56,6 +58,7 @@ enum class Type {
|
||||||
ARRAY,
|
ARRAY,
|
||||||
OPTIONAL,
|
OPTIONAL,
|
||||||
RESULT,
|
RESULT,
|
||||||
|
ERROR,
|
||||||
// -- basic types
|
// -- basic types
|
||||||
FLOAT,
|
FLOAT,
|
||||||
DOUBLE,
|
DOUBLE,
|
||||||
|
|
@ -86,6 +89,8 @@ inline std::string to_string(Type type) {
|
||||||
return OPTIONAL_IDENTIFIER;
|
return OPTIONAL_IDENTIFIER;
|
||||||
case Type::RESULT:
|
case Type::RESULT:
|
||||||
return RESULT_IDENTIFIER;
|
return RESULT_IDENTIFIER;
|
||||||
|
case Type::ERROR:
|
||||||
|
return ERROR_IDENTIFIER;
|
||||||
// -- basic types
|
// -- basic types
|
||||||
case Type::FLOAT:
|
case Type::FLOAT:
|
||||||
return FLOAT_IDENTIFIER;
|
return FLOAT_IDENTIFIER;
|
||||||
|
|
@ -127,6 +132,7 @@ inline Type to_type(const std::string &str) {
|
||||||
builtin_types[ARRAY_IDENTIFIER] = Type::ARRAY;
|
builtin_types[ARRAY_IDENTIFIER] = Type::ARRAY;
|
||||||
builtin_types[OPTIONAL_IDENTIFIER] = Type::OPTIONAL;
|
builtin_types[OPTIONAL_IDENTIFIER] = Type::OPTIONAL;
|
||||||
builtin_types[RESULT_IDENTIFIER] = Type::RESULT;
|
builtin_types[RESULT_IDENTIFIER] = Type::RESULT;
|
||||||
|
builtin_types[ERROR_IDENTIFIER] = Type::ERROR;
|
||||||
|
|
||||||
// -- basic types
|
// -- basic types
|
||||||
builtin_types[FLOAT_IDENTIFIER] = Type::FLOAT;
|
builtin_types[FLOAT_IDENTIFIER] = Type::FLOAT;
|
||||||
|
|
@ -172,6 +178,7 @@ inline std::optional<size_t> get_parameters_count(Type type) {
|
||||||
case Type::ARRAY:
|
case Type::ARRAY:
|
||||||
case Type::OPTIONAL:
|
case Type::OPTIONAL:
|
||||||
case Type::RESULT:
|
case Type::RESULT:
|
||||||
|
case Type::ERROR:
|
||||||
return 1;
|
return 1;
|
||||||
// -- basic types
|
// -- basic types
|
||||||
case Type::FLOAT:
|
case Type::FLOAT:
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
using MaybeTypeProxy = std::optional<TypeProxy>;
|
using MaybeTypeProxy = std::optional<TypeProxy>;
|
||||||
|
using TypeProxies = std::vector<TypeProxy>;
|
||||||
|
|
||||||
class Type {
|
class Type {
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -147,8 +147,9 @@ public:
|
||||||
Arguments expect_builtin(builtin::types::Type type,
|
Arguments expect_builtin(builtin::types::Type type,
|
||||||
SourcesManager &sources_manager) const {
|
SourcesManager &sources_manager) const {
|
||||||
Arguments copy(*this);
|
Arguments copy(*this);
|
||||||
copy.expected_type_ =
|
copy.expected_types_ = {
|
||||||
sources_manager.get_type_storage()->primitive_type(type);
|
sources_manager.get_type_storage()->primitive_type(type)};
|
||||||
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
Arguments pass_builtin(builtin::types::Type type,
|
Arguments pass_builtin(builtin::types::Type type,
|
||||||
|
|
@ -159,9 +160,15 @@ public:
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Arguments expect(nodes::TypeProxies types) const {
|
||||||
|
Arguments copy(*this);
|
||||||
|
copy.expected_types_ = types;
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
Arguments expect(nodes::MaybeTypeProxy type) const {
|
Arguments expect(nodes::MaybeTypeProxy type) const {
|
||||||
Arguments copy(*this);
|
Arguments copy(*this);
|
||||||
copy.expected_type_ = type;
|
copy.expected_types_ = (type.has_value() ? nodes::TypeProxies{type.value()} : nodes::TypeProxies{});
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -171,7 +178,19 @@ public:
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes::MaybeTypeProxy get_expected() const { return expected_type_; };
|
Arguments without_expect() const {
|
||||||
|
Arguments copy(*this);
|
||||||
|
copy.expected_types_ = {};
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
Arguments without_pass() const {
|
||||||
|
Arguments copy(*this);
|
||||||
|
copy.passed_type_ = {};
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
nodes::TypeProxies get_expected() const { return expected_types_; };
|
||||||
|
|
||||||
nodes::MaybeTypeProxy get_passed() const { return passed_type_; };
|
nodes::MaybeTypeProxy get_passed() const { return passed_type_; };
|
||||||
|
|
||||||
|
|
@ -179,8 +198,8 @@ public:
|
||||||
// TODO: arguments builder ??
|
// TODO: arguments builder ??
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nodes::MaybeTypeProxy expected_type_ = {};
|
nodes::TypeProxies expected_types_;
|
||||||
nodes::MaybeTypeProxy passed_type_ = {};
|
nodes::MaybeTypeProxy passed_type_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ContextHolder {
|
class ContextHolder {
|
||||||
|
|
@ -211,11 +230,25 @@ private:
|
||||||
nodes::MaybeTypeProxy *context_exit_type_;
|
nodes::MaybeTypeProxy *context_exit_type_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
nodes::TypeProxy check_same_to_pass_type_in_arguments(
|
||||||
|
nodes::TypeProxy type, const Arguments &arguments, const nodes::Node &node,
|
||||||
|
SourcesManager &sources_manager,
|
||||||
|
const std::string &message = "Different type with passed one");
|
||||||
|
|
||||||
|
// bool check_no_pass_type_in_arguments(
|
||||||
|
// const Arguments &arguments, const nodes::Node &node,
|
||||||
|
// SourcesManager &sources_manager,
|
||||||
|
// const std::string &message = "Type can't be passed to this node");
|
||||||
|
|
||||||
nodes::TypeCheckResult type_same_to_expected(
|
nodes::TypeCheckResult type_same_to_expected(
|
||||||
nodes::TypeProxy type, nodes::MaybeTypeProxy expected_type,
|
nodes::TypeProxy type, const Arguments& argumensr,
|
||||||
const nodes::Node &node, error_handling::ErrorLog &error_log,
|
const nodes::Node &node, SourcesManager &sources_manager,
|
||||||
const std::string &message = "Different type with expected one");
|
const std::string &message = "Different type with expected one");
|
||||||
|
|
||||||
|
nodes::TypeCheckResult type_check_from_arguments(
|
||||||
|
nodes::TypeProxy type, const Arguments& arguments,
|
||||||
|
const nodes::Node &node, SourcesManager &sources_manager);
|
||||||
|
|
||||||
std::optional<const nodes::TypeDefinition *>
|
std::optional<const nodes::TypeDefinition *>
|
||||||
find_type_definition_handle_errors(const std::string &name,
|
find_type_definition_handle_errors(const std::string &name,
|
||||||
const nodes::Node &node,
|
const nodes::Node &node,
|
||||||
|
|
@ -229,8 +262,4 @@ find_name_definition_handle_errors(const std::string &name,
|
||||||
void type_check_error(const std::string &message, const nodes::Node &node,
|
void type_check_error(const std::string &message, const nodes::Node &node,
|
||||||
SourcesManager &sources_manager);
|
SourcesManager &sources_manager);
|
||||||
|
|
||||||
bool check_no_pass_type_in_arguments(const Arguments &arguments,
|
|
||||||
const nodes::Node &node,
|
|
||||||
SourcesManager &sources_manager);
|
|
||||||
|
|
||||||
} // namespace type_check
|
} // namespace type_check
|
||||||
|
|
|
||||||
|
|
@ -51,13 +51,9 @@ nodes::TypeProxy get_literal_type(const nodes::Literal &literal,
|
||||||
|
|
||||||
nodes::TypeCheckResult type_check_literal(const nodes::Literal &literal,
|
nodes::TypeCheckResult type_check_literal(const nodes::Literal &literal,
|
||||||
SourcesManager &sources_manager,
|
SourcesManager &sources_manager,
|
||||||
nodes::MaybeTypeProxy expected_type) {
|
const Arguments &arguments) {
|
||||||
auto const type = get_literal_type(literal, sources_manager);
|
auto const type = get_literal_type(literal, sources_manager);
|
||||||
if (expected_type.has_value() && type != expected_type.value()) {
|
return type_same_to_expected(type, arguments, literal, sources_manager);
|
||||||
return nodes::TypeCheckResult::construct_invalid_result();
|
|
||||||
// nodes::TypeCheckResult::fail_with(type, expected_type, literal); // TODO: create error ??
|
|
||||||
}
|
|
||||||
return nodes::TypeCheckResult(type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace type_check
|
} // namespace type_check
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ type_check_expression(const nodes::Expression &expression,
|
||||||
case 12: // Literal
|
case 12: // Literal
|
||||||
// TODO
|
// TODO
|
||||||
return type_check_literal(*expression.get<nodes::Literal>().value(),
|
return type_check_literal(*expression.get<nodes::Literal>().value(),
|
||||||
sources_manager, arguments.get_expected());
|
sources_manager, arguments);
|
||||||
// --- empty lines
|
// --- empty lines
|
||||||
case 13: // Extra
|
case 13: // Extra
|
||||||
return nodes::TypeCheckResult(
|
return nodes::TypeCheckResult(
|
||||||
|
|
@ -153,10 +153,10 @@ nodes::TypeCheckResult type_check_match(const nodes::Match &expression,
|
||||||
builtin::types::Type::UNIT)};
|
builtin::types::Type::UNIT)};
|
||||||
}
|
}
|
||||||
|
|
||||||
return type_same_to_expected(sources_manager.get_type_storage()->add_array_of(
|
return type_check_from_arguments(
|
||||||
|
sources_manager.get_type_storage()->add_array_of(
|
||||||
expression_result.value().get()),
|
expression_result.value().get()),
|
||||||
arguments.get_expected(), expression,
|
arguments, expression, sources_manager);
|
||||||
*sources_manager.get_error_log());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes::TypeCheckResult type_check_condition(const nodes::Condition &expression,
|
nodes::TypeCheckResult type_check_condition(const nodes::Condition &expression,
|
||||||
|
|
@ -196,10 +196,10 @@ nodes::TypeCheckResult type_check_condition(const nodes::Condition &expression,
|
||||||
expression_result = nodes::TypeCheckResult::construct_invalid_result();
|
expression_result = nodes::TypeCheckResult::construct_invalid_result();
|
||||||
}
|
}
|
||||||
|
|
||||||
return type_same_to_expected(sources_manager.get_type_storage()->add_array_of(
|
return type_check_from_arguments(
|
||||||
|
sources_manager.get_type_storage()->add_array_of(
|
||||||
expression_result.value().get()),
|
expression_result.value().get()),
|
||||||
arguments.get_expected(), expression,
|
arguments, expression, sources_manager);
|
||||||
*sources_manager.get_error_log());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes::TypeCheckResult type_check_loop(const nodes::Loop &expression,
|
nodes::TypeCheckResult type_check_loop(const nodes::Loop &expression,
|
||||||
|
|
@ -261,9 +261,9 @@ nodes::TypeCheckResult type_check_loop(const nodes::Loop &expression,
|
||||||
|
|
||||||
// TODO: modifier checks ??, modifiers ??
|
// TODO: modifier checks ??, modifiers ??
|
||||||
|
|
||||||
return type_same_to_expected(
|
return type_check_from_arguments(
|
||||||
sources_manager.get_type_storage()->add_array_of(expression_result.get()),
|
sources_manager.get_type_storage()->add_array_of(expression_result.get()),
|
||||||
arguments.get_expected(), expression, *sources_manager.get_error_log());
|
arguments, expression, sources_manager);
|
||||||
} // IN PROGRESS
|
} // IN PROGRESS
|
||||||
|
|
||||||
// --- containers
|
// --- containers
|
||||||
|
|
@ -296,10 +296,10 @@ nodes::TypeCheckResult type_check_array(const nodes::Container &expression,
|
||||||
return nodes::TypeCheckResult::construct_invalid_result();
|
return nodes::TypeCheckResult::construct_invalid_result();
|
||||||
}
|
}
|
||||||
|
|
||||||
return type_same_to_expected(sources_manager.get_type_storage()->add_array_of(
|
return type_check_from_arguments(
|
||||||
|
sources_manager.get_type_storage()->add_array_of(
|
||||||
last_expression_result.value().get()),
|
last_expression_result.value().get()),
|
||||||
arguments.get_expected(), expression,
|
arguments, expression, sources_manager);
|
||||||
*sources_manager.get_error_log());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes::TypeCheckResult type_check_block(const nodes::Container &expression,
|
nodes::TypeCheckResult type_check_block(const nodes::Container &expression,
|
||||||
|
|
@ -327,10 +327,10 @@ nodes::TypeCheckResult type_check_block(const nodes::Container &expression,
|
||||||
sources_manager.get_type_storage()->primitive_type(
|
sources_manager.get_type_storage()->primitive_type(
|
||||||
builtin::types::Type::UNIT));
|
builtin::types::Type::UNIT));
|
||||||
|
|
||||||
return type_same_to_expected(sources_manager.get_type_storage()->add_array_of(
|
return type_check_from_arguments(
|
||||||
|
sources_manager.get_type_storage()->add_array_of(
|
||||||
block_brought_type.get()),
|
block_brought_type.get()),
|
||||||
arguments.get_expected(), expression,
|
arguments, expression, sources_manager);
|
||||||
*sources_manager.get_error_log());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes::TypeCheckResult type_check_container(const nodes::Container &expression,
|
nodes::TypeCheckResult type_check_container(const nodes::Container &expression,
|
||||||
|
|
@ -375,10 +375,10 @@ nodes::TypeCheckResult type_check_return(const nodes::Return &expression,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return type_same_to_expected(
|
return type_check_from_arguments(
|
||||||
sources_manager.get_type_storage()->primitive_type(
|
sources_manager.get_type_storage()->primitive_type(
|
||||||
builtin::types::Type::UNIT),
|
builtin::types::Type::UNIT),
|
||||||
arguments.get_expected(), expression, *sources_manager.get_error_log());
|
arguments, expression, sources_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes::TypeCheckResult
|
nodes::TypeCheckResult
|
||||||
|
|
@ -410,10 +410,10 @@ type_check_name_definition(const nodes::NameDefinition &expression,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return BOOL as any := / =: expression
|
// Return BOOL as any := / =: expression
|
||||||
return type_same_to_expected(
|
return type_check_from_arguments(
|
||||||
sources_manager.get_type_storage()->primitive_type(
|
sources_manager.get_type_storage()->primitive_type(
|
||||||
builtin::types::Type::BOOL),
|
builtin::types::Type::BOOL),
|
||||||
arguments.get_expected(), expression, *sources_manager.get_error_log());
|
arguments, expression, sources_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes::TypeCheckResult type_check_array_access(const nodes::Access &expression,
|
nodes::TypeCheckResult type_check_array_access(const nodes::Access &expression,
|
||||||
|
|
@ -439,9 +439,9 @@ nodes::TypeCheckResult type_check_array_access(const nodes::Access &expression,
|
||||||
|
|
||||||
// TODO: modifier checks ??
|
// TODO: modifier checks ??
|
||||||
|
|
||||||
return type_same_to_expected(value_result.get().get()->get_parameter_proxy(0),
|
return type_check_from_arguments(
|
||||||
arguments.get_expected(), expression,
|
value_result.get().get()->get_parameter_proxy(0), arguments, expression,
|
||||||
*sources_manager.get_error_log());
|
sources_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes::TypeCheckResult type_check_tuple_access(const nodes::Access &expression,
|
nodes::TypeCheckResult type_check_tuple_access(const nodes::Access &expression,
|
||||||
|
|
@ -464,9 +464,9 @@ nodes::TypeCheckResult type_check_tuple_access(const nodes::Access &expression,
|
||||||
|
|
||||||
// TODO: modifier checks ??
|
// TODO: modifier checks ??
|
||||||
|
|
||||||
return type_same_to_expected(
|
return type_check_from_arguments(
|
||||||
value_result.get().get()->get_parameter_proxy(index),
|
value_result.get().get()->get_parameter_proxy(index), arguments,
|
||||||
arguments.get_expected(), expression, *sources_manager.get_error_log());
|
expression, sources_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes::TypeCheckResult type_check_access(const nodes::Access &expression,
|
nodes::TypeCheckResult type_check_access(const nodes::Access &expression,
|
||||||
|
|
@ -487,10 +487,10 @@ nodes::TypeCheckResult
|
||||||
type_check_loop_control(const nodes::LoopControl &expression,
|
type_check_loop_control(const nodes::LoopControl &expression,
|
||||||
SourcesManager &sources_manager, State &,
|
SourcesManager &sources_manager, State &,
|
||||||
const Arguments &arguments) {
|
const Arguments &arguments) {
|
||||||
return type_same_to_expected(
|
return type_check_from_arguments(
|
||||||
sources_manager.get_type_storage()->primitive_type(
|
sources_manager.get_type_storage()->primitive_type(
|
||||||
builtin::types::Type::UNIT),
|
builtin::types::Type::UNIT),
|
||||||
arguments.get_expected(), expression, *sources_manager.get_error_log());
|
arguments, expression, sources_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes::TypeCheckResult
|
nodes::TypeCheckResult
|
||||||
|
|
@ -528,8 +528,8 @@ type_check_modifier_expression(const nodes::ModifierExpression &expression,
|
||||||
modified_result.get(), expression.get_modifier()));
|
modified_result.get(), expression.get_modifier()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return type_same_to_expected(modified_result.get(), arguments.get_expected(),
|
return type_check_from_arguments(modified_result.get(), arguments, expression,
|
||||||
expression, *sources_manager.get_error_log());
|
sources_manager);
|
||||||
} // IN PROGRESS
|
} // IN PROGRESS
|
||||||
|
|
||||||
// --- other
|
// --- other
|
||||||
|
|
@ -628,9 +628,8 @@ type_check_name_expression(const nodes::NameExpression &expression,
|
||||||
|
|
||||||
// TODO: invert modifier ??
|
// TODO: invert modifier ??
|
||||||
// TODO: generic types should be deduced from arguments
|
// TODO: generic types should be deduced from arguments
|
||||||
return type_same_to_expected(returned->get_type_proxy().value(),
|
return type_check_from_arguments(returned->get_type_proxy().value(),
|
||||||
arguments.get_expected(), expression,
|
arguments, expression, sources_manager);
|
||||||
*sources_manager.get_error_log());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// checks for universal call syntax ??
|
// checks for universal call syntax ??
|
||||||
|
|
@ -680,6 +679,10 @@ type_check_constructor(const nodes::Constructor &expression,
|
||||||
|
|
||||||
// TODO: work with generics (type_definition->arguments, ...)
|
// TODO: work with generics (type_definition->arguments, ...)
|
||||||
|
|
||||||
|
const auto builtin_type = type.get()->to_builtin();
|
||||||
|
|
||||||
|
switch (builtin_type) {
|
||||||
|
case builtin::types::Type::TUPLE:
|
||||||
// for tuple
|
// for tuple
|
||||||
for (size_t i = 0; i < expression.arguments_size();
|
for (size_t i = 0; i < expression.arguments_size();
|
||||||
++i) { // TODO: deduce order by annotations
|
++i) { // TODO: deduce order by annotations
|
||||||
|
|
@ -710,11 +713,33 @@ type_check_constructor(const nodes::Constructor &expression,
|
||||||
Arguments{}.expect(type.get()->get_parameter_proxy(i)));
|
Arguments{}.expect(type.get()->get_parameter_proxy(i)));
|
||||||
// TODO: do something with argument type ??
|
// TODO: do something with argument type ??
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case builtin::types::Type::VARIANT:
|
||||||
|
// TODO: expect one of types
|
||||||
|
break;
|
||||||
|
case builtin::types::Type::OPTIONAL:
|
||||||
|
// TODO: expect type (generic) or NULL
|
||||||
|
break;
|
||||||
|
case builtin::types::Type::RESULT:
|
||||||
|
// TODO: expect ERROR or type (generic)
|
||||||
|
break;
|
||||||
|
case builtin::types::Type::ERROR:
|
||||||
|
// TODO: expect type (generic)
|
||||||
|
break;
|
||||||
|
case builtin::types::Type::FUNCTION:
|
||||||
|
// TODO: built from one value (function)
|
||||||
|
break;
|
||||||
|
case builtin::types::Type::NONE:
|
||||||
|
// TODO: built from one value
|
||||||
|
break;
|
||||||
|
default: // array, basic types
|
||||||
|
type_check_error("Type can't be constructed", expression, sources_manager);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: deduce generic parts in type
|
// TODO: deduce generic parts in type
|
||||||
return type_same_to_expected(expression.get_type_proxy(),
|
return type_check_from_arguments(expression.get_type_proxy(), arguments,
|
||||||
arguments.get_expected(), expression,
|
expression, sources_manager);
|
||||||
*sources_manager.get_error_log());
|
|
||||||
// TODO: add <- modifiier to type ??
|
// TODO: add <- modifiier to type ??
|
||||||
|
|
||||||
} // IN PROGRESS
|
} // IN PROGRESS
|
||||||
|
|
@ -724,12 +749,19 @@ nodes::TypeCheckResult type_check_lambda(const nodes::Lambda &expression,
|
||||||
SourcesManager &sources_manager,
|
SourcesManager &sources_manager,
|
||||||
State &state,
|
State &state,
|
||||||
const Arguments &arguments) {
|
const Arguments &arguments) {
|
||||||
if (!arguments.get_expected().has_value()) {
|
if (arguments.get_expected().empty()) {
|
||||||
type_check_error("Can't deduce type of lambda function from context",
|
type_check_error("Can't deduce type of lambda function from context: no "
|
||||||
|
"one type expected",
|
||||||
expression, sources_manager);
|
expression, sources_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto expected_type = arguments.get_expected().value();
|
if (arguments.get_expected().size() != 1) {
|
||||||
|
type_check_error("Can't deduce type of lambda function from context; too "
|
||||||
|
"much possible types",
|
||||||
|
expression, sources_manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto expected_type = arguments.get_expected().front();
|
||||||
if (!expected_type.get()->is_builtin(builtin::types::Type::FUNCTION)) {
|
if (!expected_type.get()->is_builtin(builtin::types::Type::FUNCTION)) {
|
||||||
type_check_error("Type of lambda function should be function", expression,
|
type_check_error("Type of lambda function should be function", expression,
|
||||||
sources_manager);
|
sources_manager);
|
||||||
|
|
@ -742,7 +774,10 @@ nodes::TypeCheckResult type_check_lambda(const nodes::Lambda &expression,
|
||||||
// auto returned_type = type_check_expression(
|
// auto returned_type = type_check_expression(
|
||||||
// *expression.get_expression(), sources_manager, state, Arguments{});
|
// *expression.get_expression(), sources_manager, state, Arguments{});
|
||||||
|
|
||||||
return nodes::TypeCheckResult{expected_type}; // TODO: same to expected ??
|
// TODO: needed ?? (only passed type check required ??)
|
||||||
|
return type_check_from_arguments(
|
||||||
|
expected_type, arguments, expression,
|
||||||
|
sources_manager); // TODO: same to expected ??
|
||||||
} // IN PROGRESS
|
} // IN PROGRESS
|
||||||
|
|
||||||
} // namespace type_check
|
} // namespace type_check
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,54 @@
|
||||||
#include "type_check_utils.hpp"
|
#include "type_check_utils.hpp"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace type_check {
|
namespace type_check {
|
||||||
|
|
||||||
nodes::TypeCheckResult type_same_to_expected(
|
// pass type -> compare types, return bool
|
||||||
nodes::TypeProxy type, nodes::MaybeTypeProxy expected_type,
|
// no pass type -> return type
|
||||||
const nodes::Node &node, error_handling::ErrorLog &error_log,
|
nodes::TypeProxy check_same_to_pass_type_in_arguments(
|
||||||
|
nodes::TypeProxy type, const Arguments &arguments, const nodes::Node &node,
|
||||||
|
SourcesManager &sources_manager, const std::string &message) {
|
||||||
|
if (!arguments.get_passed().has_value()) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type != arguments.get_passed().value()) {
|
||||||
|
type_check_error(message, node, sources_manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sources_manager.get_type_storage()->primitive_type(
|
||||||
|
builtin::types::Type::BOOL);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool check_no_pass_type_in_arguments(const Arguments &arguments,
|
||||||
|
const nodes::Node &node,
|
||||||
|
SourcesManager &sources_manager,
|
||||||
const std::string &message) {
|
const std::string &message) {
|
||||||
if (!expected_type.has_value()) {
|
if (arguments.get_passed().has_value()) {
|
||||||
|
type_check_error(message, node, sources_manager);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
nodes::TypeCheckResult
|
||||||
|
type_same_to_expected(nodes::TypeProxy type,
|
||||||
|
const Arguments& arguments,
|
||||||
|
const nodes::Node &node, SourcesManager &sources_manager,
|
||||||
|
const std::string &message) {
|
||||||
|
const auto& expected = arguments.get_expected();
|
||||||
|
|
||||||
|
if (expected.empty()) {
|
||||||
return nodes::TypeCheckResult{type};
|
return nodes::TypeCheckResult{type};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type != expected_type.value()) {
|
|
||||||
error_log.add_error(error_handling::ErrorLog::ErrorMessage(
|
|
||||||
node, message, error_handling::ErrorType::TYPE_CHECK));
|
|
||||||
|
|
||||||
return nodes::TypeCheckResult::construct_invalid_result();
|
|
||||||
}
|
|
||||||
// TODO: use 'can cast to' (for modifiers), instead '=='
|
// TODO: use 'can cast to' (for modifiers), instead '=='
|
||||||
return nodes::TypeCheckResult{
|
if (std::all_of(expected.begin(), expected.end(), [type](nodes::TypeProxy expected_type) { return type != expected_type; })) {
|
||||||
expected_type.value()}; // TODO: retern type or expected type ??
|
type_check_error(message, node, sources_manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nodes::TypeCheckResult{expected.front()}; // any can be choosen
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
@ -72,15 +102,4 @@ void type_check_error(const std::string &message, const nodes::Node &node,
|
||||||
node, message, error_handling::ErrorType::TYPE_CHECK));
|
node, message, error_handling::ErrorType::TYPE_CHECK));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool check_no_pass_type_in_arguments(const Arguments &arguments,
|
|
||||||
const nodes::Node &node,
|
|
||||||
SourcesManager &sources_manager) {
|
|
||||||
if (arguments.get_passed().has_value()) {
|
|
||||||
type_check_error("Type can't be passed to this node", node,
|
|
||||||
sources_manager);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace type_check
|
} // namespace type_check
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue