[PART] most of builders and nodes changed to use new system

This commit is contained in:
ProgramSnail 2024-08-29 14:56:49 +03:00
parent 8f96a818ff
commit d02c3a637b
22 changed files with 1397 additions and 1536 deletions

View file

@ -17,7 +17,7 @@
class SourcesManager { class SourcesManager {
public: public:
void AddFile(const std::string &filename) { void AddFile(const std::string &filename) {
Log::Context logc(executor_.log(), utils::Log::Area::kParse); Log::Context logc(executor_.log(), Log::Area::kParse);
std::ifstream in; std::ifstream in;
in.open(filename); in.open(filename);
@ -64,6 +64,6 @@ public:
private: private:
builders::Executor executor_ = builders::Executor executor_ =
builders::Executor(utils::BuildPrintLog(std::cout), {}, {}, {}, {}); builders::Executor(utils::BuildPrintLog(std::cout), {}, {}, {}, {}, {});
std::vector<nodes::Statement> statements_ = {}; std::vector<nodes::Statement> statements_ = {};
}; };

View file

@ -1,69 +1,260 @@
#pragma once #pragma once
#include "basic_nodes.hpp" #include "basic_nodes.hpp"
#include "builders_utils.hpp"
#include "tree_sitter_wrapper.hpp" #include "tree_sitter_wrapper.hpp"
namespace utils {
struct SimpleNameIdTag {};
struct SimpleTypeIdTag {};
struct TypeclassIdTag {};
struct ArgNameIdTag {};
struct ArgTypeIdTag {};
struct OperatorIdTag {};
struct PlaceholderIdTag {};
struct GenericTypeIdTag {};
}; // namespace utils
namespace builders { namespace builders {
// returns Modifier::NONE for incorrecnt input // returns Modifier::NONE for incorrecnt input
nodes::Modifier build_modifier(parser::ParseTree::Node parser_node); template <>
struct BuilderTask<nodes::Modifier>
: public BasicBuilderTaskBase<nodes::Modifier> {
using BasicBuilderTaskBase<nodes::Modifier>::BasicBuilderTaskBase;
nodes::Node build_node(parser::ParseTree::Node parser_node); nodes::Modifier operator()(const ParserNode &parser_node,
const Args &args) override;
};
// --- literals // --- literals
nodes::Literal build_float_literal(parser::ParseTree::Node parser_node); // nodes::Literal build_float_literal(parser::ParseTree::Node parser_node);
template <>
struct BuilderTask<nodes::Literal, float>
: public BasicBuilderTaskBase<nodes::Literal> {
using BasicBuilderTaskBase<nodes::Literal>::BasicBuilderTaskBase;
nodes::Literal build_double_literal(parser::ParseTree::Node parser_node); nodes::Literal operator()(const ParserNode &parser_node,
const Args &args) override;
};
nodes::Literal build_int_literal(parser::ParseTree::Node parser_node); // nodes::Literal build_double_literal(parser::ParseTree::Node parser_node);
template <>
struct BuilderTask<nodes::Literal, double>
: public BasicBuilderTaskBase<nodes::Literal> {
using BasicBuilderTaskBase<nodes::Literal>::BasicBuilderTaskBase;
nodes::Literal build_long_literal(parser::ParseTree::Node parser_node); nodes::Literal operator()(const ParserNode &parser_node,
const Args &args) override;
};
nodes::Literal build_index_literal(parser::ParseTree::Node parser_node); // nodes::Literal build_int_literal(parser::ParseTree::Node parser_node);
template <>
struct BuilderTask<nodes::Literal, int32_t> // int
: public BasicBuilderTaskBase<nodes::Literal> {
using BasicBuilderTaskBase<nodes::Literal>::BasicBuilderTaskBase;
nodes::Literal build_string_literal(parser::ParseTree::Node parser_node); nodes::Literal operator()(const ParserNode &parser_node,
const Args &args) override;
};
nodes::Literal // nodes::Literal build_long_literal(parser::ParseTree::Node parser_node);
build_unicode_string_literal(parser::ParseTree::Node parser_node); template <>
struct BuilderTask<nodes::Literal, int64_t> // long
: public BasicBuilderTaskBase<nodes::Literal> {
using BasicBuilderTaskBase<nodes::Literal>::BasicBuilderTaskBase;
nodes::Literal build_char_literal(parser::ParseTree::Node parser_node); nodes::Literal operator()(const ParserNode &parser_node,
const Args &args) override;
};
nodes::Literal build_unicode_literal(parser::ParseTree::Node parser_node); // nodes::Literal build_index_literal(parser::ParseTree::Node parser_node);
template <>
struct BuilderTask<nodes::Literal, size_t> // index
: public BasicBuilderTaskBase<nodes::Literal> {
using BasicBuilderTaskBase<nodes::Literal>::BasicBuilderTaskBase;
nodes::Literal build_bool_literal(parser::ParseTree::Node parser_node); nodes::Literal operator()(const ParserNode &parser_node,
const Args &args) override;
};
nodes::Literal build_unit_literal(parser::ParseTree::Node parser_node); // nodes::Literal build_string_literal(parser::ParseTree::Node parser_node);
template <>
struct BuilderTask<nodes::Literal, std::string> // string
: public BasicBuilderTaskBase<nodes::Literal> {
using BasicBuilderTaskBase<nodes::Literal>::BasicBuilderTaskBase;
nodes::Literal build_null_literal(parser::ParseTree::Node parser_node); nodes::Literal operator()(const ParserNode &parser_node,
const Args &args) override;
};
// nodes::Literal
// build_unicode_string_literal(parser::ParseTree::Node parser_node);
template <>
struct BuilderTask<nodes::Literal, nodes::unicode_string>
: public BasicBuilderTaskBase<nodes::Literal> {
using BasicBuilderTaskBase<nodes::Literal>::BasicBuilderTaskBase;
nodes::Literal operator()(const ParserNode &parser_node,
const Args &args) override;
};
// nodes::Literal build_char_literal(parser::ParseTree::Node parser_node);
template <>
struct BuilderTask<nodes::Literal, char>
: public BasicBuilderTaskBase<nodes::Literal> {
using BasicBuilderTaskBase<nodes::Literal>::BasicBuilderTaskBase;
nodes::Literal operator()(const ParserNode &parser_node,
const Args &args) override;
};
// nodes::Literal build_unicode_literal(parser::ParseTree::Node parser_node);
template <>
struct BuilderTask<nodes::Literal, nodes::unicode>
: public BasicBuilderTaskBase<nodes::Literal> {
using BasicBuilderTaskBase<nodes::Literal>::BasicBuilderTaskBase;
nodes::Literal operator()(const ParserNode &parser_node,
const Args &args) override;
};
// nodes::Literal build_bool_literal(parser::ParseTree::Node parser_node);
template <>
struct BuilderTask<nodes::Literal, bool>
: public BasicBuilderTaskBase<nodes::Literal> {
using BasicBuilderTaskBase<nodes::Literal>::BasicBuilderTaskBase;
nodes::Literal operator()(const ParserNode &parser_node,
const Args &args) override;
};
// nodes::Literal build_unit_literal(parser::ParseTree::Node parser_node);
template <>
struct BuilderTask<nodes::Literal, nodes::unit>
: public BasicBuilderTaskBase<nodes::Literal> {
using BasicBuilderTaskBase<nodes::Literal>::BasicBuilderTaskBase;
nodes::Literal operator()(const ParserNode &parser_node,
const Args &args) override;
};
// nodes::Literal build_null_literal(parser::ParseTree::Node parser_node);
template <>
struct BuilderTask<nodes::Literal, nodes::null>
: public BasicBuilderTaskBase<nodes::Literal> {
using BasicBuilderTaskBase<nodes::Literal>::BasicBuilderTaskBase;
nodes::Literal operator()(const ParserNode &parser_node,
const Args &args) override;
};
// --- identifiers // --- identifiers
nodes::Identifier build_identifier(parser::ParseTree::Node parser_node); template <>
struct BuilderTask<nodes::Identifier>
: public BasicBuilderTaskBase<nodes::Identifier> {
using BasicBuilderTaskBase<nodes::Identifier>::BasicBuilderTaskBase;
nodes::Identifier build_simple_name(parser::ParseTree::Node parser_node); nodes::Identifier operator()(const ParserNode &parser_node,
const Args &args) override;
};
nodes::Identifier build_simple_type(parser::ParseTree::Node parser_node); template <>
struct BuilderTask<nodes::Identifier, utils::SimpleNameIdTag>
: public BasicBuilderTaskBase<nodes::Identifier> {
using BasicBuilderTaskBase<nodes::Identifier>::BasicBuilderTaskBase;
nodes::Identifier build_typeclass(parser::ParseTree::Node parser_node); nodes::Identifier operator()(const ParserNode &parser_node,
const Args &args) override;
};
nodes::Identifier build_argument_name(parser::ParseTree::Node parser_node); template <>
struct BuilderTask<nodes::Identifier, utils::SimpleTypeIdTag>
: public BasicBuilderTaskBase<nodes::Identifier> {
using BasicBuilderTaskBase<nodes::Identifier>::BasicBuilderTaskBase;
nodes::Identifier build_argument_type(parser::ParseTree::Node parser_node); nodes::Identifier operator()(const ParserNode &parser_node,
const Args &args) override;
};
template <>
struct BuilderTask<nodes::Identifier, utils::TypeclassIdTag>
: public BasicBuilderTaskBase<nodes::Identifier> {
using BasicBuilderTaskBase<nodes::Identifier>::BasicBuilderTaskBase;
nodes::Identifier operator()(const ParserNode &parser_node,
const Args &args) override;
};
template <>
struct BuilderTask<nodes::Identifier, utils::ArgNameIdTag>
: public BasicBuilderTaskBase<nodes::Identifier> {
using BasicBuilderTaskBase<nodes::Identifier>::BasicBuilderTaskBase;
nodes::Identifier operator()(const ParserNode &parser_node,
const Args &args) override;
};
template <>
struct BuilderTask<nodes::Identifier, utils::ArgTypeIdTag>
: public BasicBuilderTaskBase<nodes::Identifier> {
using BasicBuilderTaskBase<nodes::Identifier>::BasicBuilderTaskBase;
nodes::Identifier operator()(const ParserNode &parser_node,
const Args &args) override;
};
// Annotations are used as strings // Annotations are used as strings
std::string build_annotation(parser::ParseTree::Node parser_node); template <>
struct BuilderTask<nodes::Annotation>
: public BasicBuilderTaskBase<nodes::Annotation> {
using BasicBuilderTaskBase<nodes::Annotation>::BasicBuilderTaskBase;
nodes::Identifier build_operator(parser::ParseTree::Node parser_node); nodes::Annotation operator()(const ParserNode &parser_node,
const Args &args) override;
};
nodes::Identifier build_placeholder(parser::ParseTree::Node parser_node); template <>
struct BuilderTask<nodes::Identifier, utils::OperatorIdTag>
: public BasicBuilderTaskBase<nodes::Identifier> {
using BasicBuilderTaskBase<nodes::Identifier>::BasicBuilderTaskBase;
nodes::Identifier operator()(const ParserNode &parser_node,
const Args &args) override;
};
template <>
struct BuilderTask<nodes::Identifier, utils::PlaceholderIdTag>
: public BasicBuilderTaskBase<nodes::Identifier> {
using BasicBuilderTaskBase<nodes::Identifier>::BasicBuilderTaskBase;
nodes::Identifier operator()(const ParserNode &parser_node,
const Args &args) override;
};
// --- extra // --- extra
nodes::Extra build_extra(parser::ParseTree::Node parser_node); template <>
struct BuilderTask<nodes::Extra> : public BasicBuilderTaskBase<nodes::Extra> {
using BasicBuilderTaskBase<nodes::Extra>::BasicBuilderTaskBase;
nodes::Extra operator()(const ParserNode &parser_node,
const Args &args) override;
};
// --- empty lines // --- empty lines
nodes::EmptyLines build_empty_lines(parser::ParseTree::Node parser_node); template <>
struct BuilderTask<nodes::EmptyLines>
: public BasicBuilderTaskBase<nodes::EmptyLines> {
using BasicBuilderTaskBase<nodes::EmptyLines>::BasicBuilderTaskBase;
nodes::EmptyLines operator()(const ParserNode &parser_node,
const Args &args) override;
};
} // namespace builders } // namespace builders

View file

@ -7,26 +7,28 @@
namespace builders { namespace builders {
// using Code = parser::ParseTree; // using Code = parser::ParseTree;
using Exprs = nodes::ExprStorage; using Exprs = nodes::NodeStorage; // nodes::ExprStorage;
using Types = nodes::TypeStorage; using Types = nodes::TypeStorage;
using Names = names::NameTree; using Names = names::NameTree;
using Positions = core::DependentStorage<utils::Pos>;
// //
struct State { struct State {
std::optional<nodes::Identifier> last_defined_type_name; std::optional<nodes::Identifier> last_defined_type_name;
}; };
// //
using Executor = utils::Executor<Exprs, Types, Names, State>; using Executor = utils::Executor<Exprs, Types, Names, State, Positions>;
using ParserNode = parser::ParseTree::Node; using ParserNode = parser::ParseTree::Node;
// using Node = nodes::Node_<nodes::NodePart<utils::Pos>>; // TODO using Node = nodes::Node_<nodes::NodePart<utils::Pos>>;
using Args = utils::None; struct Args {
bool is_scoped = false;
};
template <typename N> template <typename N>
using Task = utils::Task<Executor, N, Args, parser::ParseTree::Node>; using Task = utils::Task<Executor, N, Args, parser::ParseTree::Node>;
@ -35,11 +37,71 @@ template <typename N, typename Tag = utils::None> struct BuilderTask {
static_assert(false); static_assert(false);
}; };
template <typename N> struct BuilderTaskBase : public Task<N> { template <typename N> struct BuilderTaskUtils : public Task<N> {
using Task<N>::Task; using Task<N>::Task;
template <typename OtherN, typename OtherTag = utils::None> Node Ext(storage::Id id) const {
OtherN Run(const parser::ParseTree::Node &node, const Args &args = {}) { return Node(id, this->template state<Exprs>(),
this->template state<Positions>());
}
template <typename T>
Node Expect(Node value, Log::Context &logc,
std::source_location source_location =
std::source_location::current()) const {
logc.Expect<Log::kProc>(value.Holds<T>(),
{{"value type requirement failed"}}, {},
source_location);
return value;
}
template <typename T> Node Build(T value, utils::Pos pos) {
auto id = this->template state<Exprs>().Insert(std::move(value));
this->template state<Positions>().ForceInsert(id, pos);
return GetNode(id);
}
};
//
template <typename N> struct BasicBuilderTaskBase : public BuilderTaskUtils<N> {
using BuilderTaskUtils<N>::BuilderTaskUtils;
template <typename OtherN, typename OtherTag = utils::None,
typename Ret = OtherN>
Ret Run(const parser::ParseTree::Node &node, const Args &args = {}) {
BuilderTask<OtherN, OtherTag> task(this->executor);
return task(node, args);
}
};
template <typename N>
struct ExprBuilderTaskBase : public BuilderTaskUtils<Node> {
using BuilderTaskUtils<Node>::BuilderTaskUtils;
template <typename OtherN, typename OtherTag = utils::None,
typename Ret = Node>
Ret Run(const parser::ParseTree::Node &node, const Args &args = {}) {
BuilderTask<OtherN, OtherTag> task(this->executor);
return task(node, args);
}
// TODO: rename
template <typename OtherN, typename OtherTag = utils::None,
typename Ret = OtherN>
Ret RunOther(const parser::ParseTree::Node &node, const Args &args = {}) {
BuilderTask<OtherN, OtherTag> task(this->executor);
return task(node, args);
}
};
template <typename N>
struct StatementBuilderTaskBase : public BuilderTaskUtils<N> {
using BuilderTaskUtils<N>::BuilderTaskUtils;
template <typename OtherN, typename OtherTag = utils::None,
typename Ret = OtherN>
Ret Run(const parser::ParseTree::Node &node, const Args &args = {}) {
BuilderTask<OtherN, OtherTag> task(this->executor); BuilderTask<OtherN, OtherTag> task(this->executor);
return task(node, args); return task(node, args);
} }

View file

@ -23,66 +23,58 @@ namespace builders {
// --- flow control // --- flow control
template <> template <> struct BuilderTask<Node> : public ExprBuilderTaskBase<Node> {
struct BuilderTask<nodes::Expr> : public BuilderTaskBase<nodes::Expr> { using ExprBuilderTaskBase<Node>::ExprBuilderTaskBase;
using BuilderTaskBase<nodes::Expr>::BuilderTaskBase;
nodes::Expr operator()(const ParserNode &parser_node, Node operator()(const ParserNode &parser_node, const Args &args) override;
const Args &args) override;
}; };
template <> template <>
struct BuilderTask<nodes::Match::Case> struct BuilderTask<nodes::Match::Case>
: public BuilderTaskBase<nodes::Match::Case> { : public ExprBuilderTaskBase<nodes::Match::Case> {
using BuilderTaskBase<nodes::Match::Case>::BuilderTaskBase; using ExprBuilderTaskBase<nodes::Match::Case>::ExprBuilderTaskBase;
nodes::Match::Case operator()(const ParserNode &parser_node, Node operator()(const ParserNode &parser_node, const Args &args) override;
const Args &args) override;
}; };
template <> template <>
struct BuilderTask<nodes::Match> : public BuilderTaskBase<nodes::Match> { struct BuilderTask<nodes::Match> : public ExprBuilderTaskBase<nodes::Match> {
using BuilderTaskBase<nodes::Match>::BuilderTaskBase; using ExprBuilderTaskBase<nodes::Match>::ExprBuilderTaskBase;
nodes::Match operator()(const ParserNode &parser_node, Node operator()(const ParserNode &parser_node, const Args &args) override;
const Args &args) override;
}; };
template <> template <>
struct BuilderTask<nodes::Condition> struct BuilderTask<nodes::Condition>
: public BuilderTaskBase<nodes::Condition> { : public ExprBuilderTaskBase<nodes::Condition> {
using BuilderTaskBase<nodes::Condition>::BuilderTaskBase; using ExprBuilderTaskBase<nodes::Condition>::ExprBuilderTaskBase;
nodes::Condition operator()(const ParserNode &parser_node, Node operator()(const ParserNode &parser_node, const Args &args) override;
const Args &args) override;
}; };
template <> template <>
struct BuilderTask<nodes::Loop> : public BuilderTaskBase<nodes::Loop> { struct BuilderTask<nodes::Loop> : public ExprBuilderTaskBase<nodes::Loop> {
using BuilderTaskBase<nodes::Loop>::BuilderTaskBase; using ExprBuilderTaskBase<nodes::Loop>::ExprBuilderTaskBase;
nodes::Loop operator()(const ParserNode &parser_node, Node operator()(const ParserNode &parser_node, const Args &args) override;
const Args &args) override;
}; };
// --- operators // --- operators
template <> template <>
struct BuilderTask<nodes::NameExpression, utils::CommaTag> struct BuilderTask<nodes::NameExpression, utils::CommaTag>
: public BuilderTaskBase<nodes::NameExpression> { : public ExprBuilderTaskBase<nodes::NameExpression> {
using BuilderTaskBase<nodes::NameExpression>::BuilderTaskBase; using ExprBuilderTaskBase<nodes::NameExpression>::ExprBuilderTaskBase;
nodes::NameExpression operator()(const ParserNode &parser_node, Node operator()(const ParserNode &parser_node, const Args &args) override;
const Args &args) override;
}; };
template <> template <>
struct BuilderTask<nodes::NameExpression, utils::OperatorTag> struct BuilderTask<nodes::NameExpression, utils::OperatorTag>
: public BuilderTaskBase<nodes::NameExpression> { : public ExprBuilderTaskBase<nodes::NameExpression> {
using BuilderTaskBase<nodes::NameExpression>::BuilderTaskBase; using ExprBuilderTaskBase<nodes::NameExpression>::ExprBuilderTaskBase;
nodes::NameExpression operator()(const ParserNode &parser_node, Node operator()(const ParserNode &parser_node, const Args &args) override;
const Args &args) override;
}; };
// --- continers // --- continers
@ -91,97 +83,92 @@ template <typename T>
requires std::is_same_v<T, utils::BlockTag> or requires std::is_same_v<T, utils::BlockTag> or
std::is_same_v<T, utils::ArrayTag> std::is_same_v<T, utils::ArrayTag>
struct BuilderTask<nodes::Container, T> struct BuilderTask<nodes::Container, T>
: public BuilderTaskBase<nodes::Container> { : public ExprBuilderTaskBase<nodes::Container> {
using BuilderTaskBase<nodes::Container>::BuilderTaskBase; using ExprBuilderTaskBase<nodes::Container>::ExprBuilderTaskBase;
// '{' (expression ';')* '}' // '{' (expression ';')* '}'
// or // or
// '[[' expression+ ']]' // '[[' expression+ ']]'
nodes::Container operator()(const ParserNode &parser_node, Node operator()(const ParserNode &parser_node, const Args &) override {
const Args &) override { const auto kind = 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;
std::vector<nodes::Expr> expressions; std::vector<nodes::NodeId> exprs;
auto current_node = parser_node.nth_named_child(0); auto current_node = parser_node.nth_named_child(0);
while (!current_node.is_null()) { while (!current_node.is_null()) {
expressions.push_back(Run<nodes::Expr>(current_node)); exprs.push_back(Run<Node>(current_node));
current_node = current_node.next_named_sibling(); current_node = current_node.next_named_sibling();
} }
return nodes::Container(build_node(parser_node), container_type, return state<Exprs>().Insert(nodes::Container{
std::move(expressions)); .kind = kind,
.exprs = std::move(exprs),
});
} }
}; };
// --- modifiers // --- modifiers
template <> template <>
struct BuilderTask<nodes::Return> : public BuilderTaskBase<nodes::Return> { struct BuilderTask<nodes::Return> : public ExprBuilderTaskBase<nodes::Return> {
using BuilderTaskBase<nodes::Return>::BuilderTaskBase; using ExprBuilderTaskBase<nodes::Return>::ExprBuilderTaskBase;
nodes::Return operator()(const ParserNode &parser_node, Node operator()(const ParserNode &parser_node, const Args &args) override;
const Args &args) override;
}; };
template <> template <>
struct BuilderTask<nodes::NameDefinition> struct BuilderTask<nodes::NameDefinition>
: public BuilderTaskBase<nodes::NameDefinition> { : public ExprBuilderTaskBase<nodes::NameDefinition> {
using BuilderTaskBase<nodes::NameDefinition>::BuilderTaskBase; using ExprBuilderTaskBase<nodes::NameDefinition>::ExprBuilderTaskBase;
nodes::NameDefinition operator()(const ParserNode &parser_node, Node operator()(const ParserNode &parser_node, const Args &args) override;
const Args &args) override;
}; };
template <> template <>
struct BuilderTask<nodes::Access, utils::ArrayAccessTag> struct BuilderTask<nodes::Access, utils::ArrayAccessTag>
: public BuilderTaskBase<nodes::Access> { : public ExprBuilderTaskBase<nodes::Access> {
using BuilderTaskBase<nodes::Access>::BuilderTaskBase; using ExprBuilderTaskBase<nodes::Access>::ExprBuilderTaskBase;
nodes::Access operator()(const ParserNode &parser_node, Node operator()(const ParserNode &parser_node, const Args &args) override;
const Args &args) override;
}; };
template <> template <>
struct BuilderTask<nodes::Access, utils::TupleAccessTag> struct BuilderTask<nodes::Access, utils::TupleAccessTag>
: public BuilderTaskBase<nodes::Access> { : public ExprBuilderTaskBase<nodes::Access> {
using BuilderTaskBase<nodes::Access>::BuilderTaskBase; using ExprBuilderTaskBase<nodes::Access>::ExprBuilderTaskBase;
nodes::Access operator()(const ParserNode &parser_node, Node operator()(const ParserNode &parser_node, const Args &args) override;
const Args &args) override;
}; };
template <> template <>
struct BuilderTask<nodes::LoopControl> struct BuilderTask<nodes::LoopControl>
: public BuilderTaskBase<nodes::LoopControl> { : public ExprBuilderTaskBase<nodes::LoopControl> {
using BuilderTaskBase<nodes::LoopControl>::BuilderTaskBase; using ExprBuilderTaskBase<nodes::LoopControl>::ExprBuilderTaskBase;
nodes::LoopControl operator()(const ParserNode &parser_node, Node operator()(const ParserNode &parser_node, const Args &args) override;
const Args &args) override;
}; };
template <typename T> template <typename T>
requires std::is_same_v<T, utils::RefTag> or requires std::is_same_v<T, utils::RefTag> or
std::is_same_v<T, utils::SuffixTag> std::is_same_v<T, utils::SuffixTag>
struct BuilderTask<nodes::ModifierExpression, T> struct BuilderTask<nodes::ModifierExpression, T>
: public BuilderTaskBase<nodes::ModifierExpression> { : public ExprBuilderTaskBase<nodes::ModifierExpression> {
using BuilderTaskBase<nodes::ModifierExpression>::BuilderTaskBase; using ExprBuilderTaskBase<nodes::ModifierExpression>::ExprBuilderTaskBase;
// _reference_ expression // _reference_ expression
// or // or
// expression ('?' | '!') // expression ('?' | '!')
nodes::ModifierExpression operator()(const ParserNode &parser_node, Node operator()(const ParserNode &parser_node, const Args &) 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;
return nodes::ModifierExpression( return state<Exprs>().Insert(nodes::ModifierExpression{
build_node(parser_node), .modifier = Run<nodes::Modifier>(parser_node.nth_child(modifier_pos)),
build_modifier(parser_node.nth_child(modifier_pos)), .expr = Run<Node>(parser_node.nth_named_child(0)),
Run<nodes::Expr>(parser_node.nth_named_child(0))); });
} }
}; };
@ -189,28 +176,25 @@ struct BuilderTask<nodes::ModifierExpression, T>
template <> template <>
struct BuilderTask<nodes::NameExpression, utils::FuncCallTag> struct BuilderTask<nodes::NameExpression, utils::FuncCallTag>
: public BuilderTaskBase<nodes::NameExpression> { : public ExprBuilderTaskBase<nodes::NameExpression> {
using BuilderTaskBase<nodes::NameExpression>::BuilderTaskBase; using ExprBuilderTaskBase<nodes::NameExpression>::ExprBuilderTaskBase;
nodes::NameExpression operator()(const ParserNode &parser_node, Node operator()(const ParserNode &parser_node, const Args &args) override;
const Args &args) override;
}; };
template <> template <>
struct BuilderTask<nodes::Constructor> struct BuilderTask<nodes::Constructor>
: public BuilderTaskBase<nodes::Constructor> { : public ExprBuilderTaskBase<nodes::Constructor> {
using BuilderTaskBase<nodes::Constructor>::BuilderTaskBase; using ExprBuilderTaskBase<nodes::Constructor>::ExprBuilderTaskBase;
nodes::Constructor operator()(const ParserNode &parser_node, Node operator()(const ParserNode &parser_node, const Args &args) override;
const Args &args) override;
}; };
template <> template <>
struct BuilderTask<nodes::Lambda> : public BuilderTaskBase<nodes::Lambda> { struct BuilderTask<nodes::Lambda> : public ExprBuilderTaskBase<nodes::Lambda> {
using BuilderTaskBase<nodes::Lambda>::BuilderTaskBase; using ExprBuilderTaskBase<nodes::Lambda>::ExprBuilderTaskBase;
nodes::Lambda operator()(const ParserNode &parser_node, Node operator()(const ParserNode &parser_node, const Args &args) override;
const Args &args) override;
}; };
} // namespace builders } // namespace builders

View file

@ -16,8 +16,8 @@ namespace builders {
// translate them in required order // translate them in required order
template <> template <>
struct BuilderTask<nodes::Statements> struct BuilderTask<nodes::Statements>
: public BuilderTaskBase<nodes::Statements> { : public StatementBuilderTaskBase<nodes::Statements> {
using BuilderTaskBase<nodes::Statements>::BuilderTaskBase; using StatementBuilderTaskBase<nodes::Statements>::StatementBuilderTaskBase;
nodes::Statements operator()(const ParserNode &parser_node, nodes::Statements operator()(const ParserNode &parser_node,
const Args &args) override; const Args &args) override;
@ -26,16 +26,17 @@ struct BuilderTask<nodes::Statements>
// copy of statement inserted into name_tree // copy of statement inserted into name_tree
template <> template <>
struct BuilderTask<nodes::Statement> struct BuilderTask<nodes::Statement>
: public BuilderTaskBase<nodes::Statement> { : public StatementBuilderTaskBase<nodes::Statement> {
using BuilderTaskBase<nodes::Statement>::BuilderTaskBase; using StatementBuilderTaskBase<nodes::Statement>::StatementBuilderTaskBase;
nodes::Statement operator()(const ParserNode &parser_node, nodes::Statement operator()(const ParserNode &parser_node,
const Args &args) override; const Args &args) override;
}; };
template <> template <>
struct BuilderTask<nodes::Import> : public BuilderTaskBase<nodes::Import> { struct BuilderTask<nodes::Import>
using BuilderTaskBase<nodes::Import>::BuilderTaskBase; : public StatementBuilderTaskBase<nodes::Import> {
using StatementBuilderTaskBase<nodes::Import>::StatementBuilderTaskBase;
nodes::Import operator()(const ParserNode &parser_node, nodes::Import operator()(const ParserNode &parser_node,
const Args &args) override; const Args &args) override;
@ -43,8 +44,8 @@ struct BuilderTask<nodes::Import> : public BuilderTaskBase<nodes::Import> {
template <> template <>
struct BuilderTask<nodes::Constraint> struct BuilderTask<nodes::Constraint>
: public BuilderTaskBase<nodes::Constraint> { : public StatementBuilderTaskBase<nodes::Constraint> {
using BuilderTaskBase<nodes::Constraint>::BuilderTaskBase; using StatementBuilderTaskBase<nodes::Constraint>::StatementBuilderTaskBase;
nodes::Constraint operator()(const ParserNode &parser_node, nodes::Constraint operator()(const ParserNode &parser_node,
const Args &args) override; const Args &args) override;
@ -52,8 +53,9 @@ struct BuilderTask<nodes::Constraint>
template <> template <>
struct BuilderTask<nodes::TypeDefinition> struct BuilderTask<nodes::TypeDefinition>
: public BuilderTaskBase<nodes::TypeDefinition> { : public StatementBuilderTaskBase<nodes::TypeDefinition> {
using BuilderTaskBase<nodes::TypeDefinition>::BuilderTaskBase; using StatementBuilderTaskBase<
nodes::TypeDefinition>::StatementBuilderTaskBase;
nodes::TypeDefinition operator()(const ParserNode &parser_node, nodes::TypeDefinition operator()(const ParserNode &parser_node,
const Args &args) override; const Args &args) override;
@ -61,8 +63,9 @@ struct BuilderTask<nodes::TypeDefinition>
template <> template <>
struct BuilderTask<nodes::FunctionDefinition> struct BuilderTask<nodes::FunctionDefinition>
: public BuilderTaskBase<nodes::FunctionDefinition> { : public StatementBuilderTaskBase<nodes::FunctionDefinition> {
using BuilderTaskBase<nodes::FunctionDefinition>::BuilderTaskBase; using StatementBuilderTaskBase<
nodes::FunctionDefinition>::StatementBuilderTaskBase;
nodes::FunctionDefinition operator()(const ParserNode &parser_node, nodes::FunctionDefinition operator()(const ParserNode &parser_node,
const Args &args) override; const Args &args) override;

View file

@ -1,7 +1,6 @@
#include "basic_builders.hpp" #include "basic_builders.hpp"
#include "basic_nodes.hpp" #include "basic_nodes.hpp"
#include "error_handling.hpp"
#include "tokens.hpp" #include "tokens.hpp"
#include "tree_sitter_wrapper.hpp" #include "tree_sitter_wrapper.hpp"
@ -39,7 +38,11 @@ std::optional<char> to_escape_symbol(char ch) {
} // namespace utils } // namespace utils
nodes::Modifier build_modifier(parser::ParseTree::Node parser_node) { nodes::Modifier
BuilderTask<nodes::Modifier>::operator()(const ParserNode &parser_node,
const Args &) {
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
std::string modifier = parser_node.get_value(); std::string modifier = parser_node.get_value();
if (modifier == "?") { if (modifier == "?") {
@ -81,45 +84,60 @@ nodes::Modifier build_modifier(parser::ParseTree::Node parser_node) {
} }
} }
nodes::Node build_node(parser::ParseTree::Node parser_node) {
return nodes::Node(parser_node.get_start_point(),
parser_node.get_end_point());
}
// --- literals // --- literals
nodes::Literal build_float_literal(parser::ParseTree::Node parser_node) { nodes::Literal
BuilderTask<nodes::Literal, float>::operator()(const ParserNode &parser_node,
const Args &) {
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
std::string literal = parser_node.get_value(); std::string literal = parser_node.get_value();
return nodes::Literal( return nodes::Literal{
build_node(parser_node), .value =
std::stof(literal.substr(0, literal.size() - 1))); // remove 'f' suffix std::stof(literal.substr(0, literal.size() - 1)) // remove 'f' suffix
};
} }
nodes::Literal build_double_literal(parser::ParseTree::Node parser_node) { nodes::Literal
return nodes::Literal(build_node(parser_node), BuilderTask<nodes::Literal, double>::operator()(const ParserNode &parser_node,
std::stod(parser_node.get_value())); const Args &) {
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
return nodes::Literal{.value = std::stod(parser_node.get_value())};
} }
nodes::Literal build_int_literal(parser::ParseTree::Node parser_node) { nodes::Literal
BuilderTask<nodes::Literal, int32_t>::operator()(const ParserNode &parser_node,
const Args &) {
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
std::string literal = parser_node.get_value(); std::string literal = parser_node.get_value();
return nodes::Literal(build_node(parser_node), return nodes::Literal{.value = (int32_t)std::stoll(literal.substr(
(int32_t)std::stoll(literal.substr( 0, literal.size() - 1))}; // remove 'i' suffix
0, literal.size() - 1))); // remove 'i' suffix
} }
nodes::Literal build_long_literal(parser::ParseTree::Node parser_node) { nodes::Literal
BuilderTask<nodes::Literal, int64_t>::operator()(const ParserNode &parser_node,
const Args &) {
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
std::string literal = parser_node.get_value(); std::string literal = parser_node.get_value();
return nodes::Literal(build_node(parser_node), return nodes::Literal{.value = (int64_t)std::stoll(literal.substr(
(int64_t)std::stoll(literal.substr( 0, literal.size() - 1))}; // remove 'l' suffix
0, literal.size() - 1))); // remove 'l' suffix
} }
nodes::Literal build_index_literal(parser::ParseTree::Node parser_node) { nodes::Literal
return nodes::Literal(build_node(parser_node), BuilderTask<nodes::Literal, size_t>::operator()(const ParserNode &parser_node,
(size_t)std::stoull(parser_node.get_value())); const Args &) { // index
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
return nodes::Literal{.value = (size_t)std::stoull(parser_node.get_value())};
} }
nodes::Literal build_string_literal(parser::ParseTree::Node parser_node) { nodes::Literal BuilderTask<nodes::Literal, std::string>::operator()(
const ParserNode &parser_node, const Args &) {
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
std::string literal = parser_node.get_value(); std::string literal = parser_node.get_value();
// remove " from both sides ("string") // remove " from both sides ("string")
@ -149,20 +167,25 @@ nodes::Literal build_string_literal(parser::ParseTree::Node parser_node) {
} }
literal.resize(j); literal.resize(j);
return nodes::Literal(build_node(parser_node), literal); return nodes::Literal{.value = literal};
} }
// TODO: decode escape characters, etc. // TODO: decode escape characters, etc.
nodes::Literal nodes::Literal BuilderTask<nodes::Literal, nodes::unicode_string>::operator()(
build_unicode_string_literal(parser::ParseTree::Node parser_node) { const ParserNode &parser_node, const Args &) {
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
std::string literal = parser_node.get_value(); std::string literal = parser_node.get_value();
// remove " from both sides + 'u' ("string"u) // remove " from both sides + 'u' ("string"u)
return nodes::Literal(build_node(parser_node), return nodes::Literal{.value = literal.substr(1, literal.size() - 3)};
literal.substr(1, literal.size() - 3));
} }
nodes::Literal build_char_literal(parser::ParseTree::Node parser_node) { nodes::Literal
BuilderTask<nodes::Literal, char>::operator()(const ParserNode &parser_node,
const Args &) {
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
std::string literal = parser_node.get_value(); std::string literal = parser_node.get_value();
// remove '' from both sides (''x'') // remove '' from both sides (''x'')
@ -182,108 +205,156 @@ nodes::Literal build_char_literal(parser::ParseTree::Node parser_node) {
ch = literal.back(); ch = literal.back();
} }
return nodes::Literal(build_node(parser_node), ch); return nodes::Literal{ch};
} }
// TODO: decode escape characters, etc. // TODO: decode escape characters, etc.
nodes::Literal build_unicode_literal(parser::ParseTree::Node parser_node) { nodes::Literal BuilderTask<nodes::Literal, nodes::unicode>::operator()(
const ParserNode &parser_node, const Args &) {
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
std::string literal = parser_node.get_value(); std::string literal = parser_node.get_value();
// remove '' from both sides + 'u' (''x''u) // remove '' from both sides + 'u' (''x''u)
return nodes::Literal(build_node(parser_node), return nodes::Literal{
nodes::unicode{literal.substr(2, literal.size() - 5)}); .value = nodes::unicode{literal.substr(2, literal.size() - 5)}};
} }
nodes::Literal build_bool_literal(parser::ParseTree::Node parser_node) { nodes::Literal
BuilderTask<nodes::Literal, bool>::operator()(const ParserNode &parser_node,
const Args &) {
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
std::string literal = parser_node.get_value(); std::string literal = parser_node.get_value();
return nodes::Literal(build_node(parser_node), return nodes::Literal{literal == "true" ? true : false};
literal == "true" ? true : false);
} }
nodes::Literal build_unit_literal(parser::ParseTree::Node parser_node) { nodes::Literal
return nodes::Literal(build_node(parser_node), nodes::unit{}); BuilderTask<nodes::Literal, nodes::unit>::operator()(const ParserNode &,
const Args &) {
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
return nodes::Literal{.value = nodes::unit{}};
} }
nodes::Literal build_null_literal(parser::ParseTree::Node parser_node) { nodes::Literal
return nodes::Literal(build_node(parser_node), nodes::null{}); BuilderTask<nodes::Literal, nodes::null>::operator()(const ParserNode &,
const Args &) {
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
return nodes::Literal{.value = nodes::null{}};
} }
// --- identifiers // --- identifiers
nodes::Identifier build_identifier(parser::ParseTree::Node parser_node) { nodes::Identifier
BuilderTask<nodes::Identifier>::operator()(const ParserNode &parser_node,
const Args &) {
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
tokens::Type type = tokens::string_to_type(parser_node.get_type()); tokens::Type type = tokens::string_to_type(parser_node.get_type());
switch (type) { switch (type) {
case tokens::Type::PLACEHOLDER: case tokens::Type::PLACEHOLDER:
return build_placeholder(parser_node); return Run<nodes::Identifier, ::utils::PlaceholderIdTag>(parser_node);
case tokens::Type::SIMPLE_NAME_IDENTIFIER: case tokens::Type::SIMPLE_NAME_IDENTIFIER:
return build_simple_name(parser_node); return Run<nodes::Identifier, ::utils::SimpleNameIdTag>(parser_node);
case tokens::Type::SIMPLE_TYPE_IDENTIFIER: case tokens::Type::SIMPLE_TYPE_IDENTIFIER:
return build_simple_type(parser_node); return Run<nodes::Identifier, ::utils::SimpleTypeIdTag>(parser_node);
case tokens::Type::TYPECLASS_IDENTIFIER: case tokens::Type::TYPECLASS_IDENTIFIER:
return build_typeclass(parser_node); return Run<nodes::Identifier, ::utils::TypeclassIdTag>(parser_node);
case tokens::Type::ARGUMENT_NAME_IDENTIFIER: case tokens::Type::ARGUMENT_NAME_IDENTIFIER:
return build_argument_name(parser_node); return Run<nodes::Identifier, ::utils::ArgNameIdTag>(parser_node);
case tokens::Type::ARGUMENT_TYPE_IDENTIFIER: case tokens::Type::ARGUMENT_TYPE_IDENTIFIER:
return build_argument_type(parser_node); return Run<nodes::Identifier, ::utils::ArgTypeIdTag>(parser_node);
case tokens::Type::OPERATOR: case tokens::Type::OPERATOR:
case tokens::Type::OPERATOR_TAIL1: case tokens::Type::OPERATOR_TAIL1:
case tokens::Type::OPERATOR_TAIL2: case tokens::Type::OPERATOR_TAIL2:
case tokens::Type::OPERATOR_TAIL3: case tokens::Type::OPERATOR_TAIL3:
return build_operator(parser_node); return Run<nodes::Identifier, ::utils::OperatorIdTag>(parser_node);
// [used as string] // [used as string]
// case tokens::Type::ANNOTATION_IDENTIFIER: // case tokens::Type::ANNOTATION_IDENTIFIER:
// return build_annotation(parser_node); // return build_annotation(parser_node);
default: default:
error_handling::handle_parsing_error("Unexprected identifier node type", logc.Fatal<Log::kProc>({{"Unexprected identifier node type"}},
parser_node); parser_node.get_pos());
} }
error_handling::handle_general_error("Unreachable"); ::utils::Assert(false, "Unreachable");
exit(1); // unreachable exit(1); // unreachable
} }
nodes::Identifier build_simple_name(parser::ParseTree::Node parser_node) { nodes::Identifier
return nodes::Identifier(build_node(parser_node), BuilderTask<nodes::Identifier, ::utils::SimpleNameIdTag>::operator()(
nodes::Identifier::SIMPLE_NAME, const ParserNode &parser_node, const Args &) {
parser_node.get_value()); Log::Context logc(executor.log(), Log::Area::kTypeCheck);
return nodes::Identifier{
.kind = nodes::Identifier::kSimpleName,
.value = parser_node.get_value(),
};
} }
nodes::Identifier build_simple_type(parser::ParseTree::Node parser_node) { nodes::Identifier
return nodes::Identifier(build_node(parser_node), BuilderTask<nodes::Identifier, ::utils::SimpleTypeIdTag>::operator()(
nodes::Identifier::SIMPLE_TYPE, const ParserNode &parser_node, const Args &) {
parser_node.get_value()); Log::Context logc(executor.log(), Log::Area::kTypeCheck);
return nodes::Identifier{.kind = nodes::Identifier::kSimpleType,
.value = parser_node.get_value()};
} }
nodes::Identifier build_typeclass(parser::ParseTree::Node parser_node) { nodes::Identifier
return nodes::Identifier(build_node(parser_node), BuilderTask<nodes::Identifier, ::utils::TypeclassIdTag>::operator()(
nodes::Identifier::TYPECLASS, const ParserNode &parser_node, const Args &) {
parser_node.get_value()); Log::Context logc(executor.log(), Log::Area::kTypeCheck);
return nodes::Identifier{
.kind = nodes::Identifier::kTypeclass,
.value = parser_node.get_value(),
};
} }
nodes::Identifier build_argument_name(parser::ParseTree::Node parser_node) { nodes::Identifier
return nodes::Identifier(build_node(parser_node), BuilderTask<nodes::Identifier, ::utils::ArgNameIdTag>::operator()(
nodes::Identifier::ARGUMENT_NAME, const ParserNode &parser_node, const Args &) {
parser_node.get_value()); Log::Context logc(executor.log(), Log::Area::kTypeCheck);
return nodes::Identifier{
.kind = nodes::Identifier::kArgName,
.value = parser_node.get_value(),
};
} }
nodes::Identifier build_argument_type(parser::ParseTree::Node parser_node) { nodes::Identifier
return nodes::Identifier(build_node(parser_node), BuilderTask<nodes::Identifier, ::utils::ArgTypeIdTag>::operator()(
nodes::Identifier::ARGUMENT_TYPE, const ParserNode &parser_node, const Args &) {
parser_node.get_value()); Log::Context logc(executor.log(), Log::Area::kTypeCheck);
return nodes::Identifier{.kind = nodes::Identifier::kArgType,
.value = parser_node.get_value()};
} }
// Annotations are used as strings // Annotations are used as strings
std::string build_annotation(parser::ParseTree::Node parser_node) { // TODO
nodes::Annotation
BuilderTask<nodes::Annotation>::operator()(const ParserNode &parser_node,
const Args &) {
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
std::string identifier = parser_node.get_value(); std::string identifier = parser_node.get_value();
// identifier.size() > 0 by parsing convention // identifier.size() > 0 by parsing convention
identifier = identifier.substr(1, identifier.size() - 1); identifier = identifier.substr(1, identifier.size() - 1);
return identifier; return nodes::Annotation{.value = identifier};
} }
nodes::Identifier build_operator(parser::ParseTree::Node parser_node) { nodes::Identifier
BuilderTask<nodes::Identifier, ::utils::OperatorIdTag>::operator()(
const ParserNode &parser_node, const Args &) {
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
std::string identifier = parser_node.get_value(); std::string identifier = parser_node.get_value();
// --- points needed for proper printing // --- points needed for proper printing
@ -295,24 +366,38 @@ nodes::Identifier build_operator(parser::ParseTree::Node parser_node) {
// } // }
// --- // ---
return nodes::Identifier(build_node(parser_node), nodes::Identifier::OPERATOR, return nodes::Identifier{.kind = nodes::Identifier::kOperator,
identifier); .value = identifier};
} }
nodes::Identifier build_placeholder(parser::ParseTree::Node parser_node) { nodes::Identifier
return nodes::Identifier(build_node(parser_node), BuilderTask<nodes::Identifier, ::utils::PlaceholderIdTag>::operator()(
nodes::Identifier::PLACEHOLDER, "_"); const ParserNode &, const Args &) {
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
return nodes::Identifier{
.kind = nodes::Identifier::kPlaceholder,
.value = "_",
};
} }
// --- extra // --- extra
nodes::Extra build_extra(parser::ParseTree::Node parser_node) { nodes::Extra
return nodes::Extra(build_node(parser_node), parser_node.get_value()); BuilderTask<nodes::Extra>::operator()(const ParserNode &parser_node,
const Args &) {
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
return nodes::Extra{.content = parser_node.get_value()};
} }
// --- empty lines // --- empty lines
nodes::EmptyLines build_empty_lines(parser::ParseTree::Node parser_node) { nodes::EmptyLines
BuilderTask<nodes::EmptyLines>::operator()(const ParserNode &parser_node,
const Args &) {
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
std::string empty_lines = parser_node.get_value(); std::string empty_lines = parser_node.get_value();
size_t empty_lines_count = 0; size_t empty_lines_count = 0;
@ -324,11 +409,11 @@ nodes::EmptyLines build_empty_lines(parser::ParseTree::Node parser_node) {
} }
if (empty_lines_count == 0) { if (empty_lines_count == 0) {
error_handling::handle_parsing_error("Empty lines node with zero new lines", logc.Fatal<Log::kProc>({{"Empty lines node with zero new lines"}},
parser_node); parser_node.get_pos());
} }
return nodes::EmptyLines(build_node(parser_node), empty_lines_count - 1); return nodes::EmptyLines{.count = empty_lines_count - 1};
} }
} // namespace builders } // namespace builders

View file

@ -2,154 +2,129 @@
#include "basic_builders.hpp" #include "basic_builders.hpp"
#include "basic_nodes.hpp" #include "basic_nodes.hpp"
#include "error_handling.hpp"
#include "expression_nodes.hpp" #include "expression_nodes.hpp"
#include "log.hpp"
#include "tokens.hpp" #include "tokens.hpp"
#include "type_builders.hpp" #include "type_builders.hpp"
#include "type_nodes.hpp" #include "type_nodes.hpp"
// TODO: insert is_scoped everywere
namespace builders { namespace builders {
nodes::Expr BuilderTask<nodes::Expr>::operator()(const ParserNode &parser_node, Node BuilderTask<Node>::operator()(const ParserNode &parser_node,
const Args &) { const Args &) {
Log::Context logc(executor.log(), Log::Area::kParse);
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();
// FIXME TODO
bool is_scoped = bool is_scoped =
(!maybe_parenthesis.is_null() && !maybe_parenthesis.is_named() && (!maybe_parenthesis.is_null() && !maybe_parenthesis.is_named() &&
maybe_parenthesis.get_value() == "("); maybe_parenthesis.get_value() == "(");
std::optional<nodes::ExprData::Type> expr;
switch (type) { switch (type) {
// --- flow control // --- flow control
case tokens::Type::MATCH: case tokens::Type::MATCH:
expr = Run<nodes::Match>(parser_node); return Run<nodes::Match>(parser_node, {is_scoped});
break;
case tokens::Type::CONDITION: case tokens::Type::CONDITION:
return state<Exprs>().add_expr({build_node(parser_node), return Run<nodes::Condition>(parser_node, {is_scoped});
Run<nodes::Condition>(parser_node),
is_scoped});
expr = Run<nodes::Match>(parser_node);
break;
case tokens::Type::LOOP: case tokens::Type::LOOP:
return state<Exprs>().add_expr( return Run<nodes::Loop>(parser_node, {is_scoped});
{build_node(parser_node), Run<nodes::Loop>(parser_node), is_scoped});
expr = Run<nodes::Match>(parser_node);
break;
// --- operators // --- operators
case tokens::Type::COMMA_EXPRESSION: case tokens::Type::COMMA_EXPRESSION:
expr = Run<nodes::NameExpression, utils::CommaTag>(parser_node); return Run<nodes::NameExpression, utils::CommaTag>(parser_node,
break; {is_scoped});
case tokens::Type::OPERATOR_EXPRESSION: case tokens::Type::OPERATOR_EXPRESSION:
expr = Run<nodes::NameExpression, utils::OperatorTag>(parser_node); return Run<nodes::NameExpression, utils::OperatorTag>(parser_node,
break; {is_scoped});
// --- containers // --- containers
case tokens::Type::BLOCK: case tokens::Type::BLOCK:
expr = Run<nodes::Container, utils::BlockTag>(parser_node); return Run<nodes::Container, utils::BlockTag>(parser_node, {is_scoped});
break;
case tokens::Type::ARRAY: case tokens::Type::ARRAY:
expr = Run<nodes::Container, utils::ArrayTag>(parser_node); return Run<nodes::Container, utils::ArrayTag>(parser_node, {is_scoped});
break;
// --- modifiers // --- modifiers
case tokens::Type::RETURN: case tokens::Type::RETURN:
expr = Run<nodes::Return>(parser_node); return Run<nodes::Return>(parser_node, {is_scoped});
break;
case tokens::Type::NAME_DEFINITION: case tokens::Type::NAME_DEFINITION:
expr = Run<nodes::NameDefinition>(parser_node); return Run<nodes::NameDefinition>(parser_node, {is_scoped});
break;
case tokens::Type::ARRAY_ACCESS: case tokens::Type::ARRAY_ACCESS:
expr = Run<nodes::Access, utils::ArrayAccessTag>(parser_node); return Run<nodes::Access, utils::ArrayAccessTag>(parser_node, {is_scoped});
break;
case tokens::Type::TUPLE_ACCESS: case tokens::Type::TUPLE_ACCESS:
expr = Run<nodes::Access, utils::TupleAccessTag>(parser_node); return Run<nodes::Access, utils::TupleAccessTag>(parser_node, {is_scoped});
break;
case tokens::Type::LOOP_CONTROL: case tokens::Type::LOOP_CONTROL:
expr = Run<nodes::LoopControl>(parser_node); return Run<nodes::LoopControl>(parser_node, {is_scoped});
break;
case tokens::Type::REFERENCE_EXPRESSION: case tokens::Type::REFERENCE_EXPRESSION:
expr = Run<nodes::ModifierExpression, utils::RefTag>(parser_node); return Run<nodes::ModifierExpression, utils::RefTag>(parser_node,
break; {is_scoped});
case tokens::Type::SUFFIX_EXPRESSION: case tokens::Type::SUFFIX_EXPRESSION:
expr = Run<nodes::ModifierExpression, utils::SuffixTag>(parser_node); return Run<nodes::ModifierExpression, utils::SuffixTag>(parser_node,
break; {is_scoped});
// --- other // --- other
case tokens::Type::NAME_EXPRESSION: case tokens::Type::NAME_EXPRESSION:
expr = Run<nodes::NameExpression, utils::FuncCallTag>(parser_node); return Run<nodes::NameExpression, utils::FuncCallTag>(parser_node,
break; {is_scoped});
case tokens::Type::ARGUMENT_NAME_IDENTIFIER: case tokens::Type::ARGUMENT_NAME_IDENTIFIER:
case tokens::Type::SIMPLE_NAME_IDENTIFIER: case tokens::Type::SIMPLE_NAME_IDENTIFIER:
case tokens::Type::PLACEHOLDER: case tokens::Type::PLACEHOLDER:
expr = nodes::NameExpression(build_node(parser_node), return Build(
build_identifier(parser_node)); nodes::NameExpression{
break; .name = RunOther<nodes::Identifier>(parser_node),
},
parser_node.get_pos()); // TODO: is_scoped
case tokens::Type::CONSTRUCTOR: case tokens::Type::CONSTRUCTOR:
expr = Run<nodes::Constructor>(parser_node); return Run<nodes::Constructor>(parser_node);
break;
case tokens::Type::LAMBDA: case tokens::Type::LAMBDA:
expr = Run<nodes::Lambda>(parser_node); return Run<nodes::Lambda>(parser_node);
break;
// --- literals // --- literals
case tokens::Type::FLOAT_LITERAL: // TODO: FIXME:
expr = build_float_literal(parser_node); // case tokens::Type::FLOAT_LITERAL:
break; // return BUILD : build_float_literal(parser_node);
case tokens::Type::DOUBLE_LITERAL: // case tokens::Type::DOUBLE_LITERAL:
expr = build_double_literal(parser_node); // return BUILD : build_double_literal(parser_node);
break; // case tokens::Type::INT_LITERAL:
case tokens::Type::INT_LITERAL: // return BUILD : build_int_literal(parser_node);
expr = build_int_literal(parser_node); // case tokens::Type::LONG_LITERAL:
break; // return BUILD : build_long_literal(parser_node);
case tokens::Type::LONG_LITERAL: // case tokens::Type::INDEX_LITERAL:
expr = build_long_literal(parser_node); // return BUILD : build_index_literal(parser_node);
break; // case tokens::Type::STRING_LITERAL:
case tokens::Type::INDEX_LITERAL: // return BUILD : build_string_literal(parser_node);
expr = build_index_literal(parser_node); // case tokens::Type::UNICODE_STRING_LITERAL:
break; // return BUILD : build_unicode_string_literal(parser_node);
case tokens::Type::STRING_LITERAL: // case tokens::Type::CHAR_LITERAL:
expr = build_string_literal(parser_node); // return BUILD : build_char_literal(parser_node);
break; // case tokens::Type::UNICODE_LITERAL:
case tokens::Type::UNICODE_STRING_LITERAL: // return BUILD : build_unicode_literal(parser_node);
expr = build_unicode_string_literal(parser_node); // case tokens::Type::BOOL_LITERAL:
break; // return BUILD : build_bool_literal(parser_node);
case tokens::Type::CHAR_LITERAL: // case tokens::Type::UNIT_LITERAL:
expr = build_char_literal(parser_node); // return BUILD : build_unit_literal(parser_node);
break; // case tokens::Type::NULL_LITERAL:
case tokens::Type::UNICODE_LITERAL: // return BUILD : build_null_literal(parser_node);
expr = build_unicode_literal(parser_node); // case tokens::Type::EXTRA:
break; // return BUILD : build_extra(parser_node);
case tokens::Type::BOOL_LITERAL: // case tokens::Type::EMPTY_LINES:
expr = build_bool_literal(parser_node); // return BUILD : build_empty_lines(parser_node);
break;
case tokens::Type::UNIT_LITERAL:
expr = build_unit_literal(parser_node);
break;
case tokens::Type::NULL_LITERAL:
expr = build_null_literal(parser_node);
break;
case tokens::Type::EXTRA:
expr = build_extra(parser_node);
break;
case tokens::Type::EMPTY_LINES:
expr = build_empty_lines(parser_node);
break;
default: default:
utils::Assert(true, break;
std::format("Unexpected expression node type {}",
static_cast<int>(type))); // TODO: magic_enum
// FIXME: change to fatal error ?
} }
utils::Assert(expr.has_value(), "Expression should have value"); utils::Assert(true, std::format("Unexpected expression node type {}",
static_cast<int>(type))); // TODO: magic_enum
return state<Exprs>().add_expr( // FIXME: change to fatal error ?
{build_node(parser_node), expr.value(), is_scoped}); throw std::exception();
} }
// --- flow control // --- flow control
// (':=' | '=:') expression (('??' | 'if') expression)? (_do_ expression)? // (':=' | '=:') expression (('??' | 'if') expression)? (_do_ expression)?
nodes::Match::Case Node BuilderTask<nodes::Match::Case>::operator()(const ParserNode &parser_node,
BuilderTask<nodes::Match::Case>::operator()(const ParserNode &parser_node, const Args &) {
const Args &) { Log::Context logc(executor.log(), Log::Area::kParse);
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;
@ -169,49 +144,59 @@ BuilderTask<nodes::Match::Case>::operator()(const ParserNode &parser_node,
} }
} }
return nodes::Match::Case( return Build(
build_node(parser_node), nodes::Match::Case{
case_type == ":=" ? nodes::Match::Case::PATTERN_VALUE .kind = case_type == ":=" ? nodes::Match::Case::PATTERN_VALUE
: nodes::Match::Case::VALUE_PATTERN, : nodes::Match::Case::VALUE_PATTERN,
Run<nodes::Expr>(parser_node.nth_named_child(0)), .value = Run<Node>(parser_node.nth_named_child(0)),
condition_node.has_value() ? Run<nodes::Expr>(condition_node.value()) .condition = condition_node.has_value()
: std::optional<nodes::Expr>(), ? Run<Node>(condition_node.value())
expression_node.has_value() ? Run<nodes::Expr>(expression_node.value()) : std::optional<storage::Id>(),
: std::optional<nodes::Expr>()); .expr = expression_node.has_value()
? Run<Node>(expression_node.value())
: std::optional<storage::Id>(),
},
parser_node.get_pos());
} }
// expression case+ // expression case+
nodes::Match Node BuilderTask<nodes::Match>::operator()(const ParserNode &parser_node,
BuilderTask<nodes::Match>::operator()(const ParserNode &parser_node, const Args &) {
const Args &) { Log::Context logc(executor.log(), Log::Area::kParse);
std::vector<nodes::Match::Case> cases;
std::vector<storage::Id /*nodes::Match::Case*/> cases; // TODO
auto current_node = parser_node.nth_named_child(1); auto current_node = parser_node.nth_named_child(1);
while (!current_node.is_null()) { while (!current_node.is_null()) {
cases.push_back(Run<nodes::Match::Case>(current_node)); cases.push_back(
Run<nodes::Match::Case>(current_node, {.is_scoped = false}));
current_node = current_node.next_named_sibling(); current_node = current_node.next_named_sibling();
} }
return nodes::Match(build_node(parser_node), return Build(
Run<nodes::Expr>(parser_node.nth_named_child(0)), nodes::Match{
std::move(cases)); .value = Run<Node>(parser_node.nth_named_child(0)),
.cases = std::move(cases),
},
parser_node.get_pos());
} }
// ('??' | 'if') expression _do_ expression (('!!' | 'elif') expression _do_ // ('??' | 'if') expression _do_ expression (('!!' | 'elif') expression _do_
// expression)* (('!!=>', 'else') expression)? // expression)* (('!!=>', 'else') expression)?
nodes::Condition Node BuilderTask<nodes::Condition>::operator()(const ParserNode &parser_node,
BuilderTask<nodes::Condition>::operator()(const ParserNode &parser_node, const Args &) {
const Args &) { Log::Context logc(executor.log(), Log::Area::kParse);
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<storage::Id, storage::Id>> cases;
auto current_node = parser_node.nth_named_child(0); auto current_node = parser_node.nth_named_child(0);
auto next_node = current_node.next_named_sibling(); auto next_node = current_node.next_named_sibling();
while (!current_node.is_null() && !next_node.is_null()) { while (!current_node.is_null() && !next_node.is_null()) {
cases.push_back( cases.push_back(
{Run<nodes::Expr>(current_node), Run<nodes::Expr>(next_node)}); {Run<storage::Id>(current_node), Run<storage::Id>(next_node)});
current_node = next_node.next_named_sibling(); current_node = next_node.next_named_sibling();
if (current_node.is_null()) { if (current_node.is_null()) {
break; break;
@ -219,97 +204,102 @@ BuilderTask<nodes::Condition>::operator()(const ParserNode &parser_node,
next_node = current_node.next_named_sibling(); next_node = current_node.next_named_sibling();
} }
return nodes::Condition( return Build(
build_node(parser_node), std::move(cases), nodes::Condition{
named_child_count % 2 == 1 .cases = std::move(cases),
? Run<nodes::Expr>(parser_node.nth_named_child(named_child_count - 1)) .else_case = named_child_count % 2 == 1
: std::optional<nodes::Expr>()); ? Run<Node>(parser_node.nth_named_child(
named_child_count - 1))
: std::optional<Node>(),
},
parser_node.get_pos());
} }
// ('@' | 'for') (expression | expression ':' expression)? _do_ expression // ('@' | 'for') (expression | expression ':' expression)? _do_ expression
nodes::Loop BuilderTask<nodes::Loop>::operator()(const ParserNode &parser_node, Node BuilderTask<nodes::Loop>::operator()(const ParserNode &parser_node,
const Args &) { const Args &) {
Log::Context logc(executor.log(), Log::Area::kParse);
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
return nodes::Loop(build_node(parser_node), return Build(nodes::Loop(Run<Node>(parser_node.nth_named_child(0))),
Run<nodes::Expr>(parser_node.nth_named_child(0))); parser_node.get_pos());
} else if (named_child_count == 2) { // condition, } else if (named_child_count == 2) { // condition,
// body // body
return nodes::Loop(build_node(parser_node), return Build(nodes::Loop(Run<Node>(parser_node.nth_named_child(0)),
Run<nodes::Expr>(parser_node.nth_named_child(0)), Run<Node>(parser_node.nth_named_child(1))),
Run<nodes::Expr>(parser_node.nth_named_child(1))); parser_node.get_pos());
} else if (named_child_count == 3) { // variable, } else if (named_child_count == 3) { // variable,
// interval, // interval,
// body // body
return nodes::Loop(build_node(parser_node), return Build(nodes::Loop(Run<Node>(parser_node.nth_named_child(0)),
Run<nodes::Expr>(parser_node.nth_named_child(0)), Run<Node>(parser_node.nth_named_child(1)),
Run<nodes::Expr>(parser_node.nth_named_child(1)), Run<Node>(parser_node.nth_named_child(2))),
Run<nodes::Expr>(parser_node.nth_named_child(2))); parser_node.get_pos());
} else { } else {
error_handling::handle_parsing_error("Unex" logc.Fatal<Log::kProc>({{"Unexpected named expression amount in loop"}},
"prec" parser_node.get_pos());
"ted "
"name"
"d "
"expr"
"essi"
"on "
"amou"
"nt "
"in "
"loo"
"p",
parser_node);
} }
error_handling::handle_general_error("Unreac" error_handling::handle_general_error("Unreachable");
"habl"
"e");
exit(1); // unreachable exit(1); // unreachable
} }
// --- operators // --- operators
// expression ',' expression // expression ',' expression
nodes::NameExpression Node BuilderTask<nodes::NameExpression, utils::CommaTag>::operator()(
BuilderTask<nodes::NameExpression, utils::CommaTag>::operator()(
const ParserNode &parser_node, const Args &) { const ParserNode &parser_node, const Args &) {
std::vector<std::pair<std::optional<std::string>, nodes::Expr>> args; Log::Context logc(executor.log(), Log::Area::kParse);
std::vector<std::pair<std::optional<std::string>, storage::Id>> args;
args.emplace_back(std::nullopt, args.emplace_back(std::nullopt,
Run<nodes::Expr>(parser_node.nth_named_child(0))); Run<storage::Id>(parser_node.nth_named_child(0)));
args.emplace_back(std::nullopt, args.emplace_back(std::nullopt,
Run<nodes::Expr>(parser_node.nth_named_child(1))); Run<storage::Id>(parser_node.nth_named_child(1)));
return nodes::NameExpression( return Build(
build_node(parser_node), nodes::NameExpression{
nodes::Identifier( .name =
build_node(parser_node), // can't find more precise location nodes::Identifier{
nodes::Identifier::SIMPLE_NAME, ","), // can't find more precise location
std::move(args), std::nullopt, false, true); .kind = nodes::Identifier::kSimpleName,
.value = ",",
},
.args = std::move(args),
.prefix = {},
.is_point_call = false,
.is_operator_call = true,
},
parser_node.get_pos());
} }
// expression operator expression // expression operator expression
nodes::NameExpression Node BuilderTask<nodes::NameExpression, utils::OperatorTag>::operator()(
BuilderTask<nodes::NameExpression, utils::OperatorTag>::operator()(
const ParserNode &parser_node, const Args &) { const ParserNode &parser_node, const Args &) {
auto name_node = parser_node.child_by_field_name("na" Log::Context logc(executor.log(), Log::Area::kParse);
"m"
"e");
std::vector<std::pair<std::optional<std::string>, nodes::Expr>> args; auto name_node = parser_node.child_by_field_name("name");
std::vector<std::pair<std::optional<std::string>, storage::Id>> args;
args.emplace_back(std::nullopt, args.emplace_back(std::nullopt,
Run<nodes::Expr>(name_node.previous_named_sibling())); Run<Node>(name_node.previous_named_sibling()));
args.emplace_back(std::nullopt, args.emplace_back(std::nullopt, Run<Node>(name_node.next_named_sibling()));
Run<nodes::Expr>(name_node.next_named_sibling()));
return nodes::NameExpression(build_node(parser_node), return Build(
build_operator(name_node), std::move(args), nodes::NameExpression{
std::nullopt, false, true); .name = RunOther<nodes::Identifier, utils::OperatorIdTag>(name_node),
.args = std::move(args),
.prefix = {},
.is_point_call = false,
.is_operator_call = true,
},
parser_node.get_pos());
} }
// --- continers // --- continers
@ -319,64 +309,84 @@ BuilderTask<nodes::NameExpression, utils::OperatorTag>::operator()(
// --- modifiers // --- modifiers
// ('return' | 'bring') expression // ('return' | 'bring') expression
nodes::Return Node BuilderTask<nodes::Return>::operator()(const ParserNode &parser_node,
BuilderTask<nodes::Return>::operator()(const ParserNode &parser_node, const Args &) {
const Args &) { Log::Context logc(executor.log(), Log::Area::kParse);
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 Build(
modifier == "re" nodes::Return{
"tu" .kind = modifier == "return" ? nodes::Return::RETURN
"rn" : nodes::Return::BRING,
? nodes::Return::RETURN .expr = Run<Node>(parser_node.nth_named_child(0)),
: nodes::Return::BRING, },
Run<nodes::Expr>(parser_node.nth_named_child(0))); parser_node.get_pos());
} }
// _var_let_ (simple_name_identifier | placeholder) // _var_let_ (simple_name_identifier | placeholder)
nodes::NameDefinition Node BuilderTask<nodes::NameDefinition>::operator()(
BuilderTask<nodes::NameDefinition>::operator()(const ParserNode &parser_node, const ParserNode &parser_node, const Args &) {
const Args &) { Log::Context logc(executor.log(), Log::Area::kParse);
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);
return nodes::NameDefinition(build_node(parser_node), return Build(
(modifier == "%" || modifier == "let") nodes::NameDefinition{
? nodes::NameDefinition::LET .kind = (modifier == "%" || modifier == "let")
: nodes::NameDefinition::VAR, ? nodes::NameDefinition::LET
build_identifier(name_node)); : nodes::NameDefinition::VAR,
.name =
Run<nodes::Identifier, utils::None, nodes::Identifier>(name_node),
},
parser_node.get_pos());
} // IN PROGRESS } // IN PROGRESS
// expression '[' expression ']' // expression '[' expression ']'
nodes::Access BuilderTask<nodes::Access, utils::ArrayAccessTag>::operator()( Node BuilderTask<nodes::Access, utils::ArrayAccessTag>::operator()(
const ParserNode &parser_node, const Args &) { const ParserNode &parser_node, const Args &) {
return nodes::Access(build_node(parser_node), nodes::Access::ARRAY, Log::Context logc(executor.log(), Log::Area::kParse);
Run<nodes::Expr>(parser_node.nth_named_child(0)),
Run<nodes::Expr>(parser_node.nth_named_child(1))); return Build(
nodes::Access{.kind = nodes::Access::ARRAY,
.value = Run<Node>(parser_node.nth_named_child(0)),
.index = Run<Node>(parser_node.nth_named_child(1))},
parser_node.get_pos());
} }
// expression '.' number_literal // expression '.' number_literal
nodes::Access BuilderTask<nodes::Access, utils::TupleAccessTag>::operator()( Node BuilderTask<nodes::Access, utils::TupleAccessTag>::operator()(
const ParserNode &parser_node, const Args &) { const ParserNode &parser_node, const Args &) {
return nodes::Access( Log::Context logc(executor.log(), Log::Area::kParse);
build_node(parser_node), nodes::Access::TUPLE,
Run<nodes::Expr>(parser_node.nth_named_child(0)), auto const node = Build(
state<Exprs>().add_expr( nodes::Access{
{build_node(parser_node.nth_named_child(1)), .kind = nodes::Access::TUPLE,
build_index_literal(parser_node.nth_named_child(1)), false})); .value = Run<Node>(parser_node.nth_named_child(0)),
.index = Run<Node>(parser_node.nth_named_child(1)),
// TODO: FIXME:
// .index = Build(build_index_literal(parser_node.nth_named_child(
// 1)) /*, false}*/, // ?? is_scoped ??
},
parser_node.get_pos());
return node;
} }
// 'break' | 'continue' // 'break' | 'continue'
nodes::LoopControl Node BuilderTask<nodes::LoopControl>::operator()(const ParserNode &parser_node,
BuilderTask<nodes::LoopControl>::operator()(const ParserNode &parser_node, const Args &) {
const Args &) { Log::Context logc(executor.log(), Log::Area::kParse);
return nodes::LoopControl(build_node(parser_node),
parser_node.get_value() == "br" return Build(
"ea" nodes::LoopControl{
"k" .kind = parser_node.get_value() == "break"
? nodes::LoopControl::BREAK ? nodes::LoopControl::BREAK
: nodes::LoopControl::CONTINUE); : nodes::LoopControl::CONTINUE,
},
parser_node.get_pos());
} }
// // ModifierExpression -> .hpp // // ModifierExpression -> .hpp
@ -391,10 +401,12 @@ void build_args_until_end(ParserNode first_parse_node, Executor &executor,
while (!current_node.is_null()) { while (!current_node.is_null()) {
if (tokens::string_to_type(current_node.get_type()) == if (tokens::string_to_type(current_node.get_type()) ==
tokens::Type::ANNOTATION_IDENTIFIER) { tokens::Type::ANNOTATION_IDENTIFIER) {
last_annotation = build_annotation(current_node); last_annotation =
BuilderTask<nodes::Annotation>{executor}(current_node, {})
.value; // TODO
} else { } else {
args.emplace_back(std::move(last_annotation), args.emplace_back(std::move(last_annotation),
BuilderTask<nodes::Expr>{executor}(current_node, {})); BuilderTask<Node>{executor}(current_node, {}));
last_annotation = std::nullopt; last_annotation = std::nullopt;
} }
current_node = current_node.next_named_sibling(); current_node = current_node.next_named_sibling();
@ -403,18 +415,17 @@ void build_args_until_end(ParserNode first_parse_node, Executor &executor,
// (type '.' simple_name | expression '.' simple_name | name | '(' operator // (type '.' simple_name | expression '.' simple_name | name | '(' operator
// ')') (annotation? expression)* // ')') (annotation? expression)*
nodes::NameExpression Node BuilderTask<nodes::NameExpression, utils::FuncCallTag>::operator()(
BuilderTask<nodes::NameExpression, utils::FuncCallTag>::operator()(
const ParserNode &parser_node, const Args &) { const ParserNode &parser_node, const Args &) {
Log::Context logc(executor.log(), Log::Area::kParse);
std::vector<nodes::AnnotatedArgument> args; std::vector<nodes::AnnotatedArgument> args;
std::optional<nodes::TypeData> prefix; std::optional<nodes::TypeData> prefix;
bool is_point_call = false; bool is_point_call = false;
auto name_node = parser_node.child_by_field_name("na" auto name_node = parser_node.child_by_field_name("name");
"m"
"e");
std::optional<ParserNode> prefix_node; std::optional<ParserNode> prefix_node;
@ -433,23 +444,30 @@ BuilderTask<nodes::NameExpression, utils::FuncCallTag>::operator()(
prefix_node = current_node; prefix_node = current_node;
} else { } else {
is_point_call = true; is_point_call = true;
args.emplace_back(std::nullopt, Run<nodes::Expr>(current_node)); args.emplace_back(std::nullopt, Run<Node>(current_node));
} }
} }
build_args_until_end(name_node.next_named_sibling(), executor, args); build_args_until_end(name_node.next_named_sibling(), executor, args);
return nodes::NameExpression( return Build(
build_node(parser_node), build_identifier(name_node), std::move(args), nodes::NameExpression{
prefix_node.has_value() ? build_type(prefix_node.value(), state<Types>()) .name = RunOther<nodes::Identifier>(name_node),
: nodes::MaybeType(), .args = std::move(args),
is_point_call, false); .prefix = prefix_node.has_value()
? build_type(prefix_node.value(), state<Types>())
: nodes::MaybeType(),
.is_point_call = is_point_call,
.is_operator_call = false,
},
parser_node.get_pos());
} }
// type (annotation? expression)* // type (annotation? expression)*
nodes::Constructor Node BuilderTask<nodes::Constructor>::operator()(const ParserNode &parser_node,
BuilderTask<nodes::Constructor>::operator()(const ParserNode &parser_node, const Args &) {
const Args &) { Log::Context logc(executor.log(), Log::Area::kParse);
std::vector<nodes::AnnotatedArgument> args; std::vector<nodes::AnnotatedArgument> args;
build_args_until_end(parser_node build_args_until_end(parser_node
@ -459,31 +477,39 @@ BuilderTask<nodes::Constructor>::operator()(const ParserNode &parser_node,
.next_named_sibling(), .next_named_sibling(),
executor, args); executor, args);
return nodes::Constructor( return Build(
build_node(parser_node), nodes::Constructor{
build_type(parser_node.child_by_field_name("type"), state<Types>()), .type = build_type(parser_node.child_by_field_name("type"),
std::move(args)); state<Types>()),
.args = std::move(args),
},
parser_node.get_pos());
} }
// '\\' argument_name* _do_ expression // '\\' argument_name* _do_ expression
nodes::Lambda Node BuilderTask<nodes::Lambda>::operator()(const ParserNode &parser_node,
BuilderTask<nodes::Lambda>::operator()(const ParserNode &parser_node, const Args &) {
const Args &) { Log::Context logc(executor.log(), Log::Area::kParse);
std::vector<nodes::Identifier> args; 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_
args.emplace_back(build_identifier(current_node)); args.emplace_back(RunOther<nodes::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(args), return Build(
Run<nodes::Expr>(current_node)); nodes::Lambda{
.args = std::move(args),
.expr = Run<Node>(current_node),
},
parser_node.get_pos());
} }
} // namespace builders } // namespace builders

View file

@ -4,7 +4,6 @@
#include "basic_nodes.hpp" #include "basic_nodes.hpp"
#include "doc_builders.hpp" #include "doc_builders.hpp"
#include "doc_nodes.hpp" #include "doc_nodes.hpp"
#include "error_handling.hpp"
#include "expression_builders.hpp" #include "expression_builders.hpp"
#include "statement_nodes.hpp" #include "statement_nodes.hpp"
#include "tokens.hpp" #include "tokens.hpp"
@ -22,6 +21,8 @@ namespace builders {
nodes::Statements nodes::Statements
BuilderTask<nodes::Statements>::operator()(const ParserNode &parser_node, BuilderTask<nodes::Statements>::operator()(const ParserNode &parser_node,
const Args &) { const Args &) {
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
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;
@ -39,6 +40,8 @@ BuilderTask<nodes::Statements>::operator()(const ParserNode &parser_node,
nodes::Statement nodes::Statement
BuilderTask<nodes::Statement>::operator()(const ParserNode &parser_node, BuilderTask<nodes::Statement>::operator()(const ParserNode &parser_node,
const Args &) { const Args &) {
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
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;
@ -46,45 +49,33 @@ BuilderTask<nodes::Statement>::operator()(const ParserNode &parser_node,
switch (type) { switch (type) {
case tokens::Type::IMPORT: case tokens::Type::IMPORT:
statement = nodes::Statement(build_node(parser_node), statement = nodes::Statement{Run<nodes::Import>(parser_node)};
Run<nodes::Import>(parser_node)); statement_name =
statement_name = *statement.value() statement.value().get<nodes::Import>().value()->module_name.value;
.get<nodes::Import>()
.value()
->get_module_name()
->get();
break; break;
case tokens::Type::TYPE_DEFINITION: case tokens::Type::TYPE_DEFINITION:
statement = nodes::Statement(build_node(parser_node), statement = nodes::Statement{Run<nodes::TypeDefinition>(parser_node)};
Run<nodes::TypeDefinition>(parser_node));
state<State>().last_defined_type_name = state<State>().last_defined_type_name =
*statement.value().get<nodes::TypeDefinition>().value()->get_name(); statement.value().get<nodes::TypeDefinition>().value()->name;
statement_name = *statement.value() statement_name =
.get<nodes::TypeDefinition>() statement.value().get<nodes::TypeDefinition>().value()->name.value;
.value()
->get_name()
->get();
break; break;
case tokens::Type::FUNCTION_DEFINITION: case tokens::Type::FUNCTION_DEFINITION:
statement = nodes::Statement(build_node(parser_node), statement = nodes::Statement{Run<nodes::FunctionDefinition>(parser_node)};
Run<nodes::FunctionDefinition>(parser_node)); statement_name = statement.value()
statement_name = *statement.value() .get<nodes::FunctionDefinition>()
.get<nodes::FunctionDefinition>() .value()
.value() ->full_name.value;
->get_full_name()
->get();
break; break;
case tokens::Type::EXTRA: case tokens::Type::EXTRA:
statement = statement = nodes::Statement{Run<nodes::Extra>(parser_node)};
nodes::Statement(build_node(parser_node), build_extra(parser_node));
break; break;
case tokens::Type::EMPTY_LINES: case tokens::Type::EMPTY_LINES:
statement = nodes::Statement(build_node(parser_node), statement = nodes::Statement{Run<nodes::EmptyLines>(parser_node)};
build_empty_lines(parser_node));
break; break;
default: default:
error_handling::handle_parsing_error("Unexprected statement node type", logc.Fatal<Log::kProc>({{"Unexprected statement node type"}},
parser_node); parser_node.get_pos());
} }
if (!statement.has_value()) { if (!statement.has_value()) {
@ -97,8 +88,8 @@ BuilderTask<nodes::Statement>::operator()(const ParserNode &parser_node,
.insert_combine(statement_name.value(), std::move(statement_copy)) .insert_combine(statement_name.value(), std::move(statement_copy))
.second != nodes::CombineResult::OK) { .second != nodes::CombineResult::OK) {
// TODO: more detailed errors // TODO: more detailed errors
error_handling::handle_parsing_error( logc.Fatal<Log::kProc>({{"Can't combine statements with same name"}},
"Can't combine statements with same name", parser_node); parser_node.get_pos());
} }
} }
@ -109,6 +100,7 @@ BuilderTask<nodes::Statement>::operator()(const ParserNode &parser_node,
nodes::Import nodes::Import
BuilderTask<nodes::Import>::operator()(const ParserNode &parser_node, BuilderTask<nodes::Import>::operator()(const ParserNode &parser_node,
const Args &) { const Args &) {
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
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");
@ -120,20 +112,21 @@ BuilderTask<nodes::Import>::operator()(const ParserNode &parser_node,
auto current_node = module_node.next_named_sibling(); auto current_node = module_node.next_named_sibling();
while (!current_node.is_null()) { while (!current_node.is_null()) {
symbols.push_back(build_identifier(current_node)); symbols.push_back(Run<nodes::Identifier>(current_node));
current_node = current_node.next_named_sibling(); current_node = current_node.next_named_sibling();
} }
return nodes::Import(build_node(parser_node), build_identifier(name_node), return nodes::Import(Run<nodes::Identifier>(name_node),
build_identifier(module_node), std::move(symbols)); Run<nodes::Identifier>(module_node), std::move(symbols));
} }
// '?' expression // '?' expression
nodes::Constraint nodes::Constraint
BuilderTask<nodes::Constraint>::operator()(const ParserNode &parser_node, BuilderTask<nodes::Constraint>::operator()(const ParserNode &parser_node,
const Args &) { const Args &) {
return nodes::Constraint(build_node(parser_node), Log::Context logc(executor.log(), Log::Area::kTypeCheck);
Run<nodes::Expr>(parser_node.nth_named_child(0)));
return nodes::Constraint{.expr = Run<Node>(parser_node.nth_named_child(0))};
} }
parser::ParseTree::Node collect_symbol_doc_nodes( parser::ParseTree::Node collect_symbol_doc_nodes(
@ -170,6 +163,8 @@ parser::ParseTree::Node collect_symbol_doc_nodes(
nodes::TypeDefinition nodes::TypeDefinition
BuilderTask<nodes::TypeDefinition>::operator()(const ParserNode &parser_node, BuilderTask<nodes::TypeDefinition>::operator()(const ParserNode &parser_node,
const Args &) { const Args &) {
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
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;
@ -179,16 +174,16 @@ BuilderTask<nodes::TypeDefinition>::operator()(const ParserNode &parser_node,
bool is_on_heap = !name_node.previous_sibling().is_null() && bool is_on_heap = !name_node.previous_sibling().is_null() &&
name_node.previous_sibling().get_value() == "<>"; name_node.previous_sibling().get_value() == "<>";
nodes::Identifier name = build_identifier(name_node); nodes::Identifier name = Run<nodes::Identifier>(name_node);
bool is_typeclass = (name.get_type() == nodes::Identifier::TYPECLASS); bool is_typeclass = (name.kind == nodes::Identifier::kTypeclass);
// //
if (is_typeclass && !annotation_nodes.empty()) { if (is_typeclass && !annotation_nodes.empty()) {
error_handling::handle_parsing_error( logc.Fatal<Log::kProc>(
"Typeclass definition can't have annotation documentation", {{"Typeclass definition can't have annotation documentation"}},
parser_node); parser_node.get_pos());
} }
// //
@ -202,10 +197,10 @@ BuilderTask<nodes::TypeDefinition>::operator()(const ParserNode &parser_node,
while (!current_node.is_null()) { while (!current_node.is_null()) {
switch (tokens::string_to_type(current_node.get_type())) { switch (tokens::string_to_type(current_node.get_type())) {
case tokens::Type::TYPECLASS_IDENTIFIER: case tokens::Type::TYPECLASS_IDENTIFIER:
typeclasses.push_back(build_identifier(current_node)); typeclasses.push_back(Run<nodes::Identifier>(current_node));
break; break;
case tokens::Type::ARGUMENT_TYPE_IDENTIFIER: case tokens::Type::ARGUMENT_TYPE_IDENTIFIER:
args.push_back(build_identifier(current_node)); args.push_back(Run<nodes::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:
@ -213,33 +208,34 @@ BuilderTask<nodes::TypeDefinition>::operator()(const ParserNode &parser_node,
case tokens::Type::MODIFIED_TYPE: case tokens::Type::MODIFIED_TYPE:
case tokens::Type::SIMPLE_TYPE: case tokens::Type::SIMPLE_TYPE:
if (type_node.has_value()) { if (type_node.has_value()) {
error_handling::handle_parsing_error( logc.Fatal<Log::kProc>({{"More then one type node in type definition"}},
"More then one type node in type definition", parser_node); parser_node.get_pos());
} }
type_node = current_node; type_node = current_node;
break; break;
default: default:
error_handling::handle_parsing_error( logc.Fatal<Log::kProc>({{"Unexprected node type in type definition"}},
"Unexprected node type in type definition", parser_node); parser_node.get_pos());
} }
current_node = current_node.next_named_sibling(); current_node = current_node.next_named_sibling();
} }
if (!type_node.has_value() && !annotation_nodes.empty()) { if (!type_node.has_value() && !annotation_nodes.empty()) {
error_handling::handle_parsing_error( logc.Fatal<Log::kProc>(
"Type declaration can't contain annotation documentation", parser_node); {{"Type declaration can't contain annotation documentation"}},
parser_node.get_pos());
} }
if (is_typeclass) { if (is_typeclass) {
if (!args.empty()) { if (!args.empty()) {
error_handling::handle_parsing_error("Typeclass can't have arguments", logc.Fatal<Log::kProc>({{"Typeclass can't have arguments"}},
parser_node); parser_node.get_pos());
} }
if (type_node.has_value()) { if (type_node.has_value()) {
error_handling::handle_parsing_error( logc.Fatal<Log::kProc>(
"Typeclass can't be type (contain constructors / fields)", {{"Typeclass can't be type (contain constructors / fields)"}},
type_node.value()); type_node.value().get_pos());
} }
} }
@ -255,11 +251,15 @@ BuilderTask<nodes::TypeDefinition>::operator()(const ParserNode &parser_node,
annotations, annotations.begin())); annotations, annotations.begin()));
} }
return nodes::TypeDefinition( return nodes::TypeDefinition{
build_node(parser_node), .docs =
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(args), .is_on_heap = is_on_heap,
type); .name = std::move(name),
.typeclasses = std::move(typeclasses),
.args = std::move(args),
.type = type,
};
} }
// definition_info? annotation_info* (constraint ';')* '.'? (simple_name // definition_info? annotation_info* (constraint ';')* '.'? (simple_name
@ -268,6 +268,8 @@ BuilderTask<nodes::TypeDefinition>::operator()(const ParserNode &parser_node,
// (((block | array) | '=' expression ';') | ';') // (((block | array) | '=' expression ';') | ';')
nodes::FunctionDefinition BuilderTask<nodes::FunctionDefinition>::operator()( nodes::FunctionDefinition BuilderTask<nodes::FunctionDefinition>::operator()(
const ParserNode &parser_node, const Args &) { const ParserNode &parser_node, const Args &) {
Log::Context logc(executor.log(), Log::Area::kTypeCheck);
// 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;
@ -296,8 +298,8 @@ nodes::FunctionDefinition BuilderTask<nodes::FunctionDefinition>::operator()(
is_method = true; is_method = true;
if (!state<State>().last_defined_type_name.has_value()) { if (!state<State>().last_defined_type_name.has_value()) {
error_handling::handle_parsing_error( logc.Fatal<Log::kProc>({{"Can't define method without associated type"}},
"Can't define method without associated type", parser_node); parser_node.get_pos());
} }
name_prefix = state<State>().last_defined_type_name.value(); name_prefix = state<State>().last_defined_type_name.value();
@ -307,7 +309,7 @@ nodes::FunctionDefinition BuilderTask<nodes::FunctionDefinition>::operator()(
current_node = name_node.next_sibling(); current_node = name_node.next_sibling();
if (!current_node.is_null() && !current_node.is_named()) { if (!current_node.is_null() && !current_node.is_named()) {
return_modifier = build_modifier(current_node); return_modifier = Run<nodes::Modifier>(current_node);
// only optional, result allowed // only optional, result allowed
if (!nodes::utils::is_suffix_modifier(return_modifier)) { if (!nodes::utils::is_suffix_modifier(return_modifier)) {
@ -333,7 +335,7 @@ nodes::FunctionDefinition BuilderTask<nodes::FunctionDefinition>::operator()(
// update last before modifier // update last before modifier
auto maybe_reference_node = current_node.previous_sibling(); auto maybe_reference_node = current_node.previous_sibling();
if (!maybe_reference_node.is_null() && !maybe_reference_node.is_named()) { if (!maybe_reference_node.is_null() && !maybe_reference_node.is_named()) {
last_before_modifier = build_modifier(maybe_reference_node); last_before_modifier = Run<nodes::Modifier>(maybe_reference_node);
// only out, in, ref allowed // only out, in, ref allowed
if (nodes::utils::is_suffix_modifier(last_before_modifier)) { if (nodes::utils::is_suffix_modifier(last_before_modifier)) {
@ -343,13 +345,13 @@ nodes::FunctionDefinition BuilderTask<nodes::FunctionDefinition>::operator()(
switch (tokens::string_to_type(current_node.get_type())) { switch (tokens::string_to_type(current_node.get_type())) {
case tokens::Type::ANNOTATION_IDENTIFIER: case tokens::Type::ANNOTATION_IDENTIFIER:
last_annotation = build_annotation(current_node); last_annotation = Run<nodes::Annotation>(current_node).value; // TODO
break; break;
case tokens::Type::ARGUMENT_NAME_IDENTIFIER: case tokens::Type::ARGUMENT_NAME_IDENTIFIER:
// update last after modifier // update last after modifier
maybe_reference_node = current_node.next_sibling(); maybe_reference_node = current_node.next_sibling();
if (!maybe_reference_node.is_null() && !maybe_reference_node.is_named()) { if (!maybe_reference_node.is_null() && !maybe_reference_node.is_named()) {
last_after_modifier = build_modifier(maybe_reference_node); last_after_modifier = Run<nodes::Modifier>(maybe_reference_node);
// only optional, result allowed // only optional, result allowed
if (!nodes::utils::is_suffix_modifier(last_after_modifier)) { if (!nodes::utils::is_suffix_modifier(last_after_modifier)) {
@ -363,8 +365,8 @@ nodes::FunctionDefinition BuilderTask<nodes::FunctionDefinition>::operator()(
} }
args.push_back(nodes::FunctionDefinition::Argument( args.push_back(nodes::FunctionDefinition::Argument(
last_annotation, build_identifier(current_node), last_before_modifier, last_annotation, Run<nodes::Identifier>(current_node),
last_after_modifier)); last_before_modifier, last_after_modifier));
last_annotation = std::nullopt; last_annotation = std::nullopt;
break; break;
@ -381,12 +383,12 @@ nodes::FunctionDefinition BuilderTask<nodes::FunctionDefinition>::operator()(
if (!args[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( logc.Fatal<Log::kProc>(
"It is impossible to use argument modifiers (annotations, " {{"It is impossible to use argument modifiers (annotations, "
"references, " "references, "
"optional markers, result markers) when types explicitely " "optional markers, result markers) when types explicitely "
"defined. Use type annotations instead.", "defined. Use type annotations instead."}},
current_node); current_node.get_pos());
} }
} }
@ -396,9 +398,9 @@ nodes::FunctionDefinition BuilderTask<nodes::FunctionDefinition>::operator()(
break; break;
default: default:
if (expression_node.has_value()) { if (expression_node.has_value()) {
error_handling::handle_parsing_error( logc.Fatal<Log::kProc>(
"More then one expression found in function definition", {{"More then one expression found in function definition"}},
parser_node); parser_node.get_pos());
} }
expression_node = current_node; expression_node = current_node;
break; break;
@ -407,15 +409,16 @@ nodes::FunctionDefinition BuilderTask<nodes::FunctionDefinition>::operator()(
} }
if (current_type_id > 0 && current_type_id < args.size()) { if (current_type_id > 0 && current_type_id < args.size()) {
error_handling::handle_parsing_error( logc.Fatal<Log::kProc>(
"Less types then arguments in function definition", parser_node); {{"Less types then arguments in function definition"}},
parser_node.get_pos());
} }
if (current_type_id == 0 && !expression_node.has_value()) { if (current_type_id == 0 && !expression_node.has_value()) {
error_handling::handle_parsing_error( logc.Fatal<Log::kProc>(
"Can't declare function without types (types or function body should " {{"Can't declare function without types (types or function body should "
"be added)", "be added)"}},
parser_node); parser_node.get_pos());
} }
// automatic annotations // automatic annotations
@ -424,13 +427,13 @@ nodes::FunctionDefinition BuilderTask<nodes::FunctionDefinition>::operator()(
if (are_annotations_same_to_names) { if (are_annotations_same_to_names) {
for (size_t i = 0; i < args.size(); ++i) { for (size_t i = 0; i < args.size(); ++i) {
std::string new_annotation = *args[i].get_name().value()->get(); std::string new_annotation = args[i].get_name().value()->value;
if (!args[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( logc.Fatal<Log::kProc>({{"no annotations provided ( => all annotations "
"no annotations provided ( => all annotations same to names), but " "same to names), but "
"can't add name annotation", "can't add name annotation"}},
current_node); current_node.get_pos());
} }
} }
} }
@ -439,21 +442,20 @@ nodes::FunctionDefinition BuilderTask<nodes::FunctionDefinition>::operator()(
for (auto &arg : args) { for (auto &arg : args) {
if (arg.get_annotation().has_value()) { if (arg.get_annotation().has_value()) {
if (!annotations_set.insert(*arg.get_annotation().value()).second) { if (!annotations_set.insert(*arg.get_annotation().value()).second) {
error_handling::handle_parsing_error( logc.Fatal<Log::kProc>(
"Two or more same annotations found in function definition", {{"Two or more same annotations found in function definition"}},
parser_node); parser_node.get_pos());
} }
} }
} }
return nodes::FunctionDefinition( return nodes::FunctionDefinition(
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(args), Run<nodes::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<Node>(expression_node.value())
: std::optional<nodes::Expr>()); : std::optional<Node>());
} }
} // namespace builders } // namespace builders

View file

@ -151,37 +151,37 @@ inline bool can_cast_modifier(Modifier from, Modifier to) {
} // namespace utils } // namespace utils
class Node { // class Node {
public: // public:
Node() : undefined_(true) {} // Node() : undefined_(true) {}
Node(std::pair<size_t, size_t> start_position, // Node(std::pair<size_t, size_t> start_position,
std::pair<size_t, size_t> end_position) // std::pair<size_t, size_t> end_position)
: undefined_(false), start_position_(start_position), // : undefined_(false), start_position_(start_position),
end_position_(end_position) {} // end_position_(end_position) {}
std::pair<size_t, size_t> get_start_position() const { // std::pair<size_t, size_t> get_start_position() const {
if (undefined_) { // if (undefined_) {
error_handling::handle_general_error( // error_handling::handle_general_error(
"Get start position from undefined node"); // "Get start position from undefined node");
} // }
return start_position_; // return start_position_;
} // }
std::pair<size_t, size_t> get_end_position() const { // std::pair<size_t, size_t> get_end_position() const {
if (undefined_) { // if (undefined_) {
error_handling::handle_general_error( // error_handling::handle_general_error(
"Get end position from undefined node"); // "Get end position from undefined node");
} // }
return end_position_; // return end_position_;
} // }
protected: // protected:
bool undefined_ = false; // bool undefined_ = false;
std::pair<size_t, size_t> start_position_ = {0, 0}; // std::pair<size_t, size_t> start_position_ = {0, 0};
std::pair<size_t, size_t> end_position_ = {0, 0}; // std::pair<size_t, size_t> end_position_ = {0, 0};
}; // };
struct unit {}; struct unit {};
struct null {}; struct null {};
@ -194,162 +194,121 @@ struct unicode {
std::string ch; std::string ch;
}; };
class Literal : public Node { struct Literal {
public: public:
using Type = using Type =
std::variant<float, double, int32_t, int64_t, size_t, std::string, std::variant<float, double, int32_t, int64_t, size_t, std::string,
unicode_string, char, unicode, bool, unit, null>; unicode_string, char, unicode, bool, unit, null>;
template <typename T>
Literal(Node node, T &&value) : Node(node), value_(std::forward<T>(value)) {}
template <typename T> std::optional<T *> get() { template <typename T> std::optional<T *> get() {
if (std::holds_alternative<T>(value_)) { if (std::holds_alternative<T>(value)) {
return &std::get<T>(value_); return &std::get<T>(value);
} }
return std::nullopt; return std::nullopt;
} }
template <typename T> std::optional<const T *> get() const { template <typename T> std::optional<const T *> get() const {
if (std::holds_alternative<T>(value_)) { if (std::holds_alternative<T>(value)) {
return &std::get<T>(value_); return &std::get<T>(value);
} }
return std::nullopt; return std::nullopt;
} }
Type &get_any() { return value_; } //
const Type &get_any() const { return value_; } Type value;
private:
Type value_;
}; };
class Identifier : public Node { // TODO: merge with identifier ??
public: struct Annotation {
static constexpr char NAME_DELIMITER = '.'; auto operator<=>(const Annotation &other) const = default;
enum IdentifierType { std::string value;
SIMPLE_NAME, };
SIMPLE_TYPE,
TYPECLASS, struct Identifier {
ARGUMENT_NAME, public:
ARGUMENT_TYPE, static constexpr char kNameDelimiter = '.';
enum Kind {
kSimpleName,
kSimpleType,
kTypeclass,
kArgName,
kArgType,
// ANNOTATION, used as std::string // ANNOTATION, used as std::string
OPERATOR, kOperator,
PLACEHOLDER, kPlaceholder,
// //
GENERIC_TYPE, kGenericType,
}; };
Identifier(Node node, IdentifierType type, std::string &&value) //
: Node(node), type_(type), value_(std::move(value)) {}
Identifier(Node node, IdentifierType type, const std::string &value) auto operator<=>(const Identifier &other) const = default;
: Node(node), type_(type), value_(value) {}
IdentifierType get_type() const { return type_; }
// //
std::string *get() { return &value_; } Kind kind;
std::string value;
const std::string *get() const { return &value_; } // TODO
// // void append_before(const std::string &name) {
// value_ = name + NAME_DELIMITER + value_;
// }
void append_before(const std::string &name) { // void append_before(
value_ = name + NAME_DELIMITER + value_; // const Identifier &identifier,
} // std::source_location location = std::source_location::current()) {
// error_handling::expect(identifier.type_ == type_,
// "different Identifier types on append_before",
// location);
// value_ = *identifier.get() + NAME_DELIMITER + value_;
// }
void append_before( // void append_after(const std::string &name) {
const Identifier &identifier, // value_ += NAME_DELIMITER + name;
std::source_location location = std::source_location::current()) { // }
error_handling::expect(identifier.type_ == type_,
"different Identifier types on append_before",
location);
value_ = *identifier.get() + NAME_DELIMITER + value_;
}
void append_after(const std::string &name) { // void append_after(
value_ += NAME_DELIMITER + name; // const Identifier &identifier,
} // std::source_location location = std::source_location::current()) {
// error_handling::expect(identifier.type_ == type_,
// "different Identifier types on append_after",
// location);
// value_ += NAME_DELIMITER + *identifier.get();
// }
void append_after( // std::vector<Identifier> get_fragments() const {
const Identifier &identifier, // std::vector<Identifier> fragments;
std::source_location location = std::source_location::current()) { // for (auto &&fragment_name :
error_handling::expect(identifier.type_ == type_, // std::ranges::views::split(value_, NAME_DELIMITER)) {
"different Identifier types on append_after", // fragments.emplace_back(
location); // *this, type_,
value_ += NAME_DELIMITER + *identifier.get(); // std::string(fragment_name.begin(), fragment_name.end()));
} // }
// return fragments;
// }
std::vector<Identifier> get_fragments() const { // std::pair<Identifier, Identifier> split_first() {
std::vector<Identifier> fragments; // const auto pos = value_.find(NAME_DELIMITER);
for (auto &&fragment_name : // if (pos == std::string::npos) {
std::ranges::views::split(value_, NAME_DELIMITER)) { // return {Identifier(*this, type_, ""), *this};
fragments.emplace_back( // }
*this, type_, // return {
std::string(fragment_name.begin(), fragment_name.end())); // Identifier(*this, type_, value_.substr(0, pos)),
} // Identifier(*this, type_, value_.substr(pos + 1))}; // '.' is leaved
return fragments; // out
} // }
std::pair<Identifier, Identifier> split_first() {
const auto pos = value_.find(NAME_DELIMITER);
if (pos == std::string::npos) {
return {Identifier(*this, type_, ""), *this};
}
return {
Identifier(*this, type_, value_.substr(0, pos)),
Identifier(*this, type_, value_.substr(pos + 1))}; // '.' is leaved out
}
//
bool operator==(const Identifier &other_identifier) const {
return type_ == other_identifier.type_ && value_ == other_identifier.value_;
}
bool operator!=(const Identifier &other_identifier) const {
return !(*this == other_identifier);
}
bool operator<(const Identifier &other_identifier) const {
return type_ < other_identifier.type_ || (type_ == other_identifier.type_ &&
value_ < other_identifier.value_);
}
private:
IdentifierType type_;
std::string value_;
}; };
class Extra : public Node { struct Extra {
public: std::string content;
Extra(Node node, std::string &&content)
: Node(node), content_(std::move(content)) {}
Extra(Node node, const std::string &content)
: Node(node), content_(content) {}
std::string *content() { return &content_; }
const std::string *content() const { return &content_; }
private:
std::string content_;
}; };
class EmptyLines : public Node { struct EmptyLines {
public: size_t count;
EmptyLines(Node node, size_t line_count)
: Node(node), line_count_(line_count) {}
size_t line_count() const { return line_count_; }
private:
size_t line_count_;
}; };
} // namespace nodes } // namespace nodes

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "basic_nodes.hpp" #include "basic_nodes.hpp"
#include "storage.hpp"
#include "type_nodes.hpp" #include "type_nodes.hpp"
#include <optional> #include <optional>
@ -9,504 +10,190 @@
namespace nodes { namespace nodes {
class TypedNode : public Node { using NodeId = storage::Id;
public:
TypedNode(Node node) : Node(node) {}
void set_expression_type(Type expression_type) {
expression_type_ = expression_type;
}
std::optional<Type> get_expression_type() const { return expression_type_; }
protected:
std::optional<Type> expression_type_;
};
class ExprData; class ExprData;
class ExprStorage;
class Expr { // TODO: add to all nodes
friend ExprStorage; struct GeneralInfo {
bool is_scoped;
public:
Expr() = delete;
ExprData *get();
const ExprData *get() const;
private:
Expr(ExprStorage &expression_storage, size_t id)
: expression_storage_(&expression_storage), id_(id) {}
private:
ExprStorage *expression_storage_;
size_t id_;
}; };
namespace utils { // namespace utils {
inline std::optional<nodes::ExprData *> // inline std::optional<nodes::ExprData *>
proxy_to_expr_optional(std::optional<nodes::Expr> &proxy) { // proxy_to_expr_optional(std::optional<nodes::Expr> &proxy) {
if (proxy.has_value()) { // if (proxy.has_value()) {
return proxy.value().get(); // return proxy.value().get();
} // }
return std::nullopt; // return std::nullopt;
} // }
inline std::optional<const nodes::ExprData *> // inline std::optional<const nodes::ExprData *>
proxy_to_expr_optional(const std::optional<nodes::Expr> &proxy) { // proxy_to_expr_optional(const std::optional<nodes::Expr> &proxy) {
if (proxy.has_value()) { // if (proxy.has_value()) {
return proxy.value().get(); // return proxy.value().get();
} // }
return std::nullopt; // return std::nullopt;
} // }
} // namespace utils // } // namespace utils
// --- flow control // --- flow control
class Match : public TypedNode { struct Match {
public: struct Case {
class Case : public TypedNode { enum Kind {
public:
enum CaseType {
PATTERN_VALUE, PATTERN_VALUE,
VALUE_PATTERN, VALUE_PATTERN,
}; };
Case(Node node, CaseType case_type, Expr value, //
std::optional<Expr> condition = std::nullopt,
std::optional<Expr> expression = std::nullopt)
: TypedNode(node), case_type_(case_type), value_(value),
condition_(condition), expression_(expression) {}
CaseType case_type() const { return case_type_; } Kind kind;
NodeId value;
ExprData *get_value() { return value_.get(); } std::optional<NodeId> condition;
std::optional<NodeId> expr;
const ExprData *get_value() const { return value_.get(); }
std::optional<ExprData *> get_condition() {
return utils::proxy_to_expr_optional(condition_);
}
std::optional<const ExprData *> get_condition() const {
return utils::proxy_to_expr_optional(condition_);
}
std::optional<ExprData *> get_expression() {
return utils::proxy_to_expr_optional(expression_);
}
std::optional<const ExprData *> get_expression() const {
return utils::proxy_to_expr_optional(expression_);
}
private:
CaseType case_type_;
Expr value_;
std::optional<Expr> condition_;
std::optional<Expr> expression_;
}; };
Match(Node node, Expr value, std::vector<Case> &&cases) //
: TypedNode(node), value_(value), cases_(std::move(cases)) {}
Match(Node node, Expr value, const std::vector<Case> &cases) NodeId value;
: TypedNode(node), value_(value), cases_(cases) {} std::vector<NodeId /*Case*/> cases;
ExprData *get_value() { return value_.get(); }
const ExprData *get_value() const { return value_.get(); }
size_t cases_size() const { return cases_.size(); }
Case *get_case(size_t id) { return &cases_.at(id); }
const Case *get_case(size_t id) const { return &cases_.at(id); }
private:
Expr value_;
std::vector<Case> cases_;
}; };
class Condition : public Node { struct Condition {
public: std::vector<std::pair<NodeId, NodeId>> cases;
Condition(Node node, std::vector<std::pair<Expr, Expr>> &&cases, std::optional<NodeId> else_case;
std::optional<Expr> else_case = std::nullopt)
: Node(node), cases_(std::move(cases)), else_case_(else_case) {}
Condition(Node node, const std::vector<std::pair<Expr, Expr>> &cases,
std::optional<Expr> else_case = std::nullopt)
: Node(node), cases_(cases), else_case_(else_case) {}
size_t cases_size() const { return cases_.size(); }
std::pair<ExprData *, ExprData *> get_case(size_t id) {
return {cases_.at(id).first.get(), cases_[id].second.get()};
}
std::pair<const ExprData *, const ExprData *> get_case(size_t id) const {
return {cases_.at(id).first.get(), cases_[id].second.get()};
}
std::optional<ExprData *> get_else_case() {
return utils::proxy_to_expr_optional(else_case_);
}
std::optional<const ExprData *> get_else_case() const {
return utils::proxy_to_expr_optional(else_case_);
}
private:
std::vector<std::pair<Expr, Expr>> cases_;
std::optional<Expr> else_case_;
}; };
class Loop : public TypedNode { // TODO: prittier constructors
struct Loop {
public: public:
enum LoopType { enum Kind {
LOOP, LOOP,
WHILE, WHILE,
FOR, FOR,
}; };
//
// LOOP // LOOP
Loop(Node node, Expr expression) Loop(NodeId expr) : kind(LOOP), expr(expr) {}
: TypedNode(node), loop_type_(LOOP), expression_(expression) {}
// WHILE // WHILE
Loop(Node node, Expr condition, Expr expression) Loop(NodeId condition, NodeId expr)
: TypedNode(node), loop_type_(WHILE), expression_(expression), : kind(WHILE), expr(expr), condition(condition) {}
condition_(condition) {}
// FOR // FOR
Loop(Node node, Expr variable, Expr interval, Expr expression) Loop(NodeId variable, NodeId interval, NodeId expr)
: TypedNode(node), loop_type_(FOR), expression_(expression), : kind(FOR), expr(expr), variable(variable), interval(interval) {}
variable_(variable), interval_(interval) {}
LoopType get_type() const { return loop_type_; } //
ExprData *get_expression() { return expression_.get(); } Kind kind;
NodeId expr;
const ExprData *get_expression() const { return expression_.get(); } std::optional<NodeId> condition;
std::optional<NodeId> variable;
std::optional<ExprData *> get_condition() { std::optional<NodeId> interval;
return utils::proxy_to_expr_optional(condition_);
}
std::optional<const ExprData *> get_condition() const {
return utils::proxy_to_expr_optional(condition_);
}
std::optional<ExprData *> get_variable() {
return utils::proxy_to_expr_optional(variable_);
}
std::optional<const ExprData *> get_variable() const {
return utils::proxy_to_expr_optional(variable_);
}
std::optional<ExprData *> get_interval() {
return utils::proxy_to_expr_optional(interval_);
}
std::optional<const ExprData *> get_interval() const {
return utils::proxy_to_expr_optional(interval_);
}
private:
LoopType loop_type_;
Expr expression_;
std::optional<Expr> condition_;
std::optional<Expr> variable_;
std::optional<Expr> interval_;
}; };
// --- containers // --- containers
class Container : public TypedNode { struct Container {
public: enum Kind {
enum ContainerType {
BLOCK, BLOCK,
ARRAY, ARRAY,
}; };
Container(Node node, ContainerType type, std::vector<Expr> &&expressions) //
: TypedNode(node), container_type_(type),
expressions_(std::move(expressions)) {}
Container(Node node, ContainerType type, const std::vector<Expr> &expressions) Kind kind;
: TypedNode(node), container_type_(type), expressions_(expressions) {} std::vector<NodeId> exprs;
ContainerType get_type() const { return container_type_; }
size_t expressions_size() const { return expressions_.size(); }
ExprData *get_expression(size_t id) { return expressions_.at(id).get(); }
const ExprData *get_expression(size_t id) const {
return expressions_.at(id).get();
}
private:
ContainerType container_type_;
std::vector<Expr> expressions_;
}; };
// --- modifiers // --- modifiers
class Return : public Node { struct Return {
public: enum Kind {
enum ReturnType {
RETURN, RETURN,
BRING, BRING,
}; };
Return(Node node, ReturnType type, Expr expression) //
: Node(node), return_type_(type), expression_(expression) {}
ReturnType get_type() const { return return_type_; } Kind kind;
NodeId expr;
ExprData *get_expression() { return expression_.get(); }
const ExprData *get_expression() const { return expression_.get(); }
private:
ReturnType return_type_;
Expr expression_;
}; };
class NameDefinition : public TypedNode { struct NameDefinition {
public: enum Kind {
enum Modifier {
LET, // % LET, // %
VAR, // $ VAR, // $
}; };
NameDefinition(Node node, Modifier modifier, Identifier &&name) //
: TypedNode(node), modifier_(modifier), name_(std::move(name)) {}
NameDefinition(Node node, Modifier modifier, const Identifier &name) Kind kind;
: TypedNode(node), modifier_(modifier), name_(name) {} Identifier name;
Modifier get_modifier() const { return modifier_; }
Identifier *get_name() { return &name_; }
const Identifier *get_name() const { return &name_; }
private:
Modifier modifier_;
Identifier name_;
}; };
class Access : public TypedNode { struct Access {
public: enum Kind {
enum AccessType {
ARRAY, ARRAY,
TUPLE, // only number literal index allowed TUPLE, // only number literal index allowed
}; };
Access(Node node, AccessType type, Expr value, Expr index) //
: TypedNode(node), access_type_(type), value_(value), index_(index) {}
AccessType get_type() const { return access_type_; } Kind kind;
ExprData *get_value() { return value_.get(); } NodeId value;
NodeId index;
const ExprData *get_value() const { return value_.get(); }
ExprData *get_index() { return index_.get(); }
const ExprData *get_index() const { return index_.get(); }
private:
AccessType access_type_;
Expr value_;
Expr index_;
}; };
class LoopControl : public TypedNode { struct LoopControl {
public: enum Kind {
enum LoopControlType {
BREAK, BREAK,
CONTINUE, CONTINUE,
}; };
LoopControl(Node node, LoopControlType type) //
: TypedNode(node), loop_control_type_(type) {}
LoopControlType get_type() const { return loop_control_type_; } Kind kind;
private:
LoopControlType loop_control_type_;
}; };
class ModifierExpression : public TypedNode { struct ModifierExpression {
public: Modifier modifier;
ModifierExpression(Node node, Modifier modifier, Expr expression) NodeId expr;
: TypedNode(node), modifier_(modifier), expression_(expression) {}
Modifier get_modifier() const { return modifier_; }
ExprData *get_expression() { return expression_.get(); }
const ExprData *get_expression() const { return expression_.get(); }
private:
Modifier modifier_;
Expr expression_;
}; };
// --- other // --- other
using AnnotatedArgument = std::pair<std::optional<std::string>, Expr>; using AnnotatedArgument = std::pair<std::optional<std::string>, NodeId>;
class NameExpression : public TypedNode { struct NameExpression {
public: Identifier name;
NameExpression(Node node, Identifier &&name)
: TypedNode(node), name_(std::move(name)) {}
NameExpression(Node node, const Identifier &name)
: TypedNode(node), name_(name) {}
NameExpression(Node node, Identifier &&name,
std::vector<AnnotatedArgument> &&args,
std::optional<Type> &&prefix, bool is_point_call = false,
bool is_operator_call = false)
: TypedNode(node), name_(std::move(name)), args_(std::move(args)),
prefix_(std::move(prefix)), is_point_call_(is_point_call),
is_operator_call_(is_operator_call) {}
Identifier *get_name() { return &name_; }
const Identifier *get_name() const { return &name_; }
std::optional<TypeData *> get_prefix() {
if (prefix_.has_value()) {
return prefix_.value().get();
}
return std::nullopt;
}
std::optional<const TypeData *> get_prefix() const {
if (prefix_.has_value()) {
return prefix_.value().get();
}
return std::nullopt;
}
size_t args_size() const { return args_.size(); }
ExprData *get_argument_value(size_t id) { return args_.at(id).second.get(); }
const ExprData *get_argument_value(size_t id) const {
return args_.at(id).second.get();
}
std::optional<std::string *> get_argument_annotation(size_t id) {
if (args_.at(id).first.has_value()) {
return &args_[id].first.value();
}
return std::nullopt;
}
std::optional<const std::string *> get_argument_annotation(size_t id) const {
if (args_.at(id).first.has_value()) {
return &args_[id].first.value();
}
return std::nullopt;
}
bool is_point_call() const { return is_point_call_; }
bool is_operator_call() const { return is_operator_call_; }
private:
Identifier name_;
// universal function call syntax // universal function call syntax
std::vector<AnnotatedArgument> args_; 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 ...
bool is_operator_call_ = false; // ... operator ... bool is_operator_call = false; // ... operator ...
}; };
class Constructor : public TypedNode { struct Constructor {
public: Type type;
Constructor(Node node, Type type, std::vector<AnnotatedArgument> &&args) std::vector<AnnotatedArgument> args;
: TypedNode(node), constructor_type_(type), args_(std::move(args)) {}
Constructor(Node node, Type type, const std::vector<AnnotatedArgument> &args)
: TypedNode(node), constructor_type_(type), args_(args) {}
TypeData *get_type() { return constructor_type_.get(); }
const TypeData *get_type() const { return constructor_type_.get(); }
Type get_type_proxy() const { return constructor_type_; }
size_t args_size() const { return args_.size(); }
ExprData *get_argument_value(size_t id) { return args_.at(id).second.get(); }
const ExprData *get_argument_value(size_t id) const {
return args_.at(id).second.get();
}
std::optional<std::string *> get_argument_annotation(size_t id) {
if (args_.at(id).first.has_value()) {
return &args_[id].first.value();
}
return std::nullopt;
}
std::optional<const std::string *> get_argument_annotation(size_t id) const {
if (args_.at(id).first.has_value()) {
return &args_[id].first.value();
}
return std::nullopt;
}
private:
Type constructor_type_;
std::vector<std::pair<std::optional<std::string>, Expr>> args_;
}; };
class Lambda : public TypedNode { struct Lambda {
public: std::vector<Identifier> args;
Lambda(Node node, std::vector<Identifier> &&args, Expr expression) NodeId expr;
: TypedNode(node), args_(std::move(args)), expression_(expression) {}
Lambda(Node node, const std::vector<Identifier> &args, Expr expression)
: TypedNode(node), args_(args), expression_(expression) {}
size_t args_size() const { return args_.size(); }
Identifier *get_argument(size_t id) { return &args_.at(id); }
const Identifier *get_argument(size_t id) const { return &args_.at(id); }
ExprData *get_expression() { return expression_.get(); }
const ExprData *get_expression() const { return expression_.get(); }
private:
std::vector<Identifier> args_;
Expr expression_;
}; };
class ExprData : public Node { class ExprData {
public: public:
using Type = std::variant< using Type = std::variant<
// --- flow control // --- flow control
@ -542,9 +229,8 @@ public:
public: public:
template <typename T> template <typename T>
ExprData(Node node, T &&expression, bool is_scoped) ExprData(T &&expression, bool is_scoped)
: Node(node), expression_(std::forward<T>(expression)), : expression_(std::forward<T>(expression)), is_scoped_(is_scoped) {}
is_scoped_(is_scoped) {}
template <typename T> std::optional<T *> get() { template <typename T> std::optional<T *> get() {
if (std::holds_alternative<T>(expression_)) { if (std::holds_alternative<T>(expression_)) {
@ -572,22 +258,22 @@ private:
bool is_scoped_ = false; bool is_scoped_ = false;
}; };
class ExprStorage { // class ExprStorage {
friend Expr; // friend Expr;
public: // public:
Expr add_expr(ExprData expression) { // Expr add_expr(ExprData expression) {
storage_.push_back(std::move(expression)); // storage_.push_back(std::move(expression));
return Expr(*this, storage_.size() - 1); // return Expr(*this, storage_.size() - 1);
} // }
private: // private:
ExprData *get_expr(size_t id) { return &storage_.at(id); } // ExprData *get_expr(size_t id) { return &storage_.at(id); }
const ExprData *get_expr(size_t id) const { return &storage_.at(id); } // const ExprData *get_expr(size_t id) const { return &storage_.at(id); }
private: // private:
std::vector<ExprData> storage_; // std::vector<ExprData> storage_;
}; // };
} // namespace nodes } // namespace nodes

View file

@ -1,15 +1,38 @@
#pragma once #pragma once
#include "expression_nodes.hpp"
#include "storage.hpp" #include "storage.hpp"
namespace nodes { namespace nodes {
// FIXME template <typename... Mixins> class Node_;
struct NodeData {
std::variant<int, bool> value; struct NodeData {
}; // TODO: union with nodes public:
template <typename T> NodeData(T value) : value(std::move(value)) {}
template <typename T> std::optional<T *> get() {
if (std::holds_alternative<T>(value)) {
return &std::get<T>(value);
}
return std::nullopt;
}
template <typename T> std::optional<const T *> get() const {
if (std::holds_alternative<T>(value)) {
return &std::get<T>(value);
}
return std::nullopt;
}
template <typename T> bool Holds() const {
return std::holds_alternative<T>(value);
}
public:
nodes::ExprData::Type value;
};
// TODO: replace NodeData with real node
class NodeStorage : public core::Storage<NodeData> { class NodeStorage : public core::Storage<NodeData> {
using Id = storage::Id; using Id = storage::Id;
@ -36,7 +59,7 @@ protected:
core::DependentStorage<T> &data_; core::DependentStorage<T> &data_;
}; };
// TODO: replace all nodes // FIXME: rename
// Mixins should be NodePart<...> or their children // Mixins should be NodePart<...> or their children
template <typename... Mixins> class Node_ : public Mixins... { template <typename... Mixins> class Node_ : public Mixins... {
using Id = storage::Id; using Id = storage::Id;
@ -45,9 +68,13 @@ public:
Node_(Id id, NodeStorage &data, Mixins &&...mixins) Node_(Id id, NodeStorage &data, Mixins &&...mixins)
: Mixins(std::move(mixins))..., id_(id), data_(data) {} : Mixins(std::move(mixins))..., id_(id), data_(data) {}
operator Id() const { return id(); }
// //
template <typename T> bool &Has() { return NodePart<T>::data_.Has(id_); } template <typename T> bool &Has() const {
return NodePart<T>::data_.Has(id_);
}
// //
@ -55,6 +82,12 @@ public:
template <typename T> T &get() { return std::get<T>(data_[id_].value); } template <typename T> T &get() { return std::get<T>(data_[id_].value); }
Id id() const { return id_; }
template <typename T> bool Holds() const {
return operator*().template Holds<T>();
}
// //
const NodeData &operator*() const { return data_[id_]; } const NodeData &operator*() const { return data_[id_]; }

View file

@ -27,54 +27,17 @@ enum class CombineResult {
}; };
// IN PROGRESS: add another constructors ?? // IN PROGRESS: add another constructors ??
class Import : public Node { struct Import {
public: Identifier import_name;
Import(Node node, const Identifier &import_name, Identifier module_name;
const Identifier &module_name, std::vector<Identifier> &&symbols = {}) std::vector<Identifier> symbols;
: Node(node), import_name_(import_name), module_name_(module_name),
symbols_(std::move(symbols)) {}
//
Identifier *get_import_name() { return &import_name_; }
const Identifier *get_import_name() const { return &import_name_; }
//
Identifier *get_module_name() { return &module_name_; }
const Identifier *get_module_name() const { return &module_name_; }
//
size_t symbols_size() const { return symbols_.size(); }
Identifier *get_symbol(size_t id) { return &symbols_.at(id); }
const Identifier *get_symbol(size_t id) const { return &symbols_.at(id); }
private:
Identifier import_name_;
Identifier module_name_;
std::vector<Identifier> symbols_;
}; };
class Constraint : public Node { struct Constraint {
public: NodeId expr;
Constraint(Node node, Expr expression)
: Node(node), expression_(expression) {}
ExprData *get_expression() { return expression_.get(); }
const ExprData *get_expression() const { return expression_.get(); }
private:
Expr expression_;
}; };
class FunctionDefinition : public Node { struct FunctionDefinition {
public:
class Argument { class Argument {
public: public:
Argument(const std::optional<std::string> &annotation, Identifier &&name, Argument(const std::optional<std::string> &annotation, Identifier &&name,
@ -242,151 +205,43 @@ public:
Modifier::NONE; // optional, result, none // sync with type Modifier::NONE; // optional, result, none // sync with type
}; };
FunctionDefinition(Node node, SymbolDocs &&docs, FunctionDefinition(SymbolDocs &&docs, 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> &&args, 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<NodeId> expr)
: Node(node), docs_(std::move(docs)), : docs(std::move(docs)), constraints(std::move(constraints)),
constraints_(std::move(constraints)), return_modifier_(return_modifier), return_modifier(return_modifier), is_method(is_method), name(name),
is_method_(is_method), name_(name), full_name_(name), full_name(name), args(std::move(args)),
args_(std::move(args)), are_annotations_same_to_names(are_annotations_same_to_names),
are_annotations_same_to_names_(are_annotations_same_to_names), expr(expr) {
expression_(expression) {
if (name_prefix.has_value()) { if (name_prefix.has_value()) {
full_name_.append_before(*name_prefix.value().get()); full_name.append_before(name_prefix.value().value);
} }
} }
// //
SymbolDocs *get_docs() { return &docs_; }
const SymbolDocs *get_docs() const { return &docs_; }
//
size_t constraints_size() const { return constraints_.size(); }
Constraint *get_constraint(size_t id) { return &constraints_.at(id); }
const Constraint *get_constraint(size_t id) const {
return &constraints_.at(id);
}
//
Modifier get_return_modifier() const { return return_modifier_; }
bool is_method() const { return is_method_; }
//
Identifier *get_name() { return &name_; }
const Identifier *get_name() const { return &name_; }
//
Identifier *get_full_name() { return &full_name_; }
const Identifier *get_full_name() const { return &full_name_; }
//
size_t args_size() const { return args_.size(); }
Argument *get_argument(size_t id) { return &args_.at(id); }
const Argument *get_argument(size_t id) const { return &args_.at(id); }
//
std::optional<ExprData *> get_expression() {
if (expression_.has_value()) {
return expression_.value().get();
}
return std::nullopt;
}
std::optional<const ExprData *> get_expression() const {
if (expression_.has_value()) {
return expression_.value().get();
}
return std::nullopt;
}
//
bool are_annotations_same_to_names() const {
return are_annotations_same_to_names_;
}
//
bool is_same_to(const FunctionDefinition &other) const; bool is_same_to(const FunctionDefinition &other) const;
CombineResult combine(FunctionDefinition &&other); CombineResult combine(FunctionDefinition &&other);
private: //
SymbolDocs docs_;
std::vector<Constraint> constraints_; SymbolDocs docs;
Modifier return_modifier_; std::vector<Constraint> constraints;
bool is_method_; Modifier return_modifier;
Identifier name_; bool is_method;
Identifier full_name_; Identifier name;
std::vector<Argument> args_; Identifier full_name;
bool are_annotations_same_to_names_; // needed for easier prinitng process std::vector<Argument> args;
std::optional<Expr> expression_; bool are_annotations_same_to_names; // needed for easier prinitng process
std::optional<NodeId> expr;
}; // refactor ?? }; // refactor ??
class TypeDefinition : public Node { struct TypeDefinition {
public: bool is_typeclass() { return name.kind == Identifier::kTypeclass; }
TypeDefinition(Node node, SymbolDocs &&docs, bool is_on_heap,
const Identifier &name, std::vector<Identifier> &&typeclasses,
std::vector<Identifier> &&args, std::optional<Type> type)
: Node(node), docs_(std::move(docs)), is_on_heap_(is_on_heap),
name_(name), typeclasses_(typeclasses), args_(std::move(args)),
type_(std::move(type)) {}
//
SymbolDocs *get_docs() { return &docs_; }
const SymbolDocs *get_docs() const { return &docs_; }
//
bool is_on_heap() const { return is_on_heap_; }
//
Identifier *get_name() { return &name_; }
const Identifier *get_name() const { return &name_; }
//
size_t args_size() const { return args_.size(); }
Identifier *get_argument(size_t id) { return &args_.at(id); }
const Identifier *get_argument(size_t id) const { return &args_.at(id); }
//
std::optional<Type> get_type() const {
if (type_.has_value()) {
return type_.value();
}
return std::nullopt;
}
//
bool is_typeclass() { return name_.get_type() == Identifier::TYPECLASS; }
// //
@ -394,53 +249,44 @@ public:
CombineResult combine(TypeDefinition &&other); CombineResult combine(TypeDefinition &&other);
private: //
SymbolDocs docs_;
bool is_on_heap_; SymbolDocs docs;
Identifier name_; bool is_on_heap;
std::vector<Identifier> typeclasses_; Identifier name;
std::vector<Identifier> args_; std::vector<Identifier> typeclasses;
std::optional<Type> type_; std::vector<Identifier> args;
std::optional<Type> type;
}; };
class Statement : public Node { struct Statement {
public: public:
using Type = std::variant<Import, TypeDefinition, FunctionDefinition, Extra, using Type = std::variant<Import, TypeDefinition, FunctionDefinition, Extra,
EmptyLines>; EmptyLines>;
// Statement(const Statement &) = default; //
// Statement(Statement &&) = default;
// Statement &operator=(const Statement &) = default;
// Statement &operator=(Statement &&) = default;
template <typename T>
Statement(Node node, T &&statement)
: Node(node), expr_(std::forward<T>(statement)) {}
template <typename T> std::optional<T *> get() { template <typename T> std::optional<T *> get() {
if (std::holds_alternative<T>(expr_)) { if (std::holds_alternative<T>(expr)) {
return &std::get<T>(expr_); return &std::get<T>(expr);
} }
return std::nullopt; return std::nullopt;
} }
template <typename T> std::optional<const T *> get() const { template <typename T> std::optional<const T *> get() const {
if (std::holds_alternative<T>(expr_)) { if (std::holds_alternative<T>(expr)) {
return &std::get<T>(expr_); return &std::get<T>(expr);
} }
return std::nullopt; return std::nullopt;
} }
Type &get_any() { return expr_; }
const Type &get_any() const { return expr_; }
bool is_same_to(const Statement &other) const; bool is_same_to(const Statement &other) const;
CombineResult combine(Statement &&other); CombineResult combine(Statement &&other);
private: //
Type expr_;
Type expr;
}; };
} // namespace nodes } // namespace nodes

View file

@ -167,7 +167,7 @@ public:
// //
bool is_generic() { return name_.get_type() == Identifier::GENERIC_TYPE; } bool is_generic() { return name_.kind == Identifier::kGenericType; }
// //
@ -192,7 +192,7 @@ public:
bool operator<(const TypeData &other) const { bool operator<(const TypeData &other) const {
if (name_ != other.name_) { if (name_ != other.name_) {
return *name_.get() < *other.name_.get(); return name_.value < other.name_.value;
} }
if (modifier_ != other.modifier_) { if (modifier_ != other.modifier_) {
@ -220,7 +220,7 @@ public:
// is parameters count check necessary ?? // is parameters count check necessary ??
builtin::Type to_builtin() const { builtin::Type to_builtin() const {
auto builtin_type = builtin::types::to_type(*name_.get()); auto builtin_type = builtin::types::to_type(name_.value);
auto builtin_type_parameters_count = auto builtin_type_parameters_count =
builtin::types::get_parameters_count(builtin_type); builtin::types::get_parameters_count(builtin_type);
@ -249,12 +249,12 @@ class TypeStorage {
public: public:
Type primitive(builtin::Type type); Type primitive(builtin::Type type);
Type add_array_of(Type type, Node node = Node()); Type add_array_of(Type type);
Type add_error_of(Type type, Node node = Node()); Type add_error_of(Type type);
nodes::Type add_container_of(std::vector<Type> &&parameters, nodes::Type add_container_of(std::vector<Type> &&parameters,
builtin::Type container, Node node = Node()); builtin::Type container);
nodes::Type add_modification_of(Type type, Modifier modifier); nodes::Type add_modification_of(Type type, Modifier modifier);

View file

@ -1,9 +1,3 @@
#include "expression_nodes.hpp" #include "expression_nodes.hpp"
namespace nodes { namespace nodes {}; // namespace nodes
ExprData *Expr::get() { return expression_storage_->get_expr(id_); }
const ExprData *Expr::get() const { return expression_storage_->get_expr(id_); }
}; // namespace nodes

View file

@ -1,5 +1,6 @@
#include "statement_nodes.hpp" #include "statement_nodes.hpp"
// #include "error_handling.hpp"
#include "error_handling.hpp" #include "error_handling.hpp"
#include "utils.hpp" #include "utils.hpp"
#include <algorithm> #include <algorithm>
@ -7,7 +8,7 @@
namespace nodes { namespace nodes {
bool FunctionDefinition::is_same_to(const FunctionDefinition &other) const { bool FunctionDefinition::is_same_to(const FunctionDefinition &other) const {
if (name_ != other.name_) { if (name != other.name) {
return false; return false;
} }
return true; return true;
@ -21,96 +22,95 @@ bool FunctionDefinition::is_same_to(const FunctionDefinition &other) const {
// name 'arg1 'arg2 -> 'arg3 = ... // function definition (without types) // name 'arg1 'arg2 -> 'arg3 = ... // function definition (without types)
CombineResult FunctionDefinition::combine(FunctionDefinition &&other) { CombineResult FunctionDefinition::combine(FunctionDefinition &&other) {
// names should be the same // names should be the same
if (name_ != other.name_) { if (name != other.name) {
return CombineResult::DIFFERENT_NAME_ERROR; return CombineResult::DIFFERENT_NAME_ERROR;
} }
// modifiers should be the same // modifiers should be the same
if (return_modifier_ != other.return_modifier_) { if (return_modifier != other.return_modifier) {
return CombineResult::DIFFERNENT_MODIFIER_ERROR; return CombineResult::DIFFERNENT_MODIFIER_ERROR;
} }
if (is_method_ != other.is_method_) { if (is_method != other.is_method) {
return CombineResult::DIFFERNENT_MODIFIER_ERROR; // other error type ?? return CombineResult::DIFFERNENT_MODIFIER_ERROR; // other error type ??
} }
if (are_annotations_same_to_names_ != other.are_annotations_same_to_names_) { if (are_annotations_same_to_names != other.are_annotations_same_to_names) {
return CombineResult::ARGUMENTS_ERROR; return CombineResult::ARGUMENTS_ERROR;
} }
// only one definition should have constraints // only one definition should have constraints
if (!constraints_.empty() && !other.constraints_.empty()) { if (!constraints.empty() && !other.constraints.empty()) {
return CombineResult::MORE_THEN_ONE_CONSTRAINTS_ERROR; return CombineResult::MORE_THEN_ONE_CONSTRAINTS_ERROR;
} }
// only one definition should have expression (body) // only one definition should have expression (body)
if (expression_.has_value() && other.expression_.has_value()) { if (expr.has_value() && other.expr.has_value()) {
return CombineResult::MORE_THEN_ONE_DEFINITION_BODY_ERROR; return CombineResult::MORE_THEN_ONE_DEFINITION_BODY_ERROR;
} }
// only one definition should have documentation // only one definition should have documentation
if (docs_.get_description().has_value() && if (docs.get_description().has_value() &&
other.docs_.get_description().has_value()) { other.docs.get_description().has_value()) {
return CombineResult::MORE_THEN_ONE_DOCS_ERROR; return CombineResult::MORE_THEN_ONE_DOCS_ERROR;
} }
if (docs_.annotations_info_size() > 0 && if (docs.annotations_info_size() > 0 &&
other.docs_.annotations_info_size() > 0) { other.docs.annotations_info_size() > 0) {
return CombineResult::MORE_THEN_ONE_DOCS_ERROR; return CombineResult::MORE_THEN_ONE_DOCS_ERROR;
} }
// check, that function definitions have same named args // check, that function definitions have same named args
for (size_t i = 0; i < std::max(args_.size(), other.args_.size()); ++i) { for (size_t i = 0; i < std::max(args.size(), other.args.size()); ++i) {
if (i < args_.size() && i < other.args_.size()) { if (i < args.size() && i < other.args.size()) {
// annotations should be the same // annotations should be the same
if ((!args_[i].get_annotation().has_value() && if ((!args[i].get_annotation().has_value() &&
!other.args_[i].get_annotation().has_value()) || !other.args[i].get_annotation().has_value()) ||
(args_[i].get_annotation().has_value() && (args[i].get_annotation().has_value() &&
other.args_[i].get_annotation().has_value() && other.args[i].get_annotation().has_value() &&
*args_[i].get_annotation().value() != *args[i].get_annotation().value() !=
*other.args_[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 ((!args_[i].get_name().has_value() && if ((!args[i].get_name().has_value() &&
!other.args_[i].get_name().has_value()) || !other.args[i].get_name().has_value()) ||
(args_[i].get_name().has_value() && (args[i].get_name().has_value() &&
other.args_[i].get_name().has_value() && other.args[i].get_name().has_value() &&
args_[i].get_name().value() != other.args_[i].get_name().value())) { args[i].get_name().value() != other.args[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 (args_[i].get_type().has_value() && if (args[i].get_type().has_value() &&
other.args_[i].get_type().has_value() && other.args[i].get_type().has_value() &&
*args_[i].get_type().value() != *other.args_[i].get_type().value()) { *args[i].get_type().value() != *other.args[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 (args_[i].get_before_modifier() != if (args[i].get_before_modifier() !=
other.args_[i].get_before_modifier() || other.args[i].get_before_modifier() ||
args_[i].get_after_modifier() != args[i].get_after_modifier() != other.args[i].get_after_modifier()) {
other.args_[i].get_after_modifier()) {
return CombineResult::ARGUMENTS_ERROR; return CombineResult::ARGUMENTS_ERROR;
} }
} else if (i < args_.size()) { } else if (i < args.size()) {
// annotations should be the same // annotations should be the same
if (args_[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 (args_[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.args_[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.args_[i].get_name().has_value()) { if (other.args[i].get_name().has_value()) {
return CombineResult::ARGUMENTS_ERROR; return CombineResult::ARGUMENTS_ERROR;
} }
} }
@ -118,28 +118,28 @@ CombineResult FunctionDefinition::combine(FunctionDefinition &&other) {
// combine docs // combine docs
// all docs should be in one definition // all docs should be in one definition
if (other.docs_.get_description().has_value() || if (other.docs.get_description().has_value() ||
other.docs_.annotations_info_size() > 0) { other.docs.annotations_info_size() > 0) {
if (docs_.annotations_info_size() > 0 || if (docs.annotations_info_size() > 0 ||
docs_.get_description().has_value()) { docs.get_description().has_value()) {
return CombineResult::MORE_THEN_ONE_DOCS_ERROR; return CombineResult::MORE_THEN_ONE_DOCS_ERROR;
} }
docs_ = std::move(other.docs_); docs = std::move(other.docs);
} }
if (!other.constraints_.empty()) { if (!other.constraints.empty()) {
constraints_ = std::move(other.constraints_); constraints = std::move(other.constraints);
} }
if (other.expression_.has_value()) { if (other.expr.has_value()) {
expression_ = other.expression_; expr = other.expr;
} }
for (size_t i = 0; i < other.args_.size(); ++i) { for (size_t i = 0; i < other.args.size(); ++i) {
if (i < args_.size()) { if (i < args.size()) {
if (other.args_[i].get_type().has_value()) { if (other.args[i].get_type().has_value()) {
if (args_[i].update_type_from(other.args_[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",
@ -147,7 +147,7 @@ CombineResult FunctionDefinition::combine(FunctionDefinition &&other) {
} }
} }
} else { } else {
args_.push_back(std::move(other.args_[i])); args.push_back(std::move(other.args[i]));
} }
} }
@ -155,7 +155,7 @@ CombineResult FunctionDefinition::combine(FunctionDefinition &&other) {
} }
bool TypeDefinition::is_same_to(const TypeDefinition &other) const { bool TypeDefinition::is_same_to(const TypeDefinition &other) const {
if (name_ != other.name_) { if (name != other.name) {
return false; return false;
} }
return true; return true;
@ -167,83 +167,83 @@ bool TypeDefinition::is_same_to(const TypeDefinition &other) const {
// Type[...] 'A 'B 'C = ... // define type // Type[...] 'A 'B 'C = ... // define type
CombineResult TypeDefinition::combine(TypeDefinition &&other) { CombineResult TypeDefinition::combine(TypeDefinition &&other) {
// name should be same // name should be same
if (name_ != other.name_) { if (name != other.name) {
return CombineResult::DIFFERENT_NAME_ERROR; return CombineResult::DIFFERENT_NAME_ERROR;
} }
// modifier should be the same // modifier should be the same
if (is_on_heap_ != other.is_on_heap_) { if (is_on_heap != other.is_on_heap) {
return CombineResult::DIFFERNENT_MODIFIER_ERROR; return CombineResult::DIFFERNENT_MODIFIER_ERROR;
} }
// typeclasses should be the same // typeclasses should be the same
if (typeclasses_.size() != other.typeclasses_.size()) { if (typeclasses.size() != other.typeclasses.size()) {
return CombineResult::ARGUMENTS_ERROR; return CombineResult::ARGUMENTS_ERROR;
} }
for (size_t i = 0; i < typeclasses_.size(); ++i) { for (size_t i = 0; i < typeclasses.size(); ++i) {
if (typeclasses_[i] != other.typeclasses_[i]) { if (typeclasses[i] != other.typeclasses[i]) {
return CombineResult::ARGUMENTS_ERROR; return CombineResult::ARGUMENTS_ERROR;
} }
} }
// args should be the same // args should be the same
if (args_.size() != other.args_.size()) { if (args.size() != other.args.size()) {
return CombineResult::ARGUMENTS_ERROR; return CombineResult::ARGUMENTS_ERROR;
} }
for (size_t i = 0; i < args_.size(); ++i) { for (size_t i = 0; i < args.size(); ++i) {
if (args_[i] != other.args_[i]) { if (args[i] != other.args[i]) {
return CombineResult::ARGUMENTS_ERROR; return CombineResult::ARGUMENTS_ERROR;
} }
} }
// only one definition should have documentation // only one definition should have documentation
if (docs_.get_description().has_value() && if (docs.get_description().has_value() &&
other.docs_.get_description().has_value()) { other.docs.get_description().has_value()) {
return CombineResult::MORE_THEN_ONE_DOCS_ERROR; return CombineResult::MORE_THEN_ONE_DOCS_ERROR;
} }
if (docs_.annotations_info_size() > 0 && if (docs.annotations_info_size() > 0 &&
other.docs_.annotations_info_size() > 0) { other.docs.annotations_info_size() > 0) {
return CombineResult::MORE_THEN_ONE_DOCS_ERROR; return CombineResult::MORE_THEN_ONE_DOCS_ERROR;
} }
// only one type should define type / body // only one type should define type / body
if (type_.has_value() && other.type_.has_value()) { if (type.has_value() && other.type.has_value()) {
return CombineResult::MORE_THEN_ONE_DEFINITION_BODY_ERROR; return CombineResult::MORE_THEN_ONE_DEFINITION_BODY_ERROR;
} }
// combine docs // combine docs
// all docs should be in one definition // all docs should be in one definition
if (other.docs_.get_description().has_value() || if (other.docs.get_description().has_value() ||
other.docs_.annotations_info_size() > 0) { other.docs.annotations_info_size() > 0) {
if (docs_.annotations_info_size() > 0 || if (docs.annotations_info_size() > 0 ||
docs_.get_description().has_value()) { docs.get_description().has_value()) {
return CombineResult::MORE_THEN_ONE_DOCS_ERROR; return CombineResult::MORE_THEN_ONE_DOCS_ERROR;
} }
docs_ = std::move(other.docs_); docs = std::move(other.docs);
} }
if (other.type_.has_value()) { if (other.type.has_value()) {
type_ = std::move(other.type_); type = std::move(other.type);
} }
return CombineResult::OK; return CombineResult::OK;
} }
bool Statement::is_same_to(const Statement &other) const { bool Statement::is_same_to(const Statement &other) const {
if (expr_.index() != other.expr_.index()) { if (expr.index() != other.expr.index()) {
return false; return false;
} }
switch (expr_.index()) { switch (expr.index()) {
case 0: // Import case 0: // Import
return false; return false;
case 1: // TypeDefinition case 1: // TypeDefinition
return std::get<TypeDefinition>(expr_).is_same_to( return std::get<TypeDefinition>(expr).is_same_to(
std::move(std::get<TypeDefinition>(other.expr_))); std::move(std::get<TypeDefinition>(other.expr)));
case 2: // FunctionDefinition case 2: // FunctionDefinition
return std::get<FunctionDefinition>(expr_).is_same_to( return std::get<FunctionDefinition>(expr).is_same_to(
std::move(std::get<FunctionDefinition>(other.expr_))); std::move(std::get<FunctionDefinition>(other.expr)));
case 3: // Extra case 3: // Extra
return false; return false;
case 4: // EmptyLines case 4: // EmptyLines
@ -259,19 +259,19 @@ bool Statement::is_same_to(const Statement &other) const {
} }
CombineResult Statement::combine(Statement &&other) { CombineResult Statement::combine(Statement &&other) {
if (expr_.index() != other.expr_.index()) { if (expr.index() != other.expr.index()) {
return CombineResult::DIFFERENT_STATEMENT_TYPES; return CombineResult::DIFFERENT_STATEMENT_TYPES;
} }
switch (expr_.index()) { switch (expr.index()) {
case 0: // Import case 0: // Import
return CombineResult::STATEMENTS_CANT_BE_COMBINED_ERROR; return CombineResult::STATEMENTS_CANT_BE_COMBINED_ERROR;
case 1: // TypeDefinition case 1: // TypeDefinition
return std::get<TypeDefinition>(expr_).combine( return std::get<TypeDefinition>(expr).combine(
std::move(std::get<TypeDefinition>(other.expr_))); std::move(std::get<TypeDefinition>(other.expr)));
case 2: // FunctionDefinition case 2: // FunctionDefinition
return std::get<FunctionDefinition>(expr_).combine( return std::get<FunctionDefinition>(expr).combine(
std::move(std::get<FunctionDefinition>(other.expr_))); std::move(std::get<FunctionDefinition>(other.expr)));
case 3: // Extra case 3: // Extra
return CombineResult::STATEMENTS_CANT_BE_COMBINED_ERROR; return CombineResult::STATEMENTS_CANT_BE_COMBINED_ERROR;
case 4: // EmptyLines case 4: // EmptyLines

View file

@ -1,5 +1,7 @@
#include "type_nodes.hpp" #include "type_nodes.hpp"
// TODO: replace error system
namespace nodes { namespace nodes {
TypeData *Type::get() { return type_storage_->get_type(id_); } TypeData *Type::get() { return type_storage_->get_type(id_); }
@ -18,12 +20,14 @@ Type TypeStorage::primitive(builtin::Type type) {
return Type(*this, iter->second); return Type(*this, iter->second);
} else { } else {
primitive_type_ids_[type] = storage_.size(); primitive_type_ids_[type] = storage_.size();
return add_type(TypeData(Identifier(Node(), Identifier::SIMPLE_TYPE, return add_type(TypeData(Identifier{
builtin::types::to_string(type)))); .kind = Identifier::kSimpleType,
.value = builtin::types::to_string(type),
}));
} }
} }
Type TypeStorage::add_array_of(Type type, Node node) { Type TypeStorage::add_array_of(Type type) {
if (type.type_storage_ != this) { if (type.type_storage_ != this) {
error_handling::handle_general_error( error_handling::handle_general_error(
"TypeStorage: Can't add array of type from another type " "TypeStorage: Can't add array of type from another type "
@ -33,12 +37,15 @@ Type TypeStorage::add_array_of(Type type, Node node) {
std::vector<nodes::Type> parameters; std::vector<nodes::Type> parameters;
parameters.push_back(type); parameters.push_back(type);
return add_type(TypeData(Identifier(node, Identifier::SIMPLE_TYPE, return add_type(TypeData(
builtin::types::ARRAY_IDENTIFIER), Identifier{
std::move(parameters))); .kind = Identifier::kSimpleType,
.value = builtin::types::ARRAY_IDENTIFIER,
},
std::move(parameters)));
} }
Type TypeStorage::add_error_of(Type type, Node node) { Type TypeStorage::add_error_of(Type type) {
if (type.type_storage_ != this) { if (type.type_storage_ != this) {
error_handling::handle_general_error( error_handling::handle_general_error(
"TypeStorage: Can't add error of type from another type " "TypeStorage: Can't add error of type from another type "
@ -48,13 +55,16 @@ Type TypeStorage::add_error_of(Type type, Node node) {
std::vector<nodes::Type> parameters; std::vector<nodes::Type> parameters;
parameters.push_back(type); parameters.push_back(type);
return add_type(TypeData(Identifier(node, Identifier::SIMPLE_TYPE, return add_type(TypeData(
builtin::types::ERROR_IDENTIFIER), Identifier{
std::move(parameters))); .kind = Identifier::kSimpleType,
.value = builtin::types::ERROR_IDENTIFIER,
},
std::move(parameters)));
} }
nodes::Type TypeStorage::add_container_of(std::vector<Type> &&parameters, nodes::Type TypeStorage::add_container_of(std::vector<Type> &&parameters,
builtin::Type container, Node node) { builtin::Type container) {
for (auto &parameter : parameters) { for (auto &parameter : parameters) {
if (parameter.type_storage_ != this) { if (parameter.type_storage_ != this) {
error_handling::handle_general_error( error_handling::handle_general_error(
@ -64,10 +74,12 @@ nodes::Type TypeStorage::add_container_of(std::vector<Type> &&parameters,
} }
} }
return add_type( return add_type(nodes::TypeData(
nodes::TypeData(nodes::Identifier(node, nodes::Identifier::SIMPLE_TYPE, nodes::Identifier{
builtin::types::to_string(container)), .kind = nodes::Identifier::kSimpleType,
std::move(parameters))); .value = builtin::types::to_string(container),
},
std::move(parameters)));
} }
nodes::Type TypeStorage::add_modification_of(Type type, Modifier modifier) { nodes::Type TypeStorage::add_modification_of(Type type, Modifier modifier) {
@ -95,7 +107,7 @@ bool TypeStorage::resolve_all_generic_types() {
for (auto &type : storage_) { for (auto &type : storage_) {
if (type.is_generic()) { if (type.is_generic()) {
auto iter = resolved_generic_names_.find(*type.get_name()->get()); auto iter = resolved_generic_names_.find(type.get_name()->value);
// because of undefined order some types can became resolved earlir // because of undefined order some types can became resolved earlir
// wirking correctly because each generic type has <= 1 successor, no // wirking correctly because each generic type has <= 1 successor, no
@ -280,9 +292,10 @@ bool TypeStorage::resolve(
// //
Identifier TypeStorage::generate_generic_type_identifier() { Identifier TypeStorage::generate_generic_type_identifier() {
Identifier identifier = Identifier identifier = Identifier{
Identifier(Node(), Identifier::GENERIC_TYPE, .kind = Identifier::kGenericType,
"G_" + std::to_string(last_generic_type_id_)); .value = "G_" + std::to_string(last_generic_type_id_),
};
++last_generic_type_id_; ++last_generic_type_id_;
return identifier; return identifier;
} }

View file

@ -33,7 +33,7 @@ void print(const nodes::ExprData &expression, printers::Printer &printer) {
void print(const nodes::Match::Case &expression, Printer &printer) { void print(const nodes::Match::Case &expression, Printer &printer) {
switch (expression.case_type()) { switch (expression.kind()) {
case nodes::Match::Case::PATTERN_VALUE: case nodes::Match::Case::PATTERN_VALUE:
printer.print(":="); printer.print(":=");
break; break;
@ -316,7 +316,7 @@ void print(const nodes::NameExpression &expression,
bool operator_called_as_function = bool operator_called_as_function =
(!expression.is_operator_call() && (!expression.is_operator_call() &&
expression.get_name()->get_type() == nodes::Identifier::OPERATOR); expression.get_name()->get_type() == nodes::Identifier::kOperator);
if (operator_called_as_function) { if (operator_called_as_function) {
printer.print("( "); printer.print("( ");

View file

@ -18,15 +18,15 @@ class State {
public: public:
struct VariableInfo { struct VariableInfo {
nodes::Type type; nodes::Type type;
nodes::NameDefinition::Modifier modifier; nodes::NameDefinition::Kind modifier;
}; };
public: public:
State(Log &log) : log_(log) {} State(Log &log) : log_(log) {}
bool insert_variable(const std::string &name, nodes::Type type, bool insert_variable(const std::string &name, nodes::Type type,
nodes::NameDefinition::Modifier modifier) { nodes::NameDefinition::Kind modifier) {
Log::Context logc(log_, utils::Log::Area::kTypeCheck); Log::Context logc(log_, Log::Area::kTypeCheck);
if (contexts_.empty()) { if (contexts_.empty()) {
logc.Fatal<Log::kSys>( logc.Fatal<Log::kSys>(
@ -50,7 +50,7 @@ public:
} }
bool bring_type(nodes::Type type) { bool bring_type(nodes::Type type) {
Log::Context logc(log_, utils::Log::Area::kTypeCheck); Log::Context logc(log_, Log::Area::kTypeCheck);
if (contexts_.empty()) { if (contexts_.empty()) {
logc.Fatal<Log::kSys>( logc.Fatal<Log::kSys>(
@ -66,7 +66,7 @@ public:
} }
bool return_type(nodes::Type type) { bool return_type(nodes::Type type) {
Log::Context logc(log_, utils::Log::Area::kTypeCheck); Log::Context logc(log_, Log::Area::kTypeCheck);
if (contexts_.empty()) { if (contexts_.empty()) {
logc.Fatal<Log::kSys>( logc.Fatal<Log::kSys>(
@ -83,7 +83,7 @@ public:
private: private:
void enter_context(const nodes::Node &node) { void enter_context(const nodes::Node &node) {
Log::Context logc(log_, utils::Log::Area::kTypeCheck); Log::Context logc(log_, Log::Area::kTypeCheck);
contexts_.emplace_back(node); contexts_.emplace_back(node);
} }
@ -92,7 +92,7 @@ private:
// returns brought type, return type is merged with next context or with // returns brought type, return type is merged with next context or with
// brought type in last context // brought type in last context
nodes::MaybeType exit_context() { nodes::MaybeType exit_context() {
Log::Context logc(log_, utils::Log::Area::kTypeCheck); Log::Context logc(log_, Log::Area::kTypeCheck);
if (contexts_.empty()) { if (contexts_.empty()) {
logc.Fatal<Log::kSys>( logc.Fatal<Log::kSys>(

View file

@ -849,7 +849,7 @@ Result CheckTask<nodes::Lambda>::operator()(const nodes::Lambda &expr,
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),
nodes::NameDefinition::Modifier::LET)) { nodes::NameDefinition::Kind::LET)) {
// TODO: which modifier ?? // TODO: which modifier ??
type_check_error("Variable is already defined in this context", expr, type_check_error("Variable is already defined in this context", expr,
executor); executor);

View file

@ -11,7 +11,7 @@ nodes::Type check_same_to_pass_type_in_args(nodes::Type type, const Args &args,
Executor &executor, Executor &executor,
const std::string &message, const std::string &message,
bool handle_errors) { bool handle_errors) {
Log::Context logc(executor.log(), utils::Log::Area::kTypeCheck); Log::Context logc(executor.log(), Log::Area::kTypeCheck);
if (not args.get_passed().has_value()) { if (not args.get_passed().has_value()) {
return type; return type;
@ -27,7 +27,7 @@ nodes::Type check_same_to_pass_type_in_args(nodes::Type type, const Args &args,
bool check_no_pass_type_in_args(const Args &args, const nodes::Node &node, bool check_no_pass_type_in_args(const Args &args, 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(), Log::Area::kTypeCheck);
if (args.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);
@ -40,7 +40,7 @@ bool check_no_pass_type_in_args(const Args &args, const nodes::Node &node,
Result type_same_to_expected(nodes::Type type, const Args &args, 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(), Log::Area::kTypeCheck);
const auto &expected = args.get_expected(); const auto &expected = args.get_expected();
@ -63,7 +63,7 @@ Result type_same_to_expected(nodes::Type type, const Args &args,
Result type_check_from_args(nodes::Type /*type*/, const Args & /*args*/, 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*/) { bool /*handle_errors*/) {
Log::Context logc(executor.log(), utils::Log::Area::kTypeCheck); Log::Context logc(executor.log(), Log::Area::kTypeCheck);
/* TODO FIXME */ /* TODO FIXME */
logc.Fatal<Log::kSys>({{"Not implemented yet"}}); logc.Fatal<Log::kSys>({{"Not implemented yet"}});
@ -76,7 +76,7 @@ find_statement(const std::string &name, const nodes::Node & /*node*/,
Executor &executor, const std::string &message_not_found, Executor &executor, const std::string &message_not_found,
const std::string &message_different_statement, const std::string &message_different_statement,
bool handle_errors) { bool handle_errors) {
Log::Context logc(executor.log(), utils::Log::Area::kTypeCheck); Log::Context logc(executor.log(), Log::Area::kTypeCheck);
const auto maybe_any_statement = executor.state<names::NameTree>().find(name); const auto maybe_any_statement = executor.state<names::NameTree>().find(name);
if (not maybe_any_statement.has_value()) { if (not maybe_any_statement.has_value()) {
@ -100,7 +100,7 @@ find_statement(const std::string &name, const nodes::Node & /*node*/,
std::optional<const nodes::TypeDefinition *> std::optional<const nodes::TypeDefinition *>
find_type_definition(const std::string &name, const nodes::Node &node, find_type_definition(const std::string &name, const nodes::Node &node,
Executor &executor, bool handle_errors) { Executor &executor, bool handle_errors) {
Log::Context logc(executor.log(), utils::Log::Area::kTypeCheck); Log::Context logc(executor.log(), Log::Area::kTypeCheck);
return find_statement<nodes::TypeDefinition>( return find_statement<nodes::TypeDefinition>(
name, node, executor, "No type definition found in name tree", name, node, executor, "No type definition found in name tree",
@ -110,7 +110,7 @@ find_type_definition(const std::string &name, const nodes::Node &node,
std::optional<const nodes::FunctionDefinition *> std::optional<const nodes::FunctionDefinition *>
find_name_definition(const std::string &name, const nodes::Node &node, find_name_definition(const std::string &name, const nodes::Node &node,
Executor &executor, bool handle_errors) { Executor &executor, bool handle_errors) {
Log::Context logc(executor.log(), utils::Log::Area::kTypeCheck); Log::Context logc(executor.log(), Log::Area::kTypeCheck);
return find_statement<nodes::FunctionDefinition>( return find_statement<nodes::FunctionDefinition>(
name, node, executor, "No name definition found in name tree", name, node, executor, "No name definition found in name tree",
@ -121,7 +121,7 @@ std::optional<nodes::Type> unfold_user_defined_type(nodes::Type type,
const nodes::Node &node, const nodes::Node &node,
Executor &executor, Executor &executor,
bool handle_errors) { bool handle_errors) {
Log::Context logc(executor.log(), utils::Log::Area::kTypeCheck); Log::Context logc(executor.log(), Log::Area::kTypeCheck);
const auto maybe_type_definition = find_type_definition( const auto maybe_type_definition = find_type_definition(
*type.get()->get_name()->get(), node, executor, handle_errors); *type.get()->get_name()->get(), node, executor, handle_errors);
@ -151,7 +151,7 @@ std::optional<nodes::Type> get_field_type_by_name(nodes::Type type,
const nodes::Node &node, const nodes::Node &node,
Executor &executor, Executor &executor,
bool handle_errors) { bool handle_errors) {
Log::Context logc(executor.log(), utils::Log::Area::kTypeCheck); Log::Context logc(executor.log(), Log::Area::kTypeCheck);
switch (type.get()->to_builtin()) { switch (type.get()->to_builtin()) {
case builtin::Type::TUPLE: { // access field case builtin::Type::TUPLE: { // access field
@ -194,7 +194,7 @@ std::optional<nodes::Type> get_field_type_by_name(nodes::Type type,
// FIXME: replace with direct log calls // FIXME: replace with direct log calls
void type_check_error(const std::string &message, const nodes::Node &, void type_check_error(const std::string &message, const nodes::Node &,
Executor &executor, bool handle_error) { Executor &executor, bool handle_error) {
Log::Context logc(executor.log(), utils::Log::Area::kTypeCheck); Log::Context logc(executor.log(), Log::Area::kTypeCheck);
if (!handle_error) { if (!handle_error) {
return; return;

View file

@ -2,6 +2,7 @@
#include <string> #include <string>
#include "log.hpp"
#include "utils.hpp" #include "utils.hpp"
#include "tree_sitter/api.h" #include "tree_sitter/api.h"
@ -18,56 +19,46 @@ public:
: node_(node), source_(source) {} : node_(node), source_(source) {}
std::string get_type() const { std::string get_type() const {
if (is_null()) { utils::Assert(not is_null(),
error_handling::handle_general_error( "Null parsing node method called (get_type)");
"Null parsing node method called (get_type)");
}
return ts_node_type(node_); return ts_node_type(node_);
} }
std::pair<size_t, size_t> get_start_point() const { utils::Pos::Point get_start_point() const {
if (is_null()) { utils::Assert(not is_null(),
error_handling::handle_general_error( "Null parsing node method called (get_start_point)");
"Null parsing node method called (get_start_point)");
}
TSPoint point = ts_node_start_point(node_); TSPoint point = ts_node_start_point(node_);
return {point.row, point.column}; return {point.row, point.column};
} }
std::pair<size_t, size_t> get_end_point() const { utils::Pos::Point get_end_point() const {
if (is_null()) { utils::Assert(not is_null(),
error_handling::handle_general_error( "Null parsing node method called (get_end_point)");
"Null parsing node method called (get_end_point)");
}
TSPoint point = ts_node_end_point(node_); TSPoint point = ts_node_end_point(node_);
return {point.row, point.column}; return {point.row, point.column};
} }
utils::Pos get_pos() const { return {get_start_point(), get_end_point()}; }
std::string get_as_sexpression() const { std::string get_as_sexpression() const {
if (is_null()) { utils::Assert(not is_null(),
error_handling::handle_general_error( "Null parsing node method called (get_as_sexpression)");
"Null parsing node method called (get_as_sexpression)");
}
return ts_node_string(node_); return ts_node_string(node_);
} }
std::string get_value() const { // from source std::string get_value() const { // from source
if (is_null()) { utils::Assert(not is_null(),
error_handling::handle_general_error( "Null parsing node method called (get_value)");
"Null parsing node method called (get_value)");
}
size_t start = ts_node_start_byte(node_); size_t start = ts_node_start_byte(node_);
size_t end = ts_node_end_byte(node_); size_t end = ts_node_end_byte(node_);
return source_->substr(start, end - start); return source_->substr(start, end - start);
} }
size_t get_value_length() const { // from source size_t get_value_length() const { // from source
if (is_null()) { utils::Assert(not is_null(),
error_handling::handle_general_error( "Null parsing node method called (get_value_length)");
"Null parsing node method called (get_value_length)");
}
size_t start = ts_node_start_byte(node_); size_t start = ts_node_start_byte(node_);
size_t end = ts_node_end_byte(node_); size_t end = ts_node_end_byte(node_);
return end - start; return end - start;
@ -76,106 +67,80 @@ public:
bool is_null() const { return ts_node_is_null(node_); } bool is_null() const { return ts_node_is_null(node_); }
bool is_named() const { bool is_named() const {
if (is_null()) { utils::Assert(not is_null(),
error_handling::handle_general_error( "Null parsing node method called (is_named)");
"Null parsing node method called (is_named)");
}
return ts_node_is_named(node_); return ts_node_is_named(node_);
} }
bool is_missing() const { bool is_missing() const {
if (is_null()) { utils::Assert(not is_null(),
error_handling::handle_general_error( "Null parsing node method called (is_missing)");
"Null parsing node method called (is_missing)");
}
return ts_node_is_missing(node_); return ts_node_is_missing(node_);
} }
bool is_extra() const { // comments, etc. bool is_extra() const { // comments, etc.
if (is_null()) { utils::Assert(not is_null(),
error_handling::handle_general_error( "Null parsing node method called (is_extra)");
"Null parsing node method called (is_extra)");
}
return ts_node_is_extra(node_); return ts_node_is_extra(node_);
} }
bool has_error() const { bool has_error() const {
if (is_null()) { utils::Assert(not is_null(),
error_handling::handle_general_error( "Null parsing node method called (has_error)");
"Null parsing node method called (has_error)");
}
return ts_node_has_error(node_); return ts_node_has_error(node_);
} }
Node nth_child(size_t n) const { Node nth_child(size_t n) const {
if (is_null()) { utils::Assert(not is_null(),
error_handling::handle_general_error( "Null parsing node method called (nth_child)");
"Null parsing node method called (nth_child)");
}
return Node(ts_node_child(node_, n), source_); return Node(ts_node_child(node_, n), source_);
} }
size_t child_count() const { size_t child_count() const {
if (is_null()) { utils::Assert(not is_null(),
error_handling::handle_general_error( "Null parsing node method called (child_count)");
"Null parsing node method called (child_count)");
}
return ts_node_child_count(node_); return ts_node_child_count(node_);
} }
Node nth_named_child(size_t n) const { Node nth_named_child(size_t n) const {
if (is_null()) { utils::Assert(not is_null(),
error_handling::handle_general_error( "Null parsing node method called (nth_named_child)");
"Null parsing node method called (nth_named_child)");
}
return Node(ts_node_named_child(node_, n), source_); return Node(ts_node_named_child(node_, n), source_);
} }
size_t named_child_count() const { size_t named_child_count() const {
if (is_null()) { utils::Assert(not is_null(),
error_handling::handle_general_error( "Null parsing node method called (named_child_count)");
"Null parsing node method called (named_child_count)");
}
return ts_node_named_child_count(node_); return ts_node_named_child_count(node_);
} }
Node child_by_field_name(const std::string &name) const { Node child_by_field_name(const std::string &name) const {
if (is_null()) { utils::Assert(not is_null(),
error_handling::handle_general_error( "Null parsing node method called (child_by_field_name)");
"Null parsing node method called (child_by_field_name)");
}
return Node(ts_node_child_by_field_name(node_, name.c_str(), name.size()), return Node(ts_node_child_by_field_name(node_, name.c_str(), name.size()),
source_); source_);
} }
Node previous_sibling() const { Node previous_sibling() const {
if (is_null()) { utils::Assert(not is_null(),
error_handling::handle_general_error( "Null parsing node method called (previous_sibling)");
"Null parsing node method called (previous_sibling)");
}
return Node(ts_node_prev_sibling(node_), source_); return Node(ts_node_prev_sibling(node_), source_);
} }
Node previous_named_sibling() const { Node previous_named_sibling() const {
if (is_null()) { utils::Assert(not is_null(),
error_handling::handle_general_error( "Null parsing node method called (previous_named_sibling)");
"Null parsing node method called (previous_named_sibling)");
}
return Node(ts_node_prev_named_sibling(node_), source_); return Node(ts_node_prev_named_sibling(node_), source_);
} }
Node next_sibling() const { Node next_sibling() const {
if (is_null()) { utils::Assert(not is_null(),
error_handling::handle_general_error( "Null parsing node method called (next_sibling)");
"Null parsing node method called (next_sibling)");
}
return Node(ts_node_next_sibling(node_), source_); return Node(ts_node_next_sibling(node_), source_);
} }
Node next_named_sibling() const { Node next_named_sibling() const {
if (is_null()) { utils::Assert(not is_null(),
error_handling::handle_general_error( "Null parsing node method called (next_named_sibling)");
"Null parsing node method called (next_named_sibling)");
}
return Node(ts_node_next_named_sibling(node_), source_); return Node(ts_node_next_named_sibling(node_), source_);
} }

View file

@ -63,6 +63,18 @@ namespace utils {
#else // GCC, Clang #else // GCC, Clang
__builtin_unreachable(); __builtin_unreachable();
#endif #endif
// ---
// // TODO
// template<typename U, typename V>
// inline std::optional<V> carry(std::optional<U> value, std::function<V(U&&)>
// const& f) {
// if (value.has_value()) {
// return f(std::move(value));
// }
// return std::nullopt;
// }
} }
} // namespace utils } // namespace utils