mirror of
https://codeberg.org/ProgramSnail/lang.git
synced 2025-12-05 22:48:43 +00:00
217 lines
6.7 KiB
C++
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
|