arguments -> args

This commit is contained in:
ProgramSnail 2024-08-26 21:38:02 +03:00
parent 76bd92e9fb
commit 8f96a818ff
16 changed files with 358 additions and 389 deletions

View file

@ -26,10 +26,10 @@ using ParserNode = parser::ParseTree::Node;
// using Node = nodes::Node_<nodes::NodePart<utils::Pos>>; // TODO // using Node = nodes::Node_<nodes::NodePart<utils::Pos>>; // TODO
using Arguments = utils::None; using Args = utils::None;
template <typename N> template <typename N>
using Task = utils::Task<Executor, N, Arguments, parser::ParseTree::Node>; using Task = utils::Task<Executor, N, Args, parser::ParseTree::Node>;
template <typename N, typename Tag = utils::None> struct BuilderTask { template <typename N, typename Tag = utils::None> struct BuilderTask {
static_assert(false); static_assert(false);
@ -39,7 +39,7 @@ template <typename N> struct BuilderTaskBase : public Task<N> {
using Task<N>::Task; using Task<N>::Task;
template <typename OtherN, typename OtherTag = utils::None> template <typename OtherN, typename OtherTag = utils::None>
OtherN Run(const parser::ParseTree::Node &node, const Arguments &args = {}) { OtherN Run(const parser::ParseTree::Node &node, const Args &args = {}) {
BuilderTask<OtherN, OtherTag> task(this->executor); BuilderTask<OtherN, OtherTag> task(this->executor);
return task(node, args); return task(node, args);
} }

View file

@ -28,7 +28,7 @@ struct BuilderTask<nodes::Expr> : public BuilderTaskBase<nodes::Expr> {
using BuilderTaskBase<nodes::Expr>::BuilderTaskBase; using BuilderTaskBase<nodes::Expr>::BuilderTaskBase;
nodes::Expr operator()(const ParserNode &parser_node, nodes::Expr operator()(const ParserNode &parser_node,
const Arguments &args) override; const Args &args) override;
}; };
template <> template <>
@ -37,7 +37,7 @@ struct BuilderTask<nodes::Match::Case>
using BuilderTaskBase<nodes::Match::Case>::BuilderTaskBase; using BuilderTaskBase<nodes::Match::Case>::BuilderTaskBase;
nodes::Match::Case operator()(const ParserNode &parser_node, nodes::Match::Case operator()(const ParserNode &parser_node,
const Arguments &args) override; const Args &args) override;
}; };
template <> template <>
@ -45,7 +45,7 @@ struct BuilderTask<nodes::Match> : public BuilderTaskBase<nodes::Match> {
using BuilderTaskBase<nodes::Match>::BuilderTaskBase; using BuilderTaskBase<nodes::Match>::BuilderTaskBase;
nodes::Match operator()(const ParserNode &parser_node, nodes::Match operator()(const ParserNode &parser_node,
const Arguments &args) override; const Args &args) override;
}; };
template <> template <>
@ -54,7 +54,7 @@ struct BuilderTask<nodes::Condition>
using BuilderTaskBase<nodes::Condition>::BuilderTaskBase; using BuilderTaskBase<nodes::Condition>::BuilderTaskBase;
nodes::Condition operator()(const ParserNode &parser_node, nodes::Condition operator()(const ParserNode &parser_node,
const Arguments &args) override; const Args &args) override;
}; };
template <> template <>
@ -62,7 +62,7 @@ struct BuilderTask<nodes::Loop> : public BuilderTaskBase<nodes::Loop> {
using BuilderTaskBase<nodes::Loop>::BuilderTaskBase; using BuilderTaskBase<nodes::Loop>::BuilderTaskBase;
nodes::Loop operator()(const ParserNode &parser_node, nodes::Loop operator()(const ParserNode &parser_node,
const Arguments &args) override; const Args &args) override;
}; };
// --- operators // --- operators
@ -73,7 +73,7 @@ struct BuilderTask<nodes::NameExpression, utils::CommaTag>
using BuilderTaskBase<nodes::NameExpression>::BuilderTaskBase; using BuilderTaskBase<nodes::NameExpression>::BuilderTaskBase;
nodes::NameExpression operator()(const ParserNode &parser_node, nodes::NameExpression operator()(const ParserNode &parser_node,
const Arguments &args) override; const Args &args) override;
}; };
template <> template <>
@ -82,7 +82,7 @@ struct BuilderTask<nodes::NameExpression, utils::OperatorTag>
using BuilderTaskBase<nodes::NameExpression>::BuilderTaskBase; using BuilderTaskBase<nodes::NameExpression>::BuilderTaskBase;
nodes::NameExpression operator()(const ParserNode &parser_node, nodes::NameExpression operator()(const ParserNode &parser_node,
const Arguments &args) override; const Args &args) override;
}; };
// --- continers // --- continers
@ -98,7 +98,7 @@ struct BuilderTask<nodes::Container, T>
// or // or
// '[[' expression+ ']]' // '[[' expression+ ']]'
nodes::Container operator()(const ParserNode &parser_node, nodes::Container operator()(const ParserNode &parser_node,
const Arguments &) override { const Args &) override {
const auto container_type = std::is_same_v<T, utils::BlockTag> const auto container_type = std::is_same_v<T, utils::BlockTag>
? nodes::Container::BLOCK ? nodes::Container::BLOCK
: nodes::Container::ARRAY; : nodes::Container::ARRAY;
@ -124,7 +124,7 @@ struct BuilderTask<nodes::Return> : public BuilderTaskBase<nodes::Return> {
using BuilderTaskBase<nodes::Return>::BuilderTaskBase; using BuilderTaskBase<nodes::Return>::BuilderTaskBase;
nodes::Return operator()(const ParserNode &parser_node, nodes::Return operator()(const ParserNode &parser_node,
const Arguments &args) override; const Args &args) override;
}; };
template <> template <>
@ -133,7 +133,7 @@ struct BuilderTask<nodes::NameDefinition>
using BuilderTaskBase<nodes::NameDefinition>::BuilderTaskBase; using BuilderTaskBase<nodes::NameDefinition>::BuilderTaskBase;
nodes::NameDefinition operator()(const ParserNode &parser_node, nodes::NameDefinition operator()(const ParserNode &parser_node,
const Arguments &args) override; const Args &args) override;
}; };
template <> template <>
@ -142,7 +142,7 @@ struct BuilderTask<nodes::Access, utils::ArrayAccessTag>
using BuilderTaskBase<nodes::Access>::BuilderTaskBase; using BuilderTaskBase<nodes::Access>::BuilderTaskBase;
nodes::Access operator()(const ParserNode &parser_node, nodes::Access operator()(const ParserNode &parser_node,
const Arguments &args) override; const Args &args) override;
}; };
template <> template <>
@ -151,7 +151,7 @@ struct BuilderTask<nodes::Access, utils::TupleAccessTag>
using BuilderTaskBase<nodes::Access>::BuilderTaskBase; using BuilderTaskBase<nodes::Access>::BuilderTaskBase;
nodes::Access operator()(const ParserNode &parser_node, nodes::Access operator()(const ParserNode &parser_node,
const Arguments &args) override; const Args &args) override;
}; };
template <> template <>
@ -160,7 +160,7 @@ struct BuilderTask<nodes::LoopControl>
using BuilderTaskBase<nodes::LoopControl>::BuilderTaskBase; using BuilderTaskBase<nodes::LoopControl>::BuilderTaskBase;
nodes::LoopControl operator()(const ParserNode &parser_node, nodes::LoopControl operator()(const ParserNode &parser_node,
const Arguments &args) override; const Args &args) override;
}; };
template <typename T> template <typename T>
@ -174,7 +174,7 @@ struct BuilderTask<nodes::ModifierExpression, T>
// or // or
// expression ('?' | '!') // expression ('?' | '!')
nodes::ModifierExpression operator()(const ParserNode &parser_node, nodes::ModifierExpression operator()(const ParserNode &parser_node,
const Arguments &) override { const Args &) override {
const size_t modifier_pos = const size_t modifier_pos =
std::is_same_v<T, utils::RefTag> ? 0 : parser_node.child_count() - 1; std::is_same_v<T, utils::RefTag> ? 0 : parser_node.child_count() - 1;
@ -193,7 +193,7 @@ struct BuilderTask<nodes::NameExpression, utils::FuncCallTag>
using BuilderTaskBase<nodes::NameExpression>::BuilderTaskBase; using BuilderTaskBase<nodes::NameExpression>::BuilderTaskBase;
nodes::NameExpression operator()(const ParserNode &parser_node, nodes::NameExpression operator()(const ParserNode &parser_node,
const Arguments &args) override; const Args &args) override;
}; };
template <> template <>
@ -202,7 +202,7 @@ struct BuilderTask<nodes::Constructor>
using BuilderTaskBase<nodes::Constructor>::BuilderTaskBase; using BuilderTaskBase<nodes::Constructor>::BuilderTaskBase;
nodes::Constructor operator()(const ParserNode &parser_node, nodes::Constructor operator()(const ParserNode &parser_node,
const Arguments &args) override; const Args &args) override;
}; };
template <> template <>
@ -210,7 +210,7 @@ struct BuilderTask<nodes::Lambda> : public BuilderTaskBase<nodes::Lambda> {
using BuilderTaskBase<nodes::Lambda>::BuilderTaskBase; using BuilderTaskBase<nodes::Lambda>::BuilderTaskBase;
nodes::Lambda operator()(const ParserNode &parser_node, nodes::Lambda operator()(const ParserNode &parser_node,
const Arguments &args) override; const Args &args) override;
}; };
} // namespace builders } // namespace builders

View file

@ -20,7 +20,7 @@ struct BuilderTask<nodes::Statements>
using BuilderTaskBase<nodes::Statements>::BuilderTaskBase; using BuilderTaskBase<nodes::Statements>::BuilderTaskBase;
nodes::Statements operator()(const ParserNode &parser_node, nodes::Statements operator()(const ParserNode &parser_node,
const Arguments &args) override; const Args &args) override;
}; };
// copy of statement inserted into name_tree // copy of statement inserted into name_tree
@ -30,7 +30,7 @@ struct BuilderTask<nodes::Statement>
using BuilderTaskBase<nodes::Statement>::BuilderTaskBase; using BuilderTaskBase<nodes::Statement>::BuilderTaskBase;
nodes::Statement operator()(const ParserNode &parser_node, nodes::Statement operator()(const ParserNode &parser_node,
const Arguments &args) override; const Args &args) override;
}; };
template <> template <>
@ -38,7 +38,7 @@ struct BuilderTask<nodes::Import> : public BuilderTaskBase<nodes::Import> {
using BuilderTaskBase<nodes::Import>::BuilderTaskBase; using BuilderTaskBase<nodes::Import>::BuilderTaskBase;
nodes::Import operator()(const ParserNode &parser_node, nodes::Import operator()(const ParserNode &parser_node,
const Arguments &args) override; const Args &args) override;
}; };
template <> template <>
@ -47,7 +47,7 @@ struct BuilderTask<nodes::Constraint>
using BuilderTaskBase<nodes::Constraint>::BuilderTaskBase; using BuilderTaskBase<nodes::Constraint>::BuilderTaskBase;
nodes::Constraint operator()(const ParserNode &parser_node, nodes::Constraint operator()(const ParserNode &parser_node,
const Arguments &args) override; const Args &args) override;
}; };
template <> template <>
@ -56,7 +56,7 @@ struct BuilderTask<nodes::TypeDefinition>
using BuilderTaskBase<nodes::TypeDefinition>::BuilderTaskBase; using BuilderTaskBase<nodes::TypeDefinition>::BuilderTaskBase;
nodes::TypeDefinition operator()(const ParserNode &parser_node, nodes::TypeDefinition operator()(const ParserNode &parser_node,
const Arguments &args) override; const Args &args) override;
}; };
template <> template <>
@ -65,7 +65,7 @@ struct BuilderTask<nodes::FunctionDefinition>
using BuilderTaskBase<nodes::FunctionDefinition>::BuilderTaskBase; using BuilderTaskBase<nodes::FunctionDefinition>::BuilderTaskBase;
nodes::FunctionDefinition operator()(const ParserNode &parser_node, nodes::FunctionDefinition operator()(const ParserNode &parser_node,
const Arguments &args) override; const Args &args) override;
}; };
// const std::optional<nodes::Identifier> &previous_defined_type_name, // TODO // const std::optional<nodes::Identifier> &previous_defined_type_name, // TODO

View file

@ -11,7 +11,7 @@
namespace builders { namespace builders {
nodes::Expr BuilderTask<nodes::Expr>::operator()(const ParserNode &parser_node, nodes::Expr BuilderTask<nodes::Expr>::operator()(const ParserNode &parser_node,
const Arguments &) { const Args &) {
tokens::Type type = tokens::string_to_type(parser_node.get_type()); tokens::Type type = tokens::string_to_type(parser_node.get_type());
auto maybe_parenthesis = parser_node.previous_sibling(); auto maybe_parenthesis = parser_node.previous_sibling();
@ -149,7 +149,7 @@ nodes::Expr BuilderTask<nodes::Expr>::operator()(const ParserNode &parser_node,
// (':=' | '=:') expression (('??' | 'if') expression)? (_do_ expression)? // (':=' | '=:') expression (('??' | 'if') expression)? (_do_ expression)?
nodes::Match::Case nodes::Match::Case
BuilderTask<nodes::Match::Case>::operator()(const ParserNode &parser_node, BuilderTask<nodes::Match::Case>::operator()(const ParserNode &parser_node,
const Arguments &) { const Args &) {
std::string case_type = parser_node.nth_child(0).get_value(); std::string case_type = parser_node.nth_child(0).get_value();
std::optional<ParserNode> condition_node; std::optional<ParserNode> condition_node;
@ -183,7 +183,7 @@ BuilderTask<nodes::Match::Case>::operator()(const ParserNode &parser_node,
// expression case+ // expression case+
nodes::Match nodes::Match
BuilderTask<nodes::Match>::operator()(const ParserNode &parser_node, BuilderTask<nodes::Match>::operator()(const ParserNode &parser_node,
const Arguments &) { const Args &) {
std::vector<nodes::Match::Case> cases; std::vector<nodes::Match::Case> cases;
auto current_node = parser_node.nth_named_child(1); auto current_node = parser_node.nth_named_child(1);
@ -201,7 +201,7 @@ BuilderTask<nodes::Match>::operator()(const ParserNode &parser_node,
// expression)* (('!!=>', 'else') expression)? // expression)* (('!!=>', 'else') expression)?
nodes::Condition nodes::Condition
BuilderTask<nodes::Condition>::operator()(const ParserNode &parser_node, BuilderTask<nodes::Condition>::operator()(const ParserNode &parser_node,
const Arguments &) { const Args &) {
size_t named_child_count = parser_node.named_child_count(); size_t named_child_count = parser_node.named_child_count();
std::vector<std::pair<nodes::Expr, nodes::Expr>> cases; std::vector<std::pair<nodes::Expr, nodes::Expr>> cases;
@ -228,7 +228,7 @@ BuilderTask<nodes::Condition>::operator()(const ParserNode &parser_node,
// ('@' | 'for') (expression | expression ':' expression)? _do_ expression // ('@' | 'for') (expression | expression ':' expression)? _do_ expression
nodes::Loop BuilderTask<nodes::Loop>::operator()(const ParserNode &parser_node, nodes::Loop BuilderTask<nodes::Loop>::operator()(const ParserNode &parser_node,
const Arguments &) { const Args &) {
size_t named_child_count = parser_node.named_child_count(); size_t named_child_count = parser_node.named_child_count();
if (named_child_count == 1) { // body if (named_child_count == 1) { // body
@ -274,41 +274,41 @@ nodes::Loop BuilderTask<nodes::Loop>::operator()(const ParserNode &parser_node,
// expression ',' expression // expression ',' expression
nodes::NameExpression nodes::NameExpression
BuilderTask<nodes::NameExpression, utils::CommaTag>::operator()( BuilderTask<nodes::NameExpression, utils::CommaTag>::operator()(
const ParserNode &parser_node, const Arguments &) { const ParserNode &parser_node, const Args &) {
std::vector<std::pair<std::optional<std::string>, nodes::Expr>> arguments; std::vector<std::pair<std::optional<std::string>, nodes::Expr>> args;
arguments.emplace_back(std::nullopt, args.emplace_back(std::nullopt,
Run<nodes::Expr>(parser_node.nth_named_child(0))); Run<nodes::Expr>(parser_node.nth_named_child(0)));
arguments.emplace_back(std::nullopt, args.emplace_back(std::nullopt,
Run<nodes::Expr>(parser_node.nth_named_child(1))); Run<nodes::Expr>(parser_node.nth_named_child(1)));
return nodes::NameExpression( return nodes::NameExpression(
build_node(parser_node), build_node(parser_node),
nodes::Identifier( nodes::Identifier(
build_node(parser_node), // can't find more precise location build_node(parser_node), // can't find more precise location
nodes::Identifier::SIMPLE_NAME, ","), nodes::Identifier::SIMPLE_NAME, ","),
std::move(arguments), std::nullopt, false, true); std::move(args), std::nullopt, false, true);
} }
// expression operator expression // expression operator expression
nodes::NameExpression nodes::NameExpression
BuilderTask<nodes::NameExpression, utils::OperatorTag>::operator()( BuilderTask<nodes::NameExpression, utils::OperatorTag>::operator()(
const ParserNode &parser_node, const Arguments &) { const ParserNode &parser_node, const Args &) {
auto name_node = parser_node.child_by_field_name("na" auto name_node = parser_node.child_by_field_name("na"
"m" "m"
"e"); "e");
std::vector<std::pair<std::optional<std::string>, nodes::Expr>> arguments; std::vector<std::pair<std::optional<std::string>, nodes::Expr>> args;
arguments.emplace_back(std::nullopt, args.emplace_back(std::nullopt,
Run<nodes::Expr>(name_node.previous_named_sibling())); Run<nodes::Expr>(name_node.previous_named_sibling()));
arguments.emplace_back(std::nullopt, args.emplace_back(std::nullopt,
Run<nodes::Expr>(name_node.next_named_sibling())); Run<nodes::Expr>(name_node.next_named_sibling()));
return nodes::NameExpression(build_node(parser_node), return nodes::NameExpression(build_node(parser_node),
build_operator(name_node), std::move(arguments), build_operator(name_node), std::move(args),
std::nullopt, false, true); std::nullopt, false, true);
} }
@ -321,7 +321,7 @@ BuilderTask<nodes::NameExpression, utils::OperatorTag>::operator()(
// ('return' | 'bring') expression // ('return' | 'bring') expression
nodes::Return nodes::Return
BuilderTask<nodes::Return>::operator()(const ParserNode &parser_node, BuilderTask<nodes::Return>::operator()(const ParserNode &parser_node,
const Arguments &) { const Args &) {
std::string modifier = parser_node.nth_child(0).get_value(); std::string modifier = parser_node.nth_child(0).get_value();
return nodes::Return(build_node(parser_node), return nodes::Return(build_node(parser_node),
@ -336,7 +336,7 @@ BuilderTask<nodes::Return>::operator()(const ParserNode &parser_node,
// _var_let_ (simple_name_identifier | placeholder) // _var_let_ (simple_name_identifier | placeholder)
nodes::NameDefinition nodes::NameDefinition
BuilderTask<nodes::NameDefinition>::operator()(const ParserNode &parser_node, BuilderTask<nodes::NameDefinition>::operator()(const ParserNode &parser_node,
const Arguments &) { const Args &) {
std::string modifier = parser_node.nth_child(0).get_value(); std::string modifier = parser_node.nth_child(0).get_value();
auto name_node = parser_node.nth_named_child(0); auto name_node = parser_node.nth_named_child(0);
@ -350,7 +350,7 @@ BuilderTask<nodes::NameDefinition>::operator()(const ParserNode &parser_node,
// expression '[' expression ']' // expression '[' expression ']'
nodes::Access BuilderTask<nodes::Access, utils::ArrayAccessTag>::operator()( nodes::Access BuilderTask<nodes::Access, utils::ArrayAccessTag>::operator()(
const ParserNode &parser_node, const Arguments &) { const ParserNode &parser_node, const Args &) {
return nodes::Access(build_node(parser_node), nodes::Access::ARRAY, return nodes::Access(build_node(parser_node), nodes::Access::ARRAY,
Run<nodes::Expr>(parser_node.nth_named_child(0)), Run<nodes::Expr>(parser_node.nth_named_child(0)),
Run<nodes::Expr>(parser_node.nth_named_child(1))); Run<nodes::Expr>(parser_node.nth_named_child(1)));
@ -358,7 +358,7 @@ nodes::Access BuilderTask<nodes::Access, utils::ArrayAccessTag>::operator()(
// expression '.' number_literal // expression '.' number_literal
nodes::Access BuilderTask<nodes::Access, utils::TupleAccessTag>::operator()( nodes::Access BuilderTask<nodes::Access, utils::TupleAccessTag>::operator()(
const ParserNode &parser_node, const Arguments &) { const ParserNode &parser_node, const Args &) {
return nodes::Access( return nodes::Access(
build_node(parser_node), nodes::Access::TUPLE, build_node(parser_node), nodes::Access::TUPLE,
Run<nodes::Expr>(parser_node.nth_named_child(0)), Run<nodes::Expr>(parser_node.nth_named_child(0)),
@ -370,7 +370,7 @@ nodes::Access BuilderTask<nodes::Access, utils::TupleAccessTag>::operator()(
// 'break' | 'continue' // 'break' | 'continue'
nodes::LoopControl nodes::LoopControl
BuilderTask<nodes::LoopControl>::operator()(const ParserNode &parser_node, BuilderTask<nodes::LoopControl>::operator()(const ParserNode &parser_node,
const Arguments &) { const Args &) {
return nodes::LoopControl(build_node(parser_node), return nodes::LoopControl(build_node(parser_node),
parser_node.get_value() == "br" parser_node.get_value() == "br"
"ea" "ea"
@ -383,9 +383,8 @@ BuilderTask<nodes::LoopControl>::operator()(const ParserNode &parser_node,
// --- other // --- other
void build_arguments_until_end( void build_args_until_end(ParserNode first_parse_node, Executor &executor,
ParserNode first_parse_node, Executor &executor, std::vector<nodes::AnnotatedArgument> &args) {
std::vector<nodes::AnnotatedArgument> &arguments) {
auto current_node = first_parse_node; auto current_node = first_parse_node;
std::optional<std::string> last_annotation; std::optional<std::string> last_annotation;
@ -394,9 +393,8 @@ void build_arguments_until_end(
tokens::Type::ANNOTATION_IDENTIFIER) { tokens::Type::ANNOTATION_IDENTIFIER) {
last_annotation = build_annotation(current_node); last_annotation = build_annotation(current_node);
} else { } else {
arguments.emplace_back( args.emplace_back(std::move(last_annotation),
std::move(last_annotation), BuilderTask<nodes::Expr>{executor}(current_node, {}));
BuilderTask<nodes::Expr>{executor}(current_node, {}));
last_annotation = std::nullopt; last_annotation = std::nullopt;
} }
current_node = current_node.next_named_sibling(); current_node = current_node.next_named_sibling();
@ -407,8 +405,8 @@ void build_arguments_until_end(
// ')') (annotation? expression)* // ')') (annotation? expression)*
nodes::NameExpression nodes::NameExpression
BuilderTask<nodes::NameExpression, utils::FuncCallTag>::operator()( BuilderTask<nodes::NameExpression, utils::FuncCallTag>::operator()(
const ParserNode &parser_node, const Arguments &) { const ParserNode &parser_node, const Args &) {
std::vector<nodes::AnnotatedArgument> arguments; std::vector<nodes::AnnotatedArgument> args;
std::optional<nodes::TypeData> prefix; std::optional<nodes::TypeData> prefix;
@ -435,16 +433,14 @@ BuilderTask<nodes::NameExpression, utils::FuncCallTag>::operator()(
prefix_node = current_node; prefix_node = current_node;
} else { } else {
is_point_call = true; is_point_call = true;
arguments.emplace_back(std::nullopt, Run<nodes::Expr>(current_node)); args.emplace_back(std::nullopt, Run<nodes::Expr>(current_node));
} }
} }
build_arguments_until_end(name_node.next_named_sibling(), executor, build_args_until_end(name_node.next_named_sibling(), executor, args);
arguments);
return nodes::NameExpression( return nodes::NameExpression(
build_node(parser_node), build_identifier(name_node), build_node(parser_node), build_identifier(name_node), std::move(args),
std::move(arguments),
prefix_node.has_value() ? build_type(prefix_node.value(), state<Types>()) prefix_node.has_value() ? build_type(prefix_node.value(), state<Types>())
: nodes::MaybeType(), : nodes::MaybeType(),
is_point_call, false); is_point_call, false);
@ -453,40 +449,40 @@ BuilderTask<nodes::NameExpression, utils::FuncCallTag>::operator()(
// type (annotation? expression)* // type (annotation? expression)*
nodes::Constructor nodes::Constructor
BuilderTask<nodes::Constructor>::operator()(const ParserNode &parser_node, BuilderTask<nodes::Constructor>::operator()(const ParserNode &parser_node,
const Arguments &) { const Args &) {
std::vector<nodes::AnnotatedArgument> arguments; std::vector<nodes::AnnotatedArgument> args;
build_arguments_until_end(parser_node build_args_until_end(parser_node
.child_by_field_name("ty" .child_by_field_name("ty"
"p" "p"
"e") "e")
.next_named_sibling(), .next_named_sibling(),
executor, arguments); executor, args);
return nodes::Constructor( return nodes::Constructor(
build_node(parser_node), build_node(parser_node),
build_type(parser_node.child_by_field_name("type"), state<Types>()), build_type(parser_node.child_by_field_name("type"), state<Types>()),
std::move(arguments)); std::move(args));
} }
// '\\' argument_name* _do_ expression // '\\' argument_name* _do_ expression
nodes::Lambda nodes::Lambda
BuilderTask<nodes::Lambda>::operator()(const ParserNode &parser_node, BuilderTask<nodes::Lambda>::operator()(const ParserNode &parser_node,
const Arguments &) { const Args &) {
std::vector<nodes::Identifier> arguments; std::vector<nodes::Identifier> args;
auto current_node = auto current_node =
parser_node.nth_child(1); // next to '\\', not null ('=>' should present) parser_node.nth_child(1); // next to '\\', not null ('=>' should present)
while (current_node.is_named()) { // until _do_ while (current_node.is_named()) { // until _do_
arguments.emplace_back(build_identifier(current_node)); args.emplace_back(build_identifier(current_node));
current_node = current_node.next_sibling(); current_node = current_node.next_sibling();
} }
// skip '=>' // skip '=>'
current_node = current_node.next_named_sibling(); current_node = current_node.next_named_sibling();
return nodes::Lambda(build_node(parser_node), std::move(arguments), return nodes::Lambda(build_node(parser_node), std::move(args),
Run<nodes::Expr>(current_node)); Run<nodes::Expr>(current_node));
} }

View file

@ -21,7 +21,7 @@ namespace builders {
// statement+ // statement+
nodes::Statements nodes::Statements
BuilderTask<nodes::Statements>::operator()(const ParserNode &parser_node, BuilderTask<nodes::Statements>::operator()(const ParserNode &parser_node,
const Arguments &) { const Args &) {
std::vector<nodes::Statement> statements; std::vector<nodes::Statement> statements;
std::optional<nodes::Identifier> last_defined_type_name; std::optional<nodes::Identifier> last_defined_type_name;
@ -38,7 +38,7 @@ BuilderTask<nodes::Statements>::operator()(const ParserNode &parser_node,
// import | type_definition | function_definition | typeclass_definition // import | type_definition | function_definition | typeclass_definition
nodes::Statement nodes::Statement
BuilderTask<nodes::Statement>::operator()(const ParserNode &parser_node, BuilderTask<nodes::Statement>::operator()(const ParserNode &parser_node,
const Arguments &) { const Args &) {
tokens::Type type = tokens::string_to_type(parser_node.get_type()); tokens::Type type = tokens::string_to_type(parser_node.get_type());
std::optional<std::string> statement_name; std::optional<std::string> statement_name;
@ -108,7 +108,7 @@ BuilderTask<nodes::Statement>::operator()(const ParserNode &parser_node,
// ('::' | 'import') simple_name ('=' simple_name)? (':' identifier*)? // ('::' | 'import') simple_name ('=' simple_name)? (':' identifier*)?
nodes::Import nodes::Import
BuilderTask<nodes::Import>::operator()(const ParserNode &parser_node, BuilderTask<nodes::Import>::operator()(const ParserNode &parser_node,
const Arguments &) { const Args &) {
auto name_node = parser_node.child_by_field_name("name"); auto name_node = parser_node.child_by_field_name("name");
auto module_node = parser_node.child_by_field_name("module"); auto module_node = parser_node.child_by_field_name("module");
@ -131,7 +131,7 @@ BuilderTask<nodes::Import>::operator()(const ParserNode &parser_node,
// '?' expression // '?' expression
nodes::Constraint nodes::Constraint
BuilderTask<nodes::Constraint>::operator()(const ParserNode &parser_node, BuilderTask<nodes::Constraint>::operator()(const ParserNode &parser_node,
const Arguments &) { const Args &) {
return nodes::Constraint(build_node(parser_node), return nodes::Constraint(build_node(parser_node),
Run<nodes::Expr>(parser_node.nth_named_child(0))); Run<nodes::Expr>(parser_node.nth_named_child(0)));
} }
@ -169,7 +169,7 @@ parser::ParseTree::Node collect_symbol_doc_nodes(
// (argument_type* '=' type)? ';' // (argument_type* '=' type)? ';'
nodes::TypeDefinition nodes::TypeDefinition
BuilderTask<nodes::TypeDefinition>::operator()(const ParserNode &parser_node, BuilderTask<nodes::TypeDefinition>::operator()(const ParserNode &parser_node,
const Arguments &) { const Args &) {
std::optional<parser::ParseTree::Node> description_node; std::optional<parser::ParseTree::Node> description_node;
std::vector<parser::ParseTree::Node> annotation_nodes; std::vector<parser::ParseTree::Node> annotation_nodes;
@ -194,7 +194,7 @@ BuilderTask<nodes::TypeDefinition>::operator()(const ParserNode &parser_node,
// //
std::vector<nodes::Identifier> typeclasses; std::vector<nodes::Identifier> typeclasses;
std::vector<nodes::Identifier> arguments; std::vector<nodes::Identifier> args;
std::optional<parser::ParseTree::Node> type_node; std::optional<parser::ParseTree::Node> type_node;
@ -205,7 +205,7 @@ BuilderTask<nodes::TypeDefinition>::operator()(const ParserNode &parser_node,
typeclasses.push_back(build_identifier(current_node)); typeclasses.push_back(build_identifier(current_node));
break; break;
case tokens::Type::ARGUMENT_TYPE_IDENTIFIER: case tokens::Type::ARGUMENT_TYPE_IDENTIFIER:
arguments.push_back(build_identifier(current_node)); args.push_back(build_identifier(current_node));
break; break;
case tokens::Type::VARIANT_TYPE: case tokens::Type::VARIANT_TYPE:
case tokens::Type::TUPLE_TYPE: case tokens::Type::TUPLE_TYPE:
@ -231,7 +231,7 @@ BuilderTask<nodes::TypeDefinition>::operator()(const ParserNode &parser_node,
} }
if (is_typeclass) { if (is_typeclass) {
if (!arguments.empty()) { if (!args.empty()) {
error_handling::handle_parsing_error("Typeclass can't have arguments", error_handling::handle_parsing_error("Typeclass can't have arguments",
parser_node); parser_node);
} }
@ -258,7 +258,7 @@ BuilderTask<nodes::TypeDefinition>::operator()(const ParserNode &parser_node,
return nodes::TypeDefinition( return nodes::TypeDefinition(
build_node(parser_node), build_node(parser_node),
build_symbol_docs(description_node, annotation_nodes, annotations), build_symbol_docs(description_node, annotation_nodes, annotations),
is_on_heap, std::move(name), std::move(typeclasses), std::move(arguments), is_on_heap, std::move(name), std::move(typeclasses), std::move(args),
type); type);
} }
@ -267,7 +267,7 @@ BuilderTask<nodes::TypeDefinition>::operator()(const ParserNode &parser_node,
// (annotation? _reference_ type)+)? // (annotation? _reference_ type)+)?
// (((block | array) | '=' expression ';') | ';') // (((block | array) | '=' expression ';') | ';')
nodes::FunctionDefinition BuilderTask<nodes::FunctionDefinition>::operator()( nodes::FunctionDefinition BuilderTask<nodes::FunctionDefinition>::operator()(
const ParserNode &parser_node, const Arguments &) { const ParserNode &parser_node, const Args &) {
// const std::optional<nodes::Identifier> &last_defined_type_name, // TODO // const std::optional<nodes::Identifier> &last_defined_type_name, // TODO
std::optional<parser::ParseTree::Node> description_node; std::optional<parser::ParseTree::Node> description_node;
@ -315,7 +315,7 @@ nodes::FunctionDefinition BuilderTask<nodes::FunctionDefinition>::operator()(
} }
} }
std::vector<nodes::FunctionDefinition::Argument> arguments; std::vector<nodes::FunctionDefinition::Argument> args;
std::vector<nodes::FunctionDefinition::Argument> argument_types; std::vector<nodes::FunctionDefinition::Argument> argument_types;
std::optional<parser::ParseTree::Node> expression_node; std::optional<parser::ParseTree::Node> expression_node;
@ -362,7 +362,7 @@ nodes::FunctionDefinition BuilderTask<nodes::FunctionDefinition>::operator()(
at_least_one_argument_annotation_found = true; at_least_one_argument_annotation_found = true;
} }
arguments.push_back(nodes::FunctionDefinition::Argument( args.push_back(nodes::FunctionDefinition::Argument(
last_annotation, build_identifier(current_node), last_before_modifier, last_annotation, build_identifier(current_node), last_before_modifier,
last_after_modifier)); last_after_modifier));
@ -373,12 +373,12 @@ nodes::FunctionDefinition BuilderTask<nodes::FunctionDefinition>::operator()(
case tokens::Type::REFERENCE_TYPE: case tokens::Type::REFERENCE_TYPE:
case tokens::Type::MODIFIED_TYPE: case tokens::Type::MODIFIED_TYPE:
case tokens::Type::SIMPLE_TYPE: case tokens::Type::SIMPLE_TYPE:
if (current_type_id >= arguments.size()) { if (current_type_id >= args.size()) {
arguments.push_back(nodes::FunctionDefinition::Argument( args.push_back(nodes::FunctionDefinition::Argument(
last_annotation, build_type(current_node, state<Types>()), last_annotation, build_type(current_node, state<Types>()),
last_before_modifier)); last_before_modifier));
} else { } else {
if (!arguments[current_type_id].add_type( if (!args[current_type_id].add_type(
last_annotation, build_type(current_node, state<Types>()), last_annotation, build_type(current_node, state<Types>()),
last_before_modifier)) { last_before_modifier)) {
error_handling::handle_parsing_error( error_handling::handle_parsing_error(
@ -406,7 +406,7 @@ nodes::FunctionDefinition BuilderTask<nodes::FunctionDefinition>::operator()(
current_node = current_node.next_named_sibling(); current_node = current_node.next_named_sibling();
} }
if (current_type_id > 0 && current_type_id < arguments.size()) { if (current_type_id > 0 && current_type_id < args.size()) {
error_handling::handle_parsing_error( error_handling::handle_parsing_error(
"Less types then arguments in function definition", parser_node); "Less types then arguments in function definition", parser_node);
} }
@ -423,9 +423,9 @@ nodes::FunctionDefinition BuilderTask<nodes::FunctionDefinition>::operator()(
(!at_least_one_argument_annotation_found && current_type_id == 0); (!at_least_one_argument_annotation_found && current_type_id == 0);
if (are_annotations_same_to_names) { if (are_annotations_same_to_names) {
for (size_t i = 0; i < arguments.size(); ++i) { for (size_t i = 0; i < args.size(); ++i) {
std::string new_annotation = *arguments[i].get_name().value()->get(); std::string new_annotation = *args[i].get_name().value()->get();
if (!arguments[i].add_annotation( if (!args[i].add_annotation(
new_annotation.substr(1, new_annotation.size() - 1))) { new_annotation.substr(1, new_annotation.size() - 1))) {
error_handling::handle_parsing_error( error_handling::handle_parsing_error(
"no annotations provided ( => all annotations same to names), but " "no annotations provided ( => all annotations same to names), but "
@ -436,9 +436,9 @@ nodes::FunctionDefinition BuilderTask<nodes::FunctionDefinition>::operator()(
} }
std::unordered_set<std::string> annotations_set; std::unordered_set<std::string> annotations_set;
for (auto &argument : arguments) { for (auto &arg : args) {
if (argument.get_annotation().has_value()) { if (arg.get_annotation().has_value()) {
if (!annotations_set.insert(*argument.get_annotation().value()).second) { if (!annotations_set.insert(*arg.get_annotation().value()).second) {
error_handling::handle_parsing_error( error_handling::handle_parsing_error(
"Two or more same annotations found in function definition", "Two or more same annotations found in function definition",
parser_node); parser_node);
@ -450,7 +450,7 @@ nodes::FunctionDefinition BuilderTask<nodes::FunctionDefinition>::operator()(
build_node(parser_node), build_node(parser_node),
build_symbol_docs(description_node, annotation_nodes, annotations_set), build_symbol_docs(description_node, annotation_nodes, annotations_set),
std::move(constraints), return_modifier, is_method, name_prefix, std::move(constraints), return_modifier, is_method, name_prefix,
build_identifier(name_node), std::move(arguments), build_identifier(name_node), std::move(args),
are_annotations_same_to_names, are_annotations_same_to_names,
expression_node.has_value() ? Run<nodes::Expr>(expression_node.value()) expression_node.has_value() ? Run<nodes::Expr>(expression_node.value())
: std::optional<nodes::Expr>()); : std::optional<nodes::Expr>());

View file

@ -381,12 +381,12 @@ public:
: TypedNode(node), name_(name) {} : TypedNode(node), name_(name) {}
NameExpression(Node node, Identifier &&name, NameExpression(Node node, Identifier &&name,
std::vector<AnnotatedArgument> &&arguments, std::vector<AnnotatedArgument> &&args,
std::optional<Type> &&prefix, bool is_point_call = false, std::optional<Type> &&prefix, bool is_point_call = false,
bool is_operator_call = false) bool is_operator_call = false)
: TypedNode(node), name_(std::move(name)), : TypedNode(node), name_(std::move(name)), args_(std::move(args)),
arguments_(std::move(arguments)), prefix_(std::move(prefix)), prefix_(std::move(prefix)), is_point_call_(is_point_call),
is_point_call_(is_point_call), is_operator_call_(is_operator_call) {} is_operator_call_(is_operator_call) {}
Identifier *get_name() { return &name_; } Identifier *get_name() { return &name_; }
@ -406,26 +406,24 @@ public:
return std::nullopt; return std::nullopt;
} }
size_t arguments_size() const { return arguments_.size(); } size_t args_size() const { return args_.size(); }
ExprData *get_argument_value(size_t id) { ExprData *get_argument_value(size_t id) { return args_.at(id).second.get(); }
return arguments_.at(id).second.get();
}
const ExprData *get_argument_value(size_t id) const { const ExprData *get_argument_value(size_t id) const {
return arguments_.at(id).second.get(); return args_.at(id).second.get();
} }
std::optional<std::string *> get_argument_annotation(size_t id) { std::optional<std::string *> get_argument_annotation(size_t id) {
if (arguments_.at(id).first.has_value()) { if (args_.at(id).first.has_value()) {
return &arguments_[id].first.value(); return &args_[id].first.value();
} }
return std::nullopt; return std::nullopt;
} }
std::optional<const std::string *> get_argument_annotation(size_t id) const { std::optional<const std::string *> get_argument_annotation(size_t id) const {
if (arguments_.at(id).first.has_value()) { if (args_.at(id).first.has_value()) {
return &arguments_[id].first.value(); return &args_[id].first.value();
} }
return std::nullopt; return std::nullopt;
} }
@ -437,7 +435,7 @@ public:
private: private:
Identifier name_; Identifier name_;
// universal function call syntax // universal function call syntax
std::vector<AnnotatedArgument> arguments_; std::vector<AnnotatedArgument> args_;
std::optional<Type> prefix_; std::optional<Type> prefix_;
// for static methods // for static methods
bool is_point_call_ = false; // x.f ... or f x ... bool is_point_call_ = false; // x.f ... or f x ...
@ -446,13 +444,11 @@ private:
class Constructor : public TypedNode { class Constructor : public TypedNode {
public: public:
Constructor(Node node, Type type, std::vector<AnnotatedArgument> &&arguments) Constructor(Node node, Type type, std::vector<AnnotatedArgument> &&args)
: TypedNode(node), constructor_type_(type), : TypedNode(node), constructor_type_(type), args_(std::move(args)) {}
arguments_(std::move(arguments)) {}
Constructor(Node node, Type type, Constructor(Node node, Type type, const std::vector<AnnotatedArgument> &args)
const std::vector<AnnotatedArgument> &arguments) : TypedNode(node), constructor_type_(type), args_(args) {}
: TypedNode(node), constructor_type_(type), arguments_(arguments) {}
TypeData *get_type() { return constructor_type_.get(); } TypeData *get_type() { return constructor_type_.get(); }
@ -460,56 +456,53 @@ public:
Type get_type_proxy() const { return constructor_type_; } Type get_type_proxy() const { return constructor_type_; }
size_t arguments_size() const { return arguments_.size(); } size_t args_size() const { return args_.size(); }
ExprData *get_argument_value(size_t id) { ExprData *get_argument_value(size_t id) { return args_.at(id).second.get(); }
return arguments_.at(id).second.get();
}
const ExprData *get_argument_value(size_t id) const { const ExprData *get_argument_value(size_t id) const {
return arguments_.at(id).second.get(); return args_.at(id).second.get();
} }
std::optional<std::string *> get_argument_annotation(size_t id) { std::optional<std::string *> get_argument_annotation(size_t id) {
if (arguments_.at(id).first.has_value()) { if (args_.at(id).first.has_value()) {
return &arguments_[id].first.value(); return &args_[id].first.value();
} }
return std::nullopt; return std::nullopt;
} }
std::optional<const std::string *> get_argument_annotation(size_t id) const { std::optional<const std::string *> get_argument_annotation(size_t id) const {
if (arguments_.at(id).first.has_value()) { if (args_.at(id).first.has_value()) {
return &arguments_[id].first.value(); return &args_[id].first.value();
} }
return std::nullopt; return std::nullopt;
} }
private: private:
Type constructor_type_; Type constructor_type_;
std::vector<std::pair<std::optional<std::string>, Expr>> arguments_; std::vector<std::pair<std::optional<std::string>, Expr>> args_;
}; };
class Lambda : public TypedNode { class Lambda : public TypedNode {
public: public:
Lambda(Node node, std::vector<Identifier> &&arguments, Expr expression) Lambda(Node node, std::vector<Identifier> &&args, Expr expression)
: TypedNode(node), arguments_(std::move(arguments)), : TypedNode(node), args_(std::move(args)), expression_(expression) {}
expression_(expression) {}
Lambda(Node node, const std::vector<Identifier> &arguments, Expr expression) Lambda(Node node, const std::vector<Identifier> &args, Expr expression)
: TypedNode(node), arguments_(arguments), expression_(expression) {} : TypedNode(node), args_(args), expression_(expression) {}
size_t arguments_size() const { return arguments_.size(); } size_t args_size() const { return args_.size(); }
Identifier *get_argument(size_t id) { return &arguments_.at(id); } Identifier *get_argument(size_t id) { return &args_.at(id); }
const Identifier *get_argument(size_t id) const { return &arguments_.at(id); } const Identifier *get_argument(size_t id) const { return &args_.at(id); }
ExprData *get_expression() { return expression_.get(); } ExprData *get_expression() { return expression_.get(); }
const ExprData *get_expression() const { return expression_.get(); } const ExprData *get_expression() const { return expression_.get(); }
private: private:
std::vector<Identifier> arguments_; std::vector<Identifier> args_;
Expr expression_; Expr expression_;
}; };
@ -521,7 +514,7 @@ public:
// --- operators // --- operators
// CommaExpression is OperatorExpression for operator ',' // CommaExpression is OperatorExpression for operator ','
// OperatorExpression is NameExpression with two arguments // OperatorExpression is NameExpression with two args
// --- containers // --- containers
// Block value is brought value ("bring x") // Block value is brought value ("bring x")

View file

@ -234,7 +234,7 @@ public:
private: private:
std::optional<std::string> annotation_; std::optional<std::string> annotation_;
std::optional<Identifier> name_; // no name for output arguments std::optional<Identifier> name_; // no name for output args
std::optional<Type> type_; // no type if it is deduced std::optional<Type> type_; // no type if it is deduced
Modifier before_modifier_ = Modifier before_modifier_ =
Modifier::NONE; // in, out, ref, none // sync with type Modifier::NONE; // in, out, ref, none // sync with type
@ -246,13 +246,13 @@ public:
std::vector<Constraint> &&constraints, std::vector<Constraint> &&constraints,
Modifier return_modifier, bool is_method, Modifier return_modifier, bool is_method,
const std::optional<Identifier> &name_prefix, const std::optional<Identifier> &name_prefix,
const Identifier &name, std::vector<Argument> &&arguments, const Identifier &name, std::vector<Argument> &&args,
bool are_annotations_same_to_names, bool are_annotations_same_to_names,
std::optional<Expr> expression) std::optional<Expr> expression)
: Node(node), docs_(std::move(docs)), : Node(node), docs_(std::move(docs)),
constraints_(std::move(constraints)), return_modifier_(return_modifier), constraints_(std::move(constraints)), return_modifier_(return_modifier),
is_method_(is_method), name_(name), full_name_(name), is_method_(is_method), name_(name), full_name_(name),
arguments_(std::move(arguments)), args_(std::move(args)),
are_annotations_same_to_names_(are_annotations_same_to_names), are_annotations_same_to_names_(are_annotations_same_to_names),
expression_(expression) { expression_(expression) {
if (name_prefix.has_value()) { if (name_prefix.has_value()) {
@ -296,11 +296,11 @@ public:
// //
size_t arguments_size() const { return arguments_.size(); } size_t args_size() const { return args_.size(); }
Argument *get_argument(size_t id) { return &arguments_.at(id); } Argument *get_argument(size_t id) { return &args_.at(id); }
const Argument *get_argument(size_t id) const { return &arguments_.at(id); } const Argument *get_argument(size_t id) const { return &args_.at(id); }
// //
@ -337,7 +337,7 @@ private:
bool is_method_; bool is_method_;
Identifier name_; Identifier name_;
Identifier full_name_; Identifier full_name_;
std::vector<Argument> arguments_; std::vector<Argument> args_;
bool are_annotations_same_to_names_; // needed for easier prinitng process bool are_annotations_same_to_names_; // needed for easier prinitng process
std::optional<Expr> expression_; std::optional<Expr> expression_;
}; // refactor ?? }; // refactor ??
@ -346,10 +346,10 @@ class TypeDefinition : public Node {
public: public:
TypeDefinition(Node node, SymbolDocs &&docs, bool is_on_heap, TypeDefinition(Node node, SymbolDocs &&docs, bool is_on_heap,
const Identifier &name, std::vector<Identifier> &&typeclasses, const Identifier &name, std::vector<Identifier> &&typeclasses,
std::vector<Identifier> &&arguments, std::optional<Type> type) std::vector<Identifier> &&args, std::optional<Type> type)
: Node(node), docs_(std::move(docs)), is_on_heap_(is_on_heap), : Node(node), docs_(std::move(docs)), is_on_heap_(is_on_heap),
name_(name), typeclasses_(typeclasses), name_(name), typeclasses_(typeclasses), args_(std::move(args)),
arguments_(std::move(arguments)), type_(std::move(type)) {} type_(std::move(type)) {}
// //
@ -369,11 +369,11 @@ public:
// //
size_t arguments_size() const { return arguments_.size(); } size_t args_size() const { return args_.size(); }
Identifier *get_argument(size_t id) { return &arguments_.at(id); } Identifier *get_argument(size_t id) { return &args_.at(id); }
const Identifier *get_argument(size_t id) const { return &arguments_.at(id); } const Identifier *get_argument(size_t id) const { return &args_.at(id); }
// //
@ -399,7 +399,7 @@ private:
bool is_on_heap_; bool is_on_heap_;
Identifier name_; Identifier name_;
std::vector<Identifier> typeclasses_; std::vector<Identifier> typeclasses_;
std::vector<Identifier> arguments_; std::vector<Identifier> args_;
std::optional<Type> type_; std::optional<Type> type_;
}; };

View file

@ -56,64 +56,61 @@ CombineResult FunctionDefinition::combine(FunctionDefinition &&other) {
return CombineResult::MORE_THEN_ONE_DOCS_ERROR; return CombineResult::MORE_THEN_ONE_DOCS_ERROR;
} }
// check, that function definitions have same named arguments // check, that function definitions have same named args
for (size_t i = 0; i < std::max(arguments_.size(), other.arguments_.size()); for (size_t i = 0; i < std::max(args_.size(), other.args_.size()); ++i) {
++i) { if (i < args_.size() && i < other.args_.size()) {
if (i < arguments_.size() && i < other.arguments_.size()) {
// annotations should be the same // annotations should be the same
if ((!arguments_[i].get_annotation().has_value() && if ((!args_[i].get_annotation().has_value() &&
!other.arguments_[i].get_annotation().has_value()) || !other.args_[i].get_annotation().has_value()) ||
(arguments_[i].get_annotation().has_value() && (args_[i].get_annotation().has_value() &&
other.arguments_[i].get_annotation().has_value() && other.args_[i].get_annotation().has_value() &&
*arguments_[i].get_annotation().value() != *args_[i].get_annotation().value() !=
*other.arguments_[i].get_annotation().value())) { *other.args_[i].get_annotation().value())) {
return CombineResult::ARGUMENTS_ERROR; return CombineResult::ARGUMENTS_ERROR;
} }
// argument names should be the same // argument names should be the same
if ((!arguments_[i].get_name().has_value() && if ((!args_[i].get_name().has_value() &&
!other.arguments_[i].get_name().has_value()) || !other.args_[i].get_name().has_value()) ||
(arguments_[i].get_name().has_value() && (args_[i].get_name().has_value() &&
other.arguments_[i].get_name().has_value() && other.args_[i].get_name().has_value() &&
arguments_[i].get_name().value() != args_[i].get_name().value() != other.args_[i].get_name().value())) {
other.arguments_[i].get_name().value())) {
return CombineResult::ARGUMENTS_ERROR; return CombineResult::ARGUMENTS_ERROR;
} }
// types should be the same (if present in both definitions) // types should be the same (if present in both definitions)
if (arguments_[i].get_type().has_value() && if (args_[i].get_type().has_value() &&
other.arguments_[i].get_type().has_value() && other.args_[i].get_type().has_value() &&
*arguments_[i].get_type().value() != *args_[i].get_type().value() != *other.args_[i].get_type().value()) {
*other.arguments_[i].get_type().value()) {
return CombineResult::ARGUMENTS_ERROR; return CombineResult::ARGUMENTS_ERROR;
} }
// argument modifiers should be the same // argument modifiers should be the same
if (arguments_[i].get_before_modifier() != if (args_[i].get_before_modifier() !=
other.arguments_[i].get_before_modifier() || other.args_[i].get_before_modifier() ||
arguments_[i].get_after_modifier() != args_[i].get_after_modifier() !=
other.arguments_[i].get_after_modifier()) { other.args_[i].get_after_modifier()) {
return CombineResult::ARGUMENTS_ERROR; return CombineResult::ARGUMENTS_ERROR;
} }
} else if (i < arguments_.size()) { } else if (i < args_.size()) {
// annotations should be the same // annotations should be the same
if (arguments_[i].get_annotation().has_value()) { if (args_[i].get_annotation().has_value()) {
return CombineResult::ARGUMENTS_ERROR; return CombineResult::ARGUMENTS_ERROR;
} }
// names should be the same // names should be the same
if (arguments_[i].get_name().has_value()) { if (args_[i].get_name().has_value()) {
return CombineResult::ARGUMENTS_ERROR; return CombineResult::ARGUMENTS_ERROR;
} }
} else { // i < other_function_definition.size() } else { // i < other_function_definition.size()
// annotations should be the same // annotations should be the same
if (other.arguments_[i].get_annotation().has_value()) { if (other.args_[i].get_annotation().has_value()) {
return CombineResult::ARGUMENTS_ERROR; return CombineResult::ARGUMENTS_ERROR;
} }
// names should be the same // names should be the same
if (other.arguments_[i].get_name().has_value()) { if (other.args_[i].get_name().has_value()) {
return CombineResult::ARGUMENTS_ERROR; return CombineResult::ARGUMENTS_ERROR;
} }
} }
@ -139,10 +136,10 @@ CombineResult FunctionDefinition::combine(FunctionDefinition &&other) {
expression_ = other.expression_; expression_ = other.expression_;
} }
for (size_t i = 0; i < other.arguments_.size(); ++i) { for (size_t i = 0; i < other.args_.size(); ++i) {
if (i < arguments_.size()) { if (i < args_.size()) {
if (other.arguments_[i].get_type().has_value()) { if (other.args_[i].get_type().has_value()) {
if (arguments_[i].update_type_from(other.arguments_[i])) { if (args_[i].update_type_from(other.args_[i])) {
error_handling::handle_internal_error( error_handling::handle_internal_error(
"Function arguments are not properly checked before merging " "Function arguments are not properly checked before merging "
"during combination", "during combination",
@ -150,7 +147,7 @@ CombineResult FunctionDefinition::combine(FunctionDefinition &&other) {
} }
} }
} else { } else {
arguments_.push_back(std::move(other.arguments_[i])); args_.push_back(std::move(other.args_[i]));
} }
} }
@ -189,12 +186,12 @@ CombineResult TypeDefinition::combine(TypeDefinition &&other) {
} }
} }
// arguments should be the same // args should be the same
if (arguments_.size() != other.arguments_.size()) { if (args_.size() != other.args_.size()) {
return CombineResult::ARGUMENTS_ERROR; return CombineResult::ARGUMENTS_ERROR;
} }
for (size_t i = 0; i < arguments_.size(); ++i) { for (size_t i = 0; i < args_.size(); ++i) {
if (arguments_[i] != other.arguments_[i]) { if (args_[i] != other.args_[i]) {
return CombineResult::ARGUMENTS_ERROR; return CombineResult::ARGUMENTS_ERROR;
} }
} }

View file

@ -332,7 +332,7 @@ void print(const nodes::NameExpression &expression,
for (size_t i = for (size_t i =
expression.is_operator_call() || expression.is_point_call() ? 1 : 0; expression.is_operator_call() || expression.is_point_call() ? 1 : 0;
i < expression.arguments_size(); ++i) { i < expression.args_size(); ++i) {
if (!expression.is_operator_call() || !is_range_operator || i > 1) { if (!expression.is_operator_call() || !is_range_operator || i > 1) {
printer.space(); printer.space();
} }
@ -349,7 +349,7 @@ void print(const nodes::NameExpression &expression,
void print(const nodes::Constructor &expression, printers::Printer &printer) { void print(const nodes::Constructor &expression, printers::Printer &printer) {
print(*expression.get_type(), printer); print(*expression.get_type(), printer);
for (size_t i = 0; i < expression.arguments_size(); ++i) { for (size_t i = 0; i < expression.args_size(); ++i) {
printer.space(); printer.space();
if (expression.get_argument_annotation(i).has_value()) { if (expression.get_argument_annotation(i).has_value()) {
@ -365,7 +365,7 @@ void print(const nodes::Constructor &expression, printers::Printer &printer) {
void print(const nodes::Lambda &expression, printers::Printer &printer) { void print(const nodes::Lambda &expression, printers::Printer &printer) {
printer.print(printer.print_words_instead_of_symbols() ? "lambda " : "\\ "); printer.print(printer.print_words_instead_of_symbols() ? "lambda " : "\\ ");
for (size_t i = 0; i < expression.arguments_size(); ++i) { for (size_t i = 0; i < expression.args_size(); ++i) {
print(*expression.get_argument(i), printer); print(*expression.get_argument(i), printer);
printer.space(); printer.space();
} }

View file

@ -74,7 +74,7 @@ void print(const nodes::TypeDefinition &statement, Printer &printer) {
print(*statement.get_name(), printer); print(*statement.get_name(), printer);
for (size_t i = 0; i < statement.arguments_size(); ++i) { for (size_t i = 0; i < statement.args_size(); ++i) {
printer.space(); printer.space();
print(*statement.get_argument(i), printer); print(*statement.get_argument(i), printer);
} }
@ -121,14 +121,14 @@ void print(const nodes::FunctionDefinition &statement, Printer &printer) {
print(statement.get_return_modifier(), printer); // ! or ? print(statement.get_return_modifier(), printer); // ! or ?
for (size_t i = 0; i < statement.arguments_size(); ++i) { for (size_t i = 0; i < statement.args_size(); ++i) {
if (!statement.get_argument(i)->get_name().has_value()) { if (!statement.get_argument(i)->get_name().has_value()) {
break; break;
} }
printer.space(); printer.space();
// all arguments are typed or are untyped in the same time // all args are typed or are untyped in the same time
if (!statement.get_argument(i)->get_type().has_value()) { if (!statement.get_argument(i)->get_type().has_value()) {
// print annotation // print annotation
@ -144,19 +144,19 @@ void print(const nodes::FunctionDefinition &statement, Printer &printer) {
print(*statement.get_argument(i)->get_name().value(), printer); print(*statement.get_argument(i)->get_name().value(), printer);
// all arguments are typed or are untyped in the same time // all args are typed or are untyped in the same time
if (!statement.get_argument(i)->get_type().has_value()) { if (!statement.get_argument(i)->get_type().has_value()) {
print(statement.get_argument(i)->get_after_modifier(), printer); print(statement.get_argument(i)->get_after_modifier(), printer);
} }
} }
// all arguments are typed or are untyped in the same time // all args are typed or are untyped in the same time
if (statement.arguments_size() > 0 && if (statement.args_size() > 0 &&
statement.get_argument(0)->get_type().has_value()) { statement.get_argument(0)->get_type().has_value()) {
printer.print(" :"); printer.print(" :");
for (size_t i = 0; i < statement.arguments_size(); ++i) { for (size_t i = 0; i < statement.args_size(); ++i) {
printer.space(); printer.space();
if (statement.get_argument(i)->get_annotation().has_value()) { if (statement.get_argument(i)->get_annotation().has_value()) {
print_annotation(*statement.get_argument(i)->get_annotation().value(), print_annotation(*statement.get_argument(i)->get_annotation().value(),

View file

@ -11,8 +11,7 @@ template <>
struct CheckTask<nodes::Literal> : public CheckTaskBase<nodes::Literal> { struct CheckTask<nodes::Literal> : public CheckTaskBase<nodes::Literal> {
using CheckTaskBase<nodes::Literal>::CheckTaskBase; using CheckTaskBase<nodes::Literal>::CheckTaskBase;
Result operator()(const nodes::Literal &literal, Result operator()(const nodes::Literal &literal, const Args &args) override;
const Arguments &arguments) override;
}; };
} // namespace type_check } // namespace type_check

View file

@ -11,8 +11,7 @@ template <>
struct CheckTask<nodes::ExprData> : public CheckTaskBase<nodes::ExprData> { struct CheckTask<nodes::ExprData> : public CheckTaskBase<nodes::ExprData> {
using CheckTaskBase<nodes::ExprData>::CheckTaskBase; using CheckTaskBase<nodes::ExprData>::CheckTaskBase;
Result operator()(const nodes::ExprData &expr, Result operator()(const nodes::ExprData &expr, const Args &args) override;
const Arguments &args) override;
}; };
// --- flow control // --- flow control
@ -21,21 +20,20 @@ template <>
struct CheckTask<nodes::Match> : public CheckTaskBase<nodes::Match> { struct CheckTask<nodes::Match> : public CheckTaskBase<nodes::Match> {
using CheckTaskBase<nodes::Match>::CheckTaskBase; using CheckTaskBase<nodes::Match>::CheckTaskBase;
Result operator()(const nodes::Match &expr, const Arguments &args) override; Result operator()(const nodes::Match &expr, const Args &args) override;
}; };
template <> template <>
struct CheckTask<nodes::Condition> : public CheckTaskBase<nodes::Condition> { struct CheckTask<nodes::Condition> : public CheckTaskBase<nodes::Condition> {
using CheckTaskBase<nodes::Condition>::CheckTaskBase; using CheckTaskBase<nodes::Condition>::CheckTaskBase;
Result operator()(const nodes::Condition &expr, Result operator()(const nodes::Condition &expr, const Args &args) override;
const Arguments &args) override;
}; };
template <> struct CheckTask<nodes::Loop> : public CheckTaskBase<nodes::Loop> { template <> struct CheckTask<nodes::Loop> : public CheckTaskBase<nodes::Loop> {
using CheckTaskBase<nodes::Loop>::CheckTaskBase; using CheckTaskBase<nodes::Loop>::CheckTaskBase;
Result operator()(const nodes::Loop &expr, const Arguments &args) override; Result operator()(const nodes::Loop &expr, const Args &args) override;
}; };
// --- containers // --- containers
@ -44,12 +42,11 @@ template <>
struct CheckTask<nodes::Container> : public CheckTaskBase<nodes::Container> { struct CheckTask<nodes::Container> : public CheckTaskBase<nodes::Container> {
using CheckTaskBase<nodes::Container>::CheckTaskBase; using CheckTaskBase<nodes::Container>::CheckTaskBase;
Result CheckArray(const nodes::Container &expr, const Arguments &args); Result CheckArray(const nodes::Container &expr, const Args &args);
Result CheckBlock(const nodes::Container &expr, const Arguments &args); Result CheckBlock(const nodes::Container &expr, const Args &args);
Result operator()(const nodes::Container &expr, Result operator()(const nodes::Container &expr, const Args &args) override;
const Arguments &args) override;
}; };
// --- modifiers // --- modifiers
@ -58,7 +55,7 @@ template <>
struct CheckTask<nodes::Return> : public CheckTaskBase<nodes::Return> { struct CheckTask<nodes::Return> : public CheckTaskBase<nodes::Return> {
using CheckTaskBase<nodes::Return>::CheckTaskBase; using CheckTaskBase<nodes::Return>::CheckTaskBase;
Result operator()(const nodes::Return &expr, const Arguments &args) override; Result operator()(const nodes::Return &expr, const Args &args) override;
}; };
template <> template <>
@ -67,18 +64,18 @@ struct CheckTask<nodes::NameDefinition>
using CheckTaskBase<nodes::NameDefinition>::CheckTaskBase; using CheckTaskBase<nodes::NameDefinition>::CheckTaskBase;
Result operator()(const nodes::NameDefinition &expr, Result operator()(const nodes::NameDefinition &expr,
const Arguments &args) override; const Args &args) override;
}; };
template <> template <>
struct CheckTask<nodes::Access> : public CheckTaskBase<nodes::Access> { struct CheckTask<nodes::Access> : public CheckTaskBase<nodes::Access> {
using CheckTaskBase<nodes::Access>::CheckTaskBase; using CheckTaskBase<nodes::Access>::CheckTaskBase;
Result CheckArrayAccess(const nodes::Access &expr, const Arguments &args); Result CheckArrayAccess(const nodes::Access &expr, const Args &args);
Result CheckTupleAccess(const nodes::Access &expr, const Arguments &args); Result CheckTupleAccess(const nodes::Access &expr, const Args &args);
Result operator()(const nodes::Access &expr, const Arguments &args) override; Result operator()(const nodes::Access &expr, const Args &args) override;
}; };
template <> template <>
@ -86,8 +83,7 @@ struct CheckTask<nodes::LoopControl>
: public CheckTaskBase<nodes::LoopControl> { : public CheckTaskBase<nodes::LoopControl> {
using CheckTaskBase<nodes::LoopControl>::CheckTaskBase; using CheckTaskBase<nodes::LoopControl>::CheckTaskBase;
Result operator()(const nodes::LoopControl &expr, Result operator()(const nodes::LoopControl &expr, const Args &args) override;
const Arguments &args) override;
}; };
template <> template <>
@ -96,7 +92,7 @@ struct CheckTask<nodes::ModifierExpression>
using CheckTaskBase<nodes::ModifierExpression>::CheckTaskBase; using CheckTaskBase<nodes::ModifierExpression>::CheckTaskBase;
Result operator()(const nodes::ModifierExpression &expr, Result operator()(const nodes::ModifierExpression &expr,
const Arguments &args) override; const Args &args) override;
}; };
// --- other // --- other
@ -107,7 +103,7 @@ struct CheckTask<nodes::NameExpression>
using CheckTaskBase<nodes::NameExpression>::CheckTaskBase; using CheckTaskBase<nodes::NameExpression>::CheckTaskBase;
Result operator()(const nodes::NameExpression &expr, Result operator()(const nodes::NameExpression &expr,
const Arguments &args) override; const Args &args) override;
}; };
template <> template <>
@ -115,30 +111,28 @@ struct CheckTask<nodes::Constructor>
: public CheckTaskBase<nodes::Constructor> { : public CheckTaskBase<nodes::Constructor> {
using CheckTaskBase<nodes::Constructor>::CheckTaskBase; using CheckTaskBase<nodes::Constructor>::CheckTaskBase;
Result operator()(const nodes::Constructor &expr, Result operator()(const nodes::Constructor &expr, const Args &args) override;
const Arguments &args) override;
}; };
template <> template <>
struct CheckTask<nodes::Lambda> : public CheckTaskBase<nodes::Lambda> { struct CheckTask<nodes::Lambda> : public CheckTaskBase<nodes::Lambda> {
using CheckTaskBase<nodes::Lambda>::CheckTaskBase; using CheckTaskBase<nodes::Lambda>::CheckTaskBase;
Result operator()(const nodes::Lambda &expr, const Arguments &args) override; Result operator()(const nodes::Lambda &expr, const Args &args) override;
}; };
template <> template <>
struct CheckTask<nodes::Extra> : public CheckTaskBase<nodes::Extra> { struct CheckTask<nodes::Extra> : public CheckTaskBase<nodes::Extra> {
using CheckTaskBase<nodes::Extra>::CheckTaskBase; using CheckTaskBase<nodes::Extra>::CheckTaskBase;
Result operator()(const nodes::Extra &expr, const Arguments &args) override; Result operator()(const nodes::Extra &expr, const Args &args) override;
}; };
template <> template <>
struct CheckTask<nodes::EmptyLines> : public CheckTaskBase<nodes::EmptyLines> { struct CheckTask<nodes::EmptyLines> : public CheckTaskBase<nodes::EmptyLines> {
using CheckTaskBase<nodes::EmptyLines>::CheckTaskBase; using CheckTaskBase<nodes::EmptyLines>::CheckTaskBase;
Result operator()(const nodes::EmptyLines &expr, Result operator()(const nodes::EmptyLines &expr, const Args &args) override;
const Arguments &args) override;
}; };
} // namespace type_check } // namespace type_check

View file

@ -167,49 +167,49 @@ using Executor = utils::Executor<Exprs, Types, Names, State>;
// //
class Arguments { class Args {
public: public:
Arguments() = default; Args() = default;
Arguments expect_builtin(builtin::Type type, Executor &executor) const { Args expect_builtin(builtin::Type type, Executor &executor) const {
Arguments copy(*this); Args copy(*this);
copy.expected_types_ = {executor.state<Types>().primitive(type)}; copy.expected_types_ = {executor.state<Types>().primitive(type)};
return copy; return copy;
} }
Arguments pass_builtin(builtin::Type type, Executor &executor) const { Args pass_builtin(builtin::Type type, Executor &executor) const {
Arguments copy(*this); Args copy(*this);
copy.passed_type_ = executor.state<Types>().primitive(type); copy.passed_type_ = executor.state<Types>().primitive(type);
return copy; return copy;
} }
Arguments expect(nodes::Types types) const { Args expect(nodes::Types types) const {
Arguments copy(*this); Args copy(*this);
copy.expected_types_ = types; copy.expected_types_ = types;
return copy; return copy;
} }
Arguments expect(nodes::MaybeType type) const { Args expect(nodes::MaybeType type) const {
Arguments copy(*this); Args copy(*this);
copy.expected_types_ = copy.expected_types_ =
(type.has_value() ? nodes::Types{type.value()} : nodes::Types{}); (type.has_value() ? nodes::Types{type.value()} : nodes::Types{});
return copy; return copy;
} }
Arguments pass(nodes::MaybeType type) const { Args pass(nodes::MaybeType type) const {
Arguments copy(*this); Args copy(*this);
copy.passed_type_ = type; copy.passed_type_ = type;
return copy; return copy;
} }
Arguments without_expect() const { Args without_expect() const {
Arguments copy(*this); Args copy(*this);
copy.expected_types_ = {}; copy.expected_types_ = {};
return copy; return copy;
} }
Arguments without_pass() const { Args without_pass() const {
Arguments copy(*this); Args copy(*this);
copy.passed_type_ = {}; copy.passed_type_ = {};
return copy; return copy;
} }
@ -219,7 +219,7 @@ public:
nodes::MaybeType get_passed() const { return passed_type_; }; nodes::MaybeType get_passed() const { return passed_type_; };
// TODO: add check, that there is no passed type for some nodes ?? // TODO: add check, that there is no passed type for some nodes ??
// TODO: arguments builder ?? // TODO: args builder ??
private: private:
nodes::Types expected_types_; nodes::Types expected_types_;
@ -298,26 +298,26 @@ using MaybeResult = std::optional<Result>;
// //
nodes::Type check_same_to_pass_type_in_arguments( nodes::Type check_same_to_pass_type_in_args(
nodes::Type type, const Arguments &arguments, const nodes::Node &node, nodes::Type type, const Args &args, const nodes::Node &node,
Executor &executor, Executor &executor,
const std::string &message = "Different type with passed one", const std::string &message = "Different type with passed one",
bool handle_errors = true); bool handle_errors = true);
// bool check_no_pass_type_in_arguments( // bool check_no_pass_type_in_args(
// const Arguments &arguments, const nodes::Node &node, // const Args &args, const nodes::Node &node,
// SourcesManager &sources_manager, // SourcesManager &sources_manager,
// const std::string &message = "Type can't be passed to this node"); // const std::string &message = "Type can't be passed to this node");
Result type_same_to_expected( Result type_same_to_expected(
nodes::Type type, const Arguments &argumensr, const nodes::Node &node, nodes::Type type, const Args &argumensr, const nodes::Node &node,
Executor &executor, Executor &executor,
const std::string &message = "Different type with expected one", const std::string &message = "Different type with expected one",
bool handle_errors = true); bool handle_errors = true);
Result type_check_from_arguments(nodes::Type type, const Arguments &arguments, Result type_check_from_args(nodes::Type type, const Args &args,
const nodes::Node &node, Executor &executor, const nodes::Node &node, Executor &executor,
bool handle_errors = true); bool handle_errors = true);
std::optional<const nodes::TypeDefinition *> std::optional<const nodes::TypeDefinition *>
find_type_definition(const std::string &name, const nodes::Node &node, find_type_definition(const std::string &name, const nodes::Node &node,
@ -343,7 +343,7 @@ void type_check_error(const std::string &message, const nodes::Node &node,
// //
template <typename N> using Task = utils::Task<Executor, Result, Arguments, N>; template <typename N> using Task = utils::Task<Executor, Result, Args, N>;
template <typename N> struct CheckTask { template <typename N> struct CheckTask {
static_assert(false); static_assert(false);
@ -352,8 +352,7 @@ template <typename N> struct CheckTask {
template <typename N> struct CheckTaskBase : public Task<N> { template <typename N> struct CheckTaskBase : public Task<N> {
using Task<N>::Task; using Task<N>::Task;
template <typename OtherN> template <typename OtherN> Result Run(const OtherN &node, const Args &args) {
Result Run(const OtherN &node, const Arguments &args) {
CheckTask<OtherN> task(this->executor); CheckTask<OtherN> task(this->executor);
return task(node, args); return task(node, args);
} }

View file

@ -38,9 +38,9 @@ nodes::Type get_literal_type(const nodes::Literal &literal,
} }
Result CheckTask<nodes::Literal>::operator()(const nodes::Literal &literal, Result CheckTask<nodes::Literal>::operator()(const nodes::Literal &literal,
const Arguments &arguments) { const Args &args) {
auto const type = get_literal_type(literal, this->executor); auto const type = get_literal_type(literal, this->executor);
return type_same_to_expected(type, arguments, literal, this->executor); return type_same_to_expected(type, args, literal, this->executor);
} }
} // namespace type_check } // namespace type_check

View file

@ -12,18 +12,16 @@
namespace type_check { namespace type_check {
Result CheckTask<nodes::ExprData>::operator()(const nodes::ExprData &expr, Result CheckTask<nodes::ExprData>::operator()(const nodes::ExprData &expr,
const Arguments &arguments) { const Args &args) {
return std::visit( return std::visit(
[this, &arguments](const auto &node) -> Result { [this, &args](const auto &node) -> Result { return Run(node, args); },
return Run(node, arguments);
},
expr.get_any()); expr.get_any());
} }
// --- flow control // --- flow control
Result CheckTask<nodes::Match>::operator()(const nodes::Match &expr, Result CheckTask<nodes::Match>::operator()(const nodes::Match &expr,
const Arguments &args) { const Args &args) {
Result value_result = Run(*expr.get_value(), {}); Result value_result = Run(*expr.get_value(), {});
// x :=/=: ... // x :=/=: ...
@ -41,7 +39,7 @@ Result CheckTask<nodes::Match>::operator()(const nodes::Match &expr,
// :=/=: x ... // :=/=: x ...
Run(*current_case->get_value(), Run(*current_case->get_value(),
Arguments{} Args{}
.expect_builtin(builtin::Type::BOOL, executor) .expect_builtin(builtin::Type::BOOL, executor)
.pass(value_result.is_invalid() ? nodes::MaybeType{} .pass(value_result.is_invalid() ? nodes::MaybeType{}
: expression_result.value().get())); : expression_result.value().get()));
@ -50,7 +48,7 @@ Result CheckTask<nodes::Match>::operator()(const nodes::Match &expr,
// ... ?? x ... // ... ?? x ...
if (current_case->get_condition().has_value()) { if (current_case->get_condition().has_value()) {
Run(*current_case->get_condition().value(), Run(*current_case->get_condition().value(),
Arguments{}.expect_builtin(builtin::Type::BOOL, executor)); Args{}.expect_builtin(builtin::Type::BOOL, executor));
} }
// ... -> x // ... -> x
@ -58,9 +56,9 @@ Result CheckTask<nodes::Match>::operator()(const nodes::Match &expr,
at_least_one_case_with_expression = true; at_least_one_case_with_expression = true;
Result case_result = Result case_result =
Run(*current_case->get_condition().value(), Run(*current_case->get_condition().value(),
Arguments{}.expect(expression_result.has_value() Args{}.expect(expression_result.has_value()
? expression_result.value().get() ? expression_result.value().get()
: nodes::MaybeType{})); : nodes::MaybeType{}));
if (!expression_result.has_value() && !case_result.is_invalid()) { if (!expression_result.has_value() && !case_result.is_invalid()) {
expression_result = std::move(case_result); expression_result = std::move(case_result);
@ -82,24 +80,23 @@ Result CheckTask<nodes::Match>::operator()(const nodes::Match &expr,
expression_result = Result{state<Types>().primitive(builtin::Type::UNIT)}; expression_result = Result{state<Types>().primitive(builtin::Type::UNIT)};
} }
return type_check_from_arguments( return type_check_from_args(
state<Types>().add_array_of(expression_result.value().get()), args, expr, state<Types>().add_array_of(expression_result.value().get()), args, expr,
executor); executor);
} }
Result CheckTask<nodes::Condition>::operator()(const nodes::Condition &expr, Result CheckTask<nodes::Condition>::operator()(const nodes::Condition &expr,
const Arguments &args) { const Args &args) {
MaybeResult expression_result; MaybeResult expression_result;
for (size_t i = 0; i < expr.cases_size(); ++i) { for (size_t i = 0; i < expr.cases_size(); ++i) {
Run(*expr.get_case(i).first, Run(*expr.get_case(i).first,
Arguments{}.expect_builtin(builtin::Type::BOOL, executor)); Args{}.expect_builtin(builtin::Type::BOOL, executor));
Result case_result = Result case_result = Run(*expr.get_case(i).first,
Run(*expr.get_case(i).first, Args{}.expect(expression_result.has_value()
Arguments{}.expect(expression_result.has_value() ? expression_result.value().get()
? expression_result.value().get() : nodes::MaybeType{}));
: nodes::MaybeType{}));
if (!expression_result.has_value() && !case_result.is_invalid()) { if (!expression_result.has_value() && !case_result.is_invalid()) {
expression_result = std::move(case_result); expression_result = std::move(case_result);
@ -108,9 +105,9 @@ Result CheckTask<nodes::Condition>::operator()(const nodes::Condition &expr,
if (expr.get_else_case().has_value()) { if (expr.get_else_case().has_value()) {
Run(*expr.get_else_case().value(), Run(*expr.get_else_case().value(),
Arguments{}.expect(expression_result.has_value() Args{}.expect(expression_result.has_value()
? expression_result.value().get() ? expression_result.value().get()
: nodes::MaybeType{})); : nodes::MaybeType{}));
} }
if (!expression_result.has_value()) { if (!expression_result.has_value()) {
@ -119,13 +116,13 @@ Result CheckTask<nodes::Condition>::operator()(const nodes::Condition &expr,
expression_result = Result::invalid(); expression_result = Result::invalid();
} }
return type_check_from_arguments( return type_check_from_args(
state<Types>().add_array_of(expression_result.value().get()), args, expr, state<Types>().add_array_of(expression_result.value().get()), args, expr,
executor); executor);
} }
Result CheckTask<nodes::Loop>::operator()(const nodes::Loop &expr, Result CheckTask<nodes::Loop>::operator()(const nodes::Loop &expr,
const Arguments &args) { const Args &args) {
// TODO: ranges ?? // TODO: ranges ??
MaybeResult interval_result; MaybeResult interval_result;
@ -139,7 +136,7 @@ Result CheckTask<nodes::Loop>::operator()(const nodes::Loop &expr,
break; break;
case nodes::Loop::WHILE: case nodes::Loop::WHILE:
Run(*expr.get_condition().value(), Run(*expr.get_condition().value(),
Arguments{}.expect_builtin(builtin::Type::BOOL, executor)); Args{}.expect_builtin(builtin::Type::BOOL, executor));
// --- type check is independent from loop itself --- // --- type check is independent from loop itself ---
// if (condition_result.value().is_invalid()) { // if (condition_result.value().is_invalid()) {
@ -151,7 +148,7 @@ Result CheckTask<nodes::Loop>::operator()(const nodes::Loop &expr,
// TODO: expect range ?? // TODO: expect range ??
interval_result = interval_result =
Run(*expr.get_interval().value(), Run(*expr.get_interval().value(),
Arguments{}.expect_builtin(builtin::Type::ARRAY, executor)); Args{}.expect_builtin(builtin::Type::ARRAY, executor));
if (interval_result.value().is_invalid()) { if (interval_result.value().is_invalid()) {
// --- type check is independent from loop itself --- // --- type check is independent from loop itself ---
@ -161,7 +158,7 @@ Result CheckTask<nodes::Loop>::operator()(const nodes::Loop &expr,
variable_result = variable_result =
Run(*expr.get_variable().value(), Run(*expr.get_variable().value(),
Arguments{}.expect( Args{}.expect(
interval_result.value().get().get()->get_parameter_proxy(0))); interval_result.value().get().get()->get_parameter_proxy(0)));
// --- type check is independent from loop itself --- // --- type check is independent from loop itself ---
@ -177,7 +174,7 @@ Result CheckTask<nodes::Loop>::operator()(const nodes::Loop &expr,
// TODO: modifier checks ??, modifiers ?? // TODO: modifier checks ??, modifiers ??
return type_check_from_arguments( return type_check_from_args(
state<Types>().add_array_of(expression_result.get()), args, expr, state<Types>().add_array_of(expression_result.get()), args, expr,
executor); executor);
} // IN PROGRESS } // IN PROGRESS
@ -185,7 +182,7 @@ Result CheckTask<nodes::Loop>::operator()(const nodes::Loop &expr,
// --- containers // --- containers
Result CheckTask<nodes::Container>::CheckArray(const nodes::Container &expr, Result CheckTask<nodes::Container>::CheckArray(const nodes::Container &expr,
const Arguments &args) { const Args &args) {
MaybeResult last_expression_result; MaybeResult last_expression_result;
for (size_t i = 0; i < expr.expressions_size(); ++i) { for (size_t i = 0; i < expr.expressions_size(); ++i) {
@ -209,13 +206,13 @@ Result CheckTask<nodes::Container>::CheckArray(const nodes::Container &expr,
return Result::invalid(); return Result::invalid();
} }
return type_check_from_arguments( return type_check_from_args(
state<Types>().add_array_of(last_expression_result.value().get()), args, state<Types>().add_array_of(last_expression_result.value().get()), args,
expr, executor); expr, executor);
} }
Result CheckTask<nodes::Container>::CheckBlock(const nodes::Container &expr, Result CheckTask<nodes::Container>::CheckBlock(const nodes::Container &expr,
const Arguments &args) { const Args &args) {
nodes::MaybeType context_exit_type; nodes::MaybeType context_exit_type;
{ {
@ -234,13 +231,13 @@ Result CheckTask<nodes::Container>::CheckBlock(const nodes::Container &expr,
? Result(context_exit_type.value()) ? Result(context_exit_type.value())
: Result(state<Types>().primitive(builtin::Type::UNIT)); : Result(state<Types>().primitive(builtin::Type::UNIT));
return type_check_from_arguments( return type_check_from_args(
state<Types>().add_array_of(block_brought_type.get()), args, expr, state<Types>().add_array_of(block_brought_type.get()), args, expr,
executor); executor);
} }
Result CheckTask<nodes::Container>::operator()(const nodes::Container &expr, Result CheckTask<nodes::Container>::operator()(const nodes::Container &expr,
const Arguments &args) { const Args &args) {
switch (expr.get_type()) { switch (expr.get_type()) {
case nodes::Container::ARRAY: case nodes::Container::ARRAY:
return CheckArray(expr, args); return CheckArray(expr, args);
@ -252,7 +249,7 @@ Result CheckTask<nodes::Container>::operator()(const nodes::Container &expr,
// --- modifiers // --- modifiers
Result CheckTask<nodes::Return>::operator()(const nodes::Return &expr, Result CheckTask<nodes::Return>::operator()(const nodes::Return &expr,
const Arguments &args) { const Args &args) {
auto returned_result = Run(*expr.get_expression(), {}); auto returned_result = Run(*expr.get_expression(), {});
if (returned_result.is_invalid()) { if (returned_result.is_invalid()) {
@ -275,14 +272,14 @@ Result CheckTask<nodes::Return>::operator()(const nodes::Return &expr,
break; break;
} }
return type_check_from_arguments( return type_check_from_args(state<Types>().primitive(builtin::Type::UNIT),
state<Types>().primitive(builtin::Type::UNIT), args, expr, executor); args, expr, executor);
} }
// TODO: warning if name is same to package prefix, function prefix, etc. ?? // TODO: warning if name is same to package prefix, function prefix, etc. ??
Result Result
CheckTask<nodes::NameDefinition>::operator()(const nodes::NameDefinition &expr, CheckTask<nodes::NameDefinition>::operator()(const nodes::NameDefinition &expr,
const Arguments &args) { const Args &args) {
if (!args.get_passed().has_value()) { if (!args.get_passed().has_value()) {
type_check_error("Can't deduce type of new variable from context", expr, type_check_error("Can't deduce type of new variable from context", expr,
executor); executor);
@ -307,19 +304,17 @@ CheckTask<nodes::NameDefinition>::operator()(const nodes::NameDefinition &expr,
} }
// Return BOOL as any := / =: expression // Return BOOL as any := / =: expression
return type_check_from_arguments( return type_check_from_args(state<Types>().primitive(builtin::Type::BOOL),
state<Types>().primitive(builtin::Type::BOOL), args, expr, executor); args, expr, executor);
} }
Result CheckTask<nodes::Access>::CheckArrayAccess(const nodes::Access &expr, Result CheckTask<nodes::Access>::CheckArrayAccess(const nodes::Access &expr,
const Arguments &args) { const Args &args) {
auto index_result = auto index_result = Run(
Run(*expr.get_index(), *expr.get_index(), Args{}.expect_builtin(builtin::Type::INDEX, executor));
Arguments{}.expect_builtin(builtin::Type::INDEX, executor));
auto value_result = auto value_result = Run(
Run(*expr.get_value(), *expr.get_value(), Args{}.expect_builtin(builtin::Type::ARRAY, executor));
Arguments{}.expect_builtin(builtin::Type::ARRAY, executor));
if (index_result.is_invalid()) { if (index_result.is_invalid()) {
return index_result; return index_result;
@ -331,15 +326,14 @@ Result CheckTask<nodes::Access>::CheckArrayAccess(const nodes::Access &expr,
// TODO: modifier checks ?? // TODO: modifier checks ??
return type_check_from_arguments( return type_check_from_args(value_result.get().get()->get_parameter_proxy(0),
value_result.get().get()->get_parameter_proxy(0), args, expr, executor); args, expr, executor);
} }
Result CheckTask<nodes::Access>::CheckTupleAccess(const nodes::Access &expr, Result CheckTask<nodes::Access>::CheckTupleAccess(const nodes::Access &expr,
const Arguments &args) { const Args &args) {
auto value_result = auto value_result = Run(
Run(*expr.get_value(), *expr.get_value(), Args{}.expect_builtin(builtin::Type::TUPLE, executor));
Arguments{}.expect_builtin(builtin::Type::TUPLE, executor));
if (value_result.is_invalid()) { if (value_result.is_invalid()) {
return value_result; return value_result;
@ -353,13 +347,13 @@ Result CheckTask<nodes::Access>::CheckTupleAccess(const nodes::Access &expr,
// TODO: modifier checks ?? // TODO: modifier checks ??
return type_check_from_arguments( return type_check_from_args(
value_result.get().get()->get_parameter_proxy(index), args, expr, value_result.get().get()->get_parameter_proxy(index), args, expr,
executor); executor);
} }
Result CheckTask<nodes::Access>::operator()(const nodes::Access &expr, Result CheckTask<nodes::Access>::operator()(const nodes::Access &expr,
const Arguments &args) { const Args &args) {
switch (expr.get_type()) { switch (expr.get_type()) {
case nodes::Access::ARRAY: case nodes::Access::ARRAY:
return CheckArrayAccess(expr, args); return CheckArrayAccess(expr, args);
@ -369,13 +363,13 @@ Result CheckTask<nodes::Access>::operator()(const nodes::Access &expr,
} }
Result CheckTask<nodes::LoopControl>::operator()(const nodes::LoopControl &expr, Result CheckTask<nodes::LoopControl>::operator()(const nodes::LoopControl &expr,
const Arguments &args) { const Args &args) {
return type_check_from_arguments( return type_check_from_args(state<Types>().primitive(builtin::Type::UNIT),
state<Types>().primitive(builtin::Type::UNIT), args, expr, executor); args, expr, executor);
} }
Result CheckTask<nodes::ModifierExpression>::operator()( Result CheckTask<nodes::ModifierExpression>::operator()(
const nodes::ModifierExpression &expr, const Arguments &args) { const nodes::ModifierExpression &expr, const Args &args) {
auto modified_result = Run(*expr.get_expression(), {}); auto modified_result = Run(*expr.get_expression(), {});
if (modified_result.is_invalid()) { if (modified_result.is_invalid()) {
@ -407,7 +401,7 @@ Result CheckTask<nodes::ModifierExpression>::operator()(
modified_result.get(), expr.get_modifier())); modified_result.get(), expr.get_modifier()));
} }
return type_check_from_arguments(modified_result.get(), args, expr, executor); return type_check_from_args(modified_result.get(), args, expr, executor);
} // IN PROGRESS } // IN PROGRESS
// --- other // --- other
@ -415,7 +409,7 @@ Result CheckTask<nodes::ModifierExpression>::operator()(
// TODO // TODO
Result Result
CheckTask<nodes::NameExpression>::operator()(const nodes::NameExpression &expr, CheckTask<nodes::NameExpression>::operator()(const nodes::NameExpression &expr,
const Arguments &args) { const Args &args) {
// TODO: constraints ?? // TODO: constraints ??
const auto name = expr.get_name(); const auto name = expr.get_name();
@ -488,16 +482,16 @@ CheckTask<nodes::NameExpression>::operator()(const nodes::NameExpression &expr,
// TODO: count passed type, if needed // TODO: count passed type, if needed
// TODO: manage situation with one out type at any position // TODO: manage situation with one out type at any position
// TODO + 1 - returned type - somtimes (can be ==) // TODO + 1 - returned type - somtimes (can be ==)
const auto arguments_given = expr.arguments_size(); const auto args_given = expr.args_size();
const auto arguments_defined = function_definition->arguments_size(); const auto args_defined = function_definition->args_size();
if (arguments_given + 1 < arguments_defined || if (args_given + 1 < args_defined ||
arguments_given > arguments_defined) { // other, when there is passed type args_given > args_defined) { // other, when there is passed type
type_check_error( type_check_error(
"Number of function arguments is different from expected (" + "Number of function args is different from expected (" +
std::to_string(arguments_given) + " instead of " + std::to_string(args_given) + " instead of " +
std::to_string(arguments_defined) + std::to_string(args_defined) +
std::string{arguments_defined > 0 std::string{args_defined > 0
? (" or " + std::to_string(arguments_defined - 1)) ? (" or " + std::to_string(args_defined - 1))
: ""} + : ""} +
")", ")",
expr, executor); expr, executor);
@ -508,7 +502,7 @@ CheckTask<nodes::NameExpression>::operator()(const nodes::NameExpression &expr,
// TODO: define types for generic function // TODO: define types for generic function
std::vector<Result> function_argument_results; std::vector<Result> function_argument_results;
for (size_t i = 0; i < arguments_given; for (size_t i = 0; i < args_given;
++i) { // TODO: pass types with oud modifier ++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);
@ -541,10 +535,10 @@ CheckTask<nodes::NameExpression>::operator()(const nodes::NameExpression &expr,
function_argument_results.push_back( function_argument_results.push_back(
Run(*expr.get_argument_value(i), Run(*expr.get_argument_value(i),
Arguments{}.expect(argument->get_type_proxy().value()))); Args{}.expect(argument->get_type_proxy().value())));
} }
if (function_definition->arguments_size() == 0) { if (function_definition->args_size() == 0) {
type_check_error( type_check_error(
"Function arguments size is zero. Returned type is not defined", expr, "Function arguments size is zero. Returned type is not defined", expr,
executor); executor);
@ -552,11 +546,10 @@ CheckTask<nodes::NameExpression>::operator()(const nodes::NameExpression &expr,
} }
// TODO: check condition // TODO: check condition
if (arguments_given + 1 == arguments_defined) { if (args_given + 1 == args_defined) {
// returned type // returned type
const nodes::FunctionDefinition::Argument *returned = const nodes::FunctionDefinition::Argument *returned =
function_definition->get_argument( function_definition->get_argument(function_definition->args_size() - 1);
function_definition->arguments_size() - 1);
// TODO: invert modifier ?? // TODO: invert modifier ??
if (!returned->get_type().has_value()) { if (!returned->get_type().has_value()) {
@ -567,9 +560,9 @@ CheckTask<nodes::NameExpression>::operator()(const nodes::NameExpression &expr,
} }
// TODO: invert modifier ?? // TODO: invert modifier ??
// TODO: generic types should be deduced from arguments // TODO: generic types should be deduced from args
return type_check_from_arguments(returned->get_type_proxy().value(), args, return type_check_from_args(returned->get_type_proxy().value(), args, expr,
expr, executor); executor);
} }
// checks for universal call syntax ?? // checks for universal call syntax ??
@ -579,7 +572,7 @@ CheckTask<nodes::NameExpression>::operator()(const nodes::NameExpression &expr,
// TODO // TODO
Result CheckTask<nodes::Constructor>::operator()(const nodes::Constructor &expr, Result CheckTask<nodes::Constructor>::operator()(const nodes::Constructor &expr,
const Arguments &args) { const Args &args) {
// TODO: constraints ?? // TODO: constraints ??
// TODO: use pass type // TODO: use pass type
@ -605,7 +598,7 @@ Result CheckTask<nodes::Constructor>::operator()(const nodes::Constructor &expr,
// TODO: work with different parametric types: tuple, variant, ... // TODO: work with different parametric types: tuple, variant, ...
if (expr.arguments_size() == 0) { if (expr.args_size() == 0) {
type_check_error("Number of type constructor arguments should be > 0", expr, type_check_error("Number of type constructor arguments should be > 0", expr,
executor); executor);
return Result::invalid(); return Result::invalid();
@ -613,18 +606,18 @@ Result CheckTask<nodes::Constructor>::operator()(const nodes::Constructor &expr,
// generic) // generic)
} }
// TODO: work with generics (type_definition->arguments, ...) // TODO: work with generics (type_definition->args, ...)
const auto builtin_type = type.get()->to_builtin(); const auto builtin_type = type.get()->to_builtin();
{ // check arguments size, ets. { // check args size, ets.
switch (builtin_type) { switch (builtin_type) {
case builtin::Type::TUPLE: case builtin::Type::TUPLE:
if (expr.arguments_size() != type.get()->parameters_size()) { if (expr.args_size() != type.get()->parameters_size()) {
type_check_error( type_check_error(
"Number of type constructor arguments is different from expected " "Number of type constructor arguments is different from expected "
"(" + "(" +
std::to_string(expr.arguments_size()) + " instead of " + std::to_string(expr.args_size()) + " instead of " +
std::to_string(type.get()->parameters_size()) + ")", std::to_string(type.get()->parameters_size()) + ")",
expr, executor); expr, executor);
return Result::invalid(); return Result::invalid();
@ -638,7 +631,7 @@ Result CheckTask<nodes::Constructor>::operator()(const nodes::Constructor &expr,
case builtin::Type::ERROR: case builtin::Type::ERROR:
case builtin::Type::FUNCTION: case builtin::Type::FUNCTION:
case builtin::Type::NONE: case builtin::Type::NONE:
if (expr.arguments_size() != 1) { // TODO: better to_string if (expr.args_size() != 1) { // TODO: better to_string
type_check_error("Number of type constructor arguments should be = 1 " type_check_error("Number of type constructor arguments should be = 1 "
"(builtin type " + "(builtin type " +
std::to_string(uint(builtin_type)) + ")", std::to_string(uint(builtin_type)) + ")",
@ -717,7 +710,7 @@ Result CheckTask<nodes::Constructor>::operator()(const nodes::Constructor &expr,
switch (builtin_type) { switch (builtin_type) {
case builtin::Type::TUPLE: case builtin::Type::TUPLE:
for (size_t i = 0; i < expr.arguments_size(); ++i) { for (size_t i = 0; i < expr.args_size(); ++i) {
check_same_annotation(i, type.get()->get_parameter(i)->get_annotation(), check_same_annotation(i, type.get()->get_parameter(i)->get_annotation(),
true /*log errors*/); true /*log errors*/);
} }
@ -755,18 +748,18 @@ Result CheckTask<nodes::Constructor>::operator()(const nodes::Constructor &expr,
} }
} }
{ // type check arguments { // type check args
switch (builtin_type) { switch (builtin_type) {
case builtin::Type::TUPLE: case builtin::Type::TUPLE:
for (size_t i = 0; i < expr.arguments_size(); ++i) { for (size_t i = 0; i < expr.args_size(); ++i) {
Run(*expr.get_argument_value(i), Run(*expr.get_argument_value(i),
Arguments{}.expect(type.get()->get_parameter_proxy(i))); Args{}.expect(type.get()->get_parameter_proxy(i)));
} }
break; break;
case builtin::Type::VARIANT: case builtin::Type::VARIANT:
if (chosen_variant_option.has_value()) { if (chosen_variant_option.has_value()) {
Run(*expr.get_argument_value(0), Run(*expr.get_argument_value(0),
Arguments{}.expect(type.get()->get_parameter_proxy( Args{}.expect(type.get()->get_parameter_proxy(
chosen_variant_option.value()))); chosen_variant_option.value())));
} else { // TODO: error, if there is more then one possible variant in } else { // TODO: error, if there is more then one possible variant in
// answer // answer
@ -774,32 +767,32 @@ Result CheckTask<nodes::Constructor>::operator()(const nodes::Constructor &expr,
for (size_t i = 0; i < type.get()->parameters_size(); ++i) { for (size_t i = 0; i < type.get()->parameters_size(); ++i) {
possible_options.push_back(type.get()->get_parameter_proxy(i)); possible_options.push_back(type.get()->get_parameter_proxy(i));
} }
Run(*expr.get_argument_value(0), Arguments{}.expect(possible_options)); Run(*expr.get_argument_value(0), Args{}.expect(possible_options));
} }
break; break;
case builtin::Type::OPTIONAL: case builtin::Type::OPTIONAL:
// first parameter or NULL // first parameter or NULL
Run(*expr.get_argument_value(0), Run(*expr.get_argument_value(0),
Arguments{}.expect( Args{}.expect(
{type.get()->get_parameter_proxy(0), {type.get()->get_parameter_proxy(0),
state<Types>().primitive(builtin::Type::NULL_OPTION)})); state<Types>().primitive(builtin::Type::NULL_OPTION)}));
break; break;
case builtin::Type::RESULT: case builtin::Type::RESULT:
// first parameter or ERROR[second parameter] // first parameter or ERROR[second parameter]
Run(*expr.get_argument_value(0), Run(*expr.get_argument_value(0),
Arguments{}.expect({type.get()->get_parameter_proxy(0), Args{}.expect({type.get()->get_parameter_proxy(0),
state<Types>().add_error_of( state<Types>().add_error_of(
type.get()->get_parameter_proxy(1))})); type.get()->get_parameter_proxy(1))}));
break; break;
case builtin::Type::ERROR: case builtin::Type::ERROR:
// first parameter // first parameter
Run(*expr.get_argument_value(0), Run(*expr.get_argument_value(0),
Arguments{}.expect(type.get()->get_parameter_proxy(0))); Args{}.expect(type.get()->get_parameter_proxy(0)));
break; break;
case builtin::Type::FUNCTION: case builtin::Type::FUNCTION:
case builtin::Type::NONE: case builtin::Type::NONE:
// type itself // type itself
Run(*expr.get_argument_value(0), Arguments{}.expect(type)); Run(*expr.get_argument_value(0), Args{}.expect(type));
break; break;
default: // array, basic types default: // array, basic types
type_check_error("Type can't be constructed", expr, executor); type_check_error("Type can't be constructed", expr, executor);
@ -808,14 +801,14 @@ Result CheckTask<nodes::Constructor>::operator()(const nodes::Constructor &expr,
} }
// TODO: deduce generic parts in type // TODO: deduce generic parts in type
return type_check_from_arguments(expr.get_type_proxy(), args, expr, executor); return type_check_from_args(expr.get_type_proxy(), args, expr, executor);
// TODO: add <- modifiier to type ?? // TODO: add <- modifiier to type ??
} // IN PROGRESS } // IN PROGRESS
// TODO // TODO
Result CheckTask<nodes::Lambda>::operator()(const nodes::Lambda &expr, Result CheckTask<nodes::Lambda>::operator()(const nodes::Lambda &expr,
const Arguments &args) { const Args &args) {
if (args.get_expected().empty()) { if (args.get_expected().empty()) {
type_check_error("Can't deduce type of lambda function from context: no " type_check_error("Can't deduce type of lambda function from context: no "
"one type expected", "one type expected",
@ -836,15 +829,15 @@ Result CheckTask<nodes::Lambda>::operator()(const nodes::Lambda &expr,
} }
// TODO: deal with return type (+1 sometimes), etc // TODO: deal with return type (+1 sometimes), etc
const auto arguments_given = expr.arguments_size(); const auto args_given = expr.args_size();
const auto arguments_defined = expected_type.get()->parameters_size(); const auto args_defined = expected_type.get()->parameters_size();
if (arguments_given != arguments_defined) { if (args_given != args_defined) {
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(arguments_given) + " instead of " + std::to_string(args_given) + " instead of " +
std::to_string(arguments_defined) + std::to_string(args_defined) +
std::string{arguments_defined > 0 std::string{args_defined > 0
? (" or " + std::to_string(arguments_defined - 1)) ? (" or " + std::to_string(args_defined - 1))
: ""} + : ""} +
")", ")",
expr, executor); expr, executor);
@ -852,7 +845,7 @@ Result CheckTask<nodes::Lambda>::operator()(const nodes::Lambda &expr,
// TODO: set another context (for expression typecheck and vars) // TODO: set another context (for expression typecheck and vars)
for (size_t i = 0; i < arguments_given; ++i) { for (size_t i = 0; i < args_given; ++i) {
if (!state<State>().insert_variable( if (!state<State>().insert_variable(
*expr.get_argument(i)->get(), *expr.get_argument(i)->get(),
expected_type.get()->get_parameter_proxy(i), expected_type.get()->get_parameter_proxy(i),
@ -864,24 +857,23 @@ Result CheckTask<nodes::Lambda>::operator()(const nodes::Lambda &expr,
} }
// TODO: out type is can be not last // TODO: out type is can be not last
if (arguments_given + 1 == arguments_defined) { if (args_given + 1 == args_defined) {
Run(*expr.get_expression(), Run(*expr.get_expression(),
Arguments{}.expect( Args{}.expect(
expected_type.get()->get_parameter_proxy(arguments_defined - 1))); expected_type.get()->get_parameter_proxy(args_defined - 1)));
} }
// TODO: needed ?? (only passed type check required ??) // TODO: needed ?? (only passed type check required ??)
return type_check_from_arguments(expected_type, args, expr, executor); return type_check_from_args(expected_type, args, expr, executor);
} // IN PROGRESS } // IN PROGRESS
Result CheckTask<nodes::Extra>::operator()(const nodes::Extra &, Result CheckTask<nodes::Extra>::operator()(const nodes::Extra &, const Args &) {
const Arguments &) {
return Result(state<Types>().primitive(builtin::Type::UNIT)); return Result(state<Types>().primitive(builtin::Type::UNIT));
} }
Result CheckTask<nodes::EmptyLines>::operator()(const nodes::EmptyLines &, Result CheckTask<nodes::EmptyLines>::operator()(const nodes::EmptyLines &,
const Arguments &) { const Args &) {
return Result(state<Types>().primitive(builtin::Type::UNIT)); return Result(state<Types>().primitive(builtin::Type::UNIT));
} }

View file

@ -6,30 +6,30 @@ namespace type_check {
// pass type -> compare types, return bool // pass type -> compare types, return bool
// no pass type -> return type // no pass type -> return type
nodes::Type check_same_to_pass_type_in_arguments( nodes::Type check_same_to_pass_type_in_args(nodes::Type type, const Args &args,
nodes::Type type, const Arguments &arguments, const nodes::Node & /*node*/, const nodes::Node & /*node*/,
Executor &executor, const std::string &message, bool handle_errors) { Executor &executor,
const std::string &message,
bool handle_errors) {
Log::Context logc(executor.log(), utils::Log::Area::kTypeCheck); Log::Context logc(executor.log(), utils::Log::Area::kTypeCheck);
if (not arguments.get_passed().has_value()) { if (not args.get_passed().has_value()) {
return type; return type;
} }
if (type != arguments.get_passed().value() and handle_errors) { if (type != args.get_passed().value() and handle_errors) {
logc.Error<Log::kProc>({{message}} /* TODO: node */); logc.Error<Log::kProc>({{message}} /* TODO: node */);
} }
return executor.state<Types>().primitive(builtin::Type::BOOL); return executor.state<Types>().primitive(builtin::Type::BOOL);
} }
bool check_no_pass_type_in_arguments(const Arguments &arguments, bool check_no_pass_type_in_args(const Args &args, const nodes::Node &node,
const nodes::Node &node, Executor &executor, const std::string &message,
Executor &executor, bool handle_errors) {
const std::string &message,
bool handle_errors) {
Log::Context logc(executor.log(), utils::Log::Area::kTypeCheck); Log::Context logc(executor.log(), utils::Log::Area::kTypeCheck);
if (arguments.get_passed().has_value()) { if (args.get_passed().has_value()) {
type_check_error(message, node, executor, handle_errors); type_check_error(message, node, executor, handle_errors);
return false; return false;
} }
@ -37,12 +37,12 @@ bool check_no_pass_type_in_arguments(const Arguments &arguments,
return true; return true;
} }
Result type_same_to_expected(nodes::Type type, const Arguments &arguments, Result type_same_to_expected(nodes::Type type, const Args &args,
const nodes::Node & /*node*/, Executor &executor, const nodes::Node & /*node*/, Executor &executor,
const std::string &message, bool handle_errors) { const std::string &message, bool handle_errors) {
Log::Context logc(executor.log(), utils::Log::Area::kTypeCheck); Log::Context logc(executor.log(), utils::Log::Area::kTypeCheck);
const auto &expected = arguments.get_expected(); const auto &expected = args.get_expected();
if (expected.empty()) { if (expected.empty()) {
return Result{type}; return Result{type};
@ -60,10 +60,9 @@ Result type_same_to_expected(nodes::Type type, const Arguments &arguments,
return Result{expected.front()}; // any can be choosen return Result{expected.front()}; // any can be choosen
} }
Result type_check_from_arguments(nodes::Type /*type*/, Result type_check_from_args(nodes::Type /*type*/, const Args & /*args*/,
const Arguments & /*arguments*/, const nodes::Node & /*node*/, Executor &executor,
const nodes::Node & /*node*/, bool /*handle_errors*/) {
Executor &executor, bool /*handle_errors*/) {
Log::Context logc(executor.log(), utils::Log::Area::kTypeCheck); Log::Context logc(executor.log(), utils::Log::Area::kTypeCheck);
/* TODO FIXME */ /* TODO FIXME */
@ -140,7 +139,7 @@ std::optional<nodes::Type> unfold_user_defined_type(nodes::Type type,
return std::nullopt; return std::nullopt;
} }
// TODO: perform type arguments substitution // TODO: perform type args substitution
logc.Require<Log::kProc>(type.get()->parameters_size() == 0, logc.Require<Log::kProc>(type.get()->parameters_size() == 0,
{{"Unfold of generic type is not supported (yet)"}}); {{"Unfold of generic type is not supported (yet)"}});
// //