lang/lang/builders/include/expression_builders.hpp
2024-08-25 15:41:20 +03:00

217 lines
6.7 KiB
C++

#pragma once
#include "basic_builders.hpp"
#include "builders_utils.hpp"
#include "expression_nodes.hpp"
#include "tree_sitter_wrapper.hpp"
namespace utils {
struct CommaTag {};
struct OperatorTag {};
struct BlockTag {};
struct ArrayTag {};
struct ArrayAccessTag {};
struct TupleAccessTag {};
struct RefTag {};
struct SuffixTag {};
struct FuncCallTag {};
} // namespace utils
namespace builders {
// --- flow control
template <>
struct BuilderTask<nodes::ExpressionProxy>
: public BuilderTaskBase<nodes::ExpressionProxy> {
using BuilderTaskBase<nodes::ExpressionProxy>::BuilderTaskBase;
nodes::ExpressionProxy operator()(const ParserNode &parser_node,
const Arguments &args) override;
};
template <>
struct BuilderTask<nodes::Match::Case>
: public BuilderTaskBase<nodes::Match::Case> {
using BuilderTaskBase<nodes::Match::Case>::BuilderTaskBase;
nodes::Match::Case operator()(const ParserNode &parser_node,
const Arguments &args) override;
};
template <>
struct BuilderTask<nodes::Match> : public BuilderTaskBase<nodes::Match> {
using BuilderTaskBase<nodes::Match>::BuilderTaskBase;
nodes::Match operator()(const ParserNode &parser_node,
const Arguments &args) override;
};
template <>
struct BuilderTask<nodes::Condition>
: public BuilderTaskBase<nodes::Condition> {
using BuilderTaskBase<nodes::Condition>::BuilderTaskBase;
nodes::Condition operator()(const ParserNode &parser_node,
const Arguments &args) override;
};
template <>
struct BuilderTask<nodes::Loop> : public BuilderTaskBase<nodes::Loop> {
using BuilderTaskBase<nodes::Loop>::BuilderTaskBase;
nodes::Loop operator()(const ParserNode &parser_node,
const Arguments &args) override;
};
// --- operators
template <>
struct BuilderTask<nodes::NameExpression, utils::CommaTag>
: public BuilderTaskBase<nodes::NameExpression> {
using BuilderTaskBase<nodes::NameExpression>::BuilderTaskBase;
nodes::NameExpression operator()(const ParserNode &parser_node,
const Arguments &args) override;
};
template <>
struct BuilderTask<nodes::NameExpression, utils::OperatorTag>
: public BuilderTaskBase<nodes::NameExpression> {
using BuilderTaskBase<nodes::NameExpression>::BuilderTaskBase;
nodes::NameExpression operator()(const ParserNode &parser_node,
const Arguments &args) override;
};
// --- continers
template <typename T>
requires std::is_same_v<T, utils::BlockTag> or
std::is_same_v<T, utils::ArrayTag>
struct BuilderTask<nodes::Container, T>
: public BuilderTaskBase<nodes::Container> {
using BuilderTaskBase<nodes::Container>::BuilderTaskBase;
// '{' (expression ';')* '}'
// or
// '[[' expression+ ']]'
nodes::Container operator()(const ParserNode &parser_node,
const Arguments &) override {
const auto container_type = std::is_same_v<T, utils::BlockTag>
? nodes::Container::BLOCK
: nodes::Container::ARRAY;
std::vector<nodes::ExpressionProxy> expressions;
auto current_node = parser_node.nth_named_child(0);
while (!current_node.is_null()) {
expressions.push_back(Run<nodes::ExpressionProxy>(current_node));
current_node = current_node.next_named_sibling();
}
return nodes::Container(build_node(parser_node), container_type,
std::move(expressions));
}
};
// --- modifiers
template <>
struct BuilderTask<nodes::Return> : public BuilderTaskBase<nodes::Return> {
using BuilderTaskBase<nodes::Return>::BuilderTaskBase;
nodes::Return operator()(const ParserNode &parser_node,
const Arguments &args) override;
};
template <>
struct BuilderTask<nodes::NameDefinition>
: public BuilderTaskBase<nodes::NameDefinition> {
using BuilderTaskBase<nodes::NameDefinition>::BuilderTaskBase;
nodes::NameDefinition operator()(const ParserNode &parser_node,
const Arguments &args) override;
};
template <>
struct BuilderTask<nodes::Access, utils::ArrayAccessTag>
: public BuilderTaskBase<nodes::Access> {
using BuilderTaskBase<nodes::Access>::BuilderTaskBase;
nodes::Access operator()(const ParserNode &parser_node,
const Arguments &args) override;
};
template <>
struct BuilderTask<nodes::Access, utils::TupleAccessTag>
: public BuilderTaskBase<nodes::Access> {
using BuilderTaskBase<nodes::Access>::BuilderTaskBase;
nodes::Access operator()(const ParserNode &parser_node,
const Arguments &args) override;
};
template <>
struct BuilderTask<nodes::LoopControl>
: public BuilderTaskBase<nodes::LoopControl> {
using BuilderTaskBase<nodes::LoopControl>::BuilderTaskBase;
nodes::LoopControl operator()(const ParserNode &parser_node,
const Arguments &args) override;
};
template <typename T>
requires std::is_same_v<T, utils::RefTag> or
std::is_same_v<T, utils::SuffixTag>
struct BuilderTask<nodes::ModifierExpression, T>
: public BuilderTaskBase<nodes::ModifierExpression> {
using BuilderTaskBase<nodes::ModifierExpression>::BuilderTaskBase;
// _reference_ expression
// or
// expression ('?' | '!')
nodes::ModifierExpression operator()(const ParserNode &parser_node,
const Arguments &) override {
const size_t modifier_pos =
std::is_same_v<T, utils::RefTag> ? 0 : parser_node.child_count() - 1;
return nodes::ModifierExpression(
build_node(parser_node),
build_modifier(parser_node.nth_child(modifier_pos)),
Run<nodes::ExpressionProxy>(parser_node.nth_named_child(0)));
}
};
// --- other
template <>
struct BuilderTask<nodes::NameExpression, utils::FuncCallTag>
: public BuilderTaskBase<nodes::NameExpression> {
using BuilderTaskBase<nodes::NameExpression>::BuilderTaskBase;
nodes::NameExpression operator()(const ParserNode &parser_node,
const Arguments &args) override;
};
template <>
struct BuilderTask<nodes::Constructor>
: public BuilderTaskBase<nodes::Constructor> {
using BuilderTaskBase<nodes::Constructor>::BuilderTaskBase;
nodes::Constructor operator()(const ParserNode &parser_node,
const Arguments &args) override;
};
template <>
struct BuilderTask<nodes::Lambda> : public BuilderTaskBase<nodes::Lambda> {
using BuilderTaskBase<nodes::Lambda>::BuilderTaskBase;
nodes::Lambda operator()(const ParserNode &parser_node,
const Arguments &args) override;
};
} // namespace builders