mirror of
https://codeberg.org/ProgramSnail/lang.git
synced 2025-12-06 06:58:46 +00:00
arguments -> args
This commit is contained in:
parent
76bd92e9fb
commit
8f96a818ff
16 changed files with 358 additions and 389 deletions
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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,13 +274,13 @@ 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(
|
||||||
|
|
@ -288,27 +288,27 @@ BuilderTask<nodes::NameExpression, utils::CommaTag>::operator()(
|
||||||
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,8 +393,7 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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>());
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
|
|
|
||||||
|
|
@ -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_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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(),
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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,24 +298,24 @@ 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);
|
||||||
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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,7 +56,7 @@ 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{}));
|
||||||
|
|
||||||
|
|
@ -82,22 +80,21 @@ 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{}));
|
||||||
|
|
||||||
|
|
@ -108,7 +105,7 @@ 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{}));
|
||||||
}
|
}
|
||||||
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
|
||||||
const std::string &message,
|
|
||||||
bool handle_errors) {
|
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)"}});
|
||||||
//
|
//
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue