mirror of
https://codeberg.org/ProgramSnail/lang.git
synced 2025-12-06 15:08:48 +00:00
better expr proxy builder task
This commit is contained in:
parent
f5856734c6
commit
cbbf626232
4 changed files with 217 additions and 189 deletions
|
|
@ -13,6 +13,8 @@ using Names = names::NameTree;
|
||||||
|
|
||||||
using Executor = utils::Executor<Exprs, Types, Names>;
|
using Executor = utils::Executor<Exprs, Types, Names>;
|
||||||
|
|
||||||
|
using ParserNode = parser::ParseTree::Node;
|
||||||
|
|
||||||
using Node = nodes::Node_<nodes::NodePart<utils::Pos>>; // TODO
|
using Node = nodes::Node_<nodes::NodePart<utils::Pos>>; // TODO
|
||||||
|
|
||||||
template <typename N>
|
template <typename N>
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ struct BuilderTask<nodes::ExpressionProxy>
|
||||||
: public BuilderTaskBase<nodes::ExpressionProxy> {
|
: public BuilderTaskBase<nodes::ExpressionProxy> {
|
||||||
using BuilderTaskBase<nodes::ExpressionProxy>::BuilderTaskBase;
|
using BuilderTaskBase<nodes::ExpressionProxy>::BuilderTaskBase;
|
||||||
|
|
||||||
nodes::ExpressionProxy operator()(const parser::ParseTree::Node &parser_node,
|
nodes::ExpressionProxy operator()(const ParserNode &parser_node,
|
||||||
const utils::None &args) override;
|
const utils::None &args) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -37,7 +37,7 @@ struct BuilderTask<nodes::Match::Case>
|
||||||
: public BuilderTaskBase<nodes::Match::Case> {
|
: public BuilderTaskBase<nodes::Match::Case> {
|
||||||
using BuilderTaskBase<nodes::Match::Case>::BuilderTaskBase;
|
using BuilderTaskBase<nodes::Match::Case>::BuilderTaskBase;
|
||||||
|
|
||||||
nodes::Match::Case operator()(const parser::ParseTree::Node &parser_node,
|
nodes::Match::Case operator()(const ParserNode &parser_node,
|
||||||
const utils::None &args) override;
|
const utils::None &args) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -45,7 +45,7 @@ template <>
|
||||||
struct BuilderTask<nodes::Match> : public BuilderTaskBase<nodes::Match> {
|
struct BuilderTask<nodes::Match> : public BuilderTaskBase<nodes::Match> {
|
||||||
using BuilderTaskBase<nodes::Match>::BuilderTaskBase;
|
using BuilderTaskBase<nodes::Match>::BuilderTaskBase;
|
||||||
|
|
||||||
nodes::Match operator()(const parser::ParseTree::Node &parser_node,
|
nodes::Match operator()(const ParserNode &parser_node,
|
||||||
const utils::None &args) override;
|
const utils::None &args) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -54,7 +54,7 @@ struct BuilderTask<nodes::Condition>
|
||||||
: public BuilderTaskBase<nodes::Condition> {
|
: public BuilderTaskBase<nodes::Condition> {
|
||||||
using BuilderTaskBase<nodes::Condition>::BuilderTaskBase;
|
using BuilderTaskBase<nodes::Condition>::BuilderTaskBase;
|
||||||
|
|
||||||
nodes::Condition operator()(const parser::ParseTree::Node &parser_node,
|
nodes::Condition operator()(const ParserNode &parser_node,
|
||||||
const utils::None &args) override;
|
const utils::None &args) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -62,7 +62,7 @@ template <>
|
||||||
struct BuilderTask<nodes::Loop> : public BuilderTaskBase<nodes::Loop> {
|
struct BuilderTask<nodes::Loop> : public BuilderTaskBase<nodes::Loop> {
|
||||||
using BuilderTaskBase<nodes::Loop>::BuilderTaskBase;
|
using BuilderTaskBase<nodes::Loop>::BuilderTaskBase;
|
||||||
|
|
||||||
nodes::Loop operator()(const parser::ParseTree::Node &parser_node,
|
nodes::Loop operator()(const ParserNode &parser_node,
|
||||||
const utils::None &args) override;
|
const utils::None &args) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -73,7 +73,7 @@ struct BuilderTask<nodes::NameExpression, utils::CommaTag>
|
||||||
: public BuilderTaskBase<nodes::NameExpression> {
|
: public BuilderTaskBase<nodes::NameExpression> {
|
||||||
using BuilderTaskBase<nodes::NameExpression>::BuilderTaskBase;
|
using BuilderTaskBase<nodes::NameExpression>::BuilderTaskBase;
|
||||||
|
|
||||||
nodes::NameExpression operator()(const parser::ParseTree::Node &parser_node,
|
nodes::NameExpression operator()(const ParserNode &parser_node,
|
||||||
const utils::None &args) override;
|
const utils::None &args) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -82,7 +82,7 @@ struct BuilderTask<nodes::NameExpression, utils::OperatorTag>
|
||||||
: public BuilderTaskBase<nodes::NameExpression> {
|
: public BuilderTaskBase<nodes::NameExpression> {
|
||||||
using BuilderTaskBase<nodes::NameExpression>::BuilderTaskBase;
|
using BuilderTaskBase<nodes::NameExpression>::BuilderTaskBase;
|
||||||
|
|
||||||
nodes::NameExpression operator()(const parser::ParseTree::Node &parser_node,
|
nodes::NameExpression operator()(const ParserNode &parser_node,
|
||||||
const utils::None &args) override;
|
const utils::None &args) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -98,7 +98,7 @@ struct BuilderTask<nodes::Container, T>
|
||||||
// '{' (expression ';')* '}'
|
// '{' (expression ';')* '}'
|
||||||
// or
|
// or
|
||||||
// '[[' expression+ ']]'
|
// '[[' expression+ ']]'
|
||||||
nodes::Container operator()(const parser::ParseTree::Node &parser_node,
|
nodes::Container operator()(const ParserNode &parser_node,
|
||||||
const utils::None &) override {
|
const utils::None &) override {
|
||||||
const auto container_type = std::is_same_v<T, utils::BlockTag>
|
const auto container_type = std::is_same_v<T, utils::BlockTag>
|
||||||
? nodes::Container::BLOCK
|
? nodes::Container::BLOCK
|
||||||
|
|
@ -124,7 +124,7 @@ template <>
|
||||||
struct BuilderTask<nodes::Return> : public BuilderTaskBase<nodes::Return> {
|
struct BuilderTask<nodes::Return> : public BuilderTaskBase<nodes::Return> {
|
||||||
using BuilderTaskBase<nodes::Return>::BuilderTaskBase;
|
using BuilderTaskBase<nodes::Return>::BuilderTaskBase;
|
||||||
|
|
||||||
nodes::Return operator()(const parser::ParseTree::Node &parser_node,
|
nodes::Return operator()(const ParserNode &parser_node,
|
||||||
const utils::None &args) override;
|
const utils::None &args) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -133,7 +133,7 @@ struct BuilderTask<nodes::NameDefinition>
|
||||||
: public BuilderTaskBase<nodes::NameDefinition> {
|
: public BuilderTaskBase<nodes::NameDefinition> {
|
||||||
using BuilderTaskBase<nodes::NameDefinition>::BuilderTaskBase;
|
using BuilderTaskBase<nodes::NameDefinition>::BuilderTaskBase;
|
||||||
|
|
||||||
nodes::NameDefinition operator()(const parser::ParseTree::Node &parser_node,
|
nodes::NameDefinition operator()(const ParserNode &parser_node,
|
||||||
const utils::None &args) override;
|
const utils::None &args) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -142,7 +142,7 @@ struct BuilderTask<nodes::Access, utils::ArrayAccessTag>
|
||||||
: public BuilderTaskBase<nodes::Access> {
|
: public BuilderTaskBase<nodes::Access> {
|
||||||
using BuilderTaskBase<nodes::Access>::BuilderTaskBase;
|
using BuilderTaskBase<nodes::Access>::BuilderTaskBase;
|
||||||
|
|
||||||
nodes::Access operator()(const parser::ParseTree::Node &parser_node,
|
nodes::Access operator()(const ParserNode &parser_node,
|
||||||
const utils::None &args) override;
|
const utils::None &args) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -151,7 +151,7 @@ struct BuilderTask<nodes::Access, utils::TupleAccessTag>
|
||||||
: public BuilderTaskBase<nodes::Access> {
|
: public BuilderTaskBase<nodes::Access> {
|
||||||
using BuilderTaskBase<nodes::Access>::BuilderTaskBase;
|
using BuilderTaskBase<nodes::Access>::BuilderTaskBase;
|
||||||
|
|
||||||
nodes::Access operator()(const parser::ParseTree::Node &parser_node,
|
nodes::Access operator()(const ParserNode &parser_node,
|
||||||
const utils::None &args) override;
|
const utils::None &args) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -160,7 +160,7 @@ struct BuilderTask<nodes::LoopControl>
|
||||||
: public BuilderTaskBase<nodes::LoopControl> {
|
: public BuilderTaskBase<nodes::LoopControl> {
|
||||||
using BuilderTaskBase<nodes::LoopControl>::BuilderTaskBase;
|
using BuilderTaskBase<nodes::LoopControl>::BuilderTaskBase;
|
||||||
|
|
||||||
nodes::LoopControl operator()(const parser::ParseTree::Node &parser_node,
|
nodes::LoopControl operator()(const ParserNode &parser_node,
|
||||||
const utils::None &args) override;
|
const utils::None &args) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -169,8 +169,7 @@ struct BuilderTask<nodes::ModifierExpression, utils::RefTag>
|
||||||
: public BuilderTaskBase<nodes::ModifierExpression> {
|
: public BuilderTaskBase<nodes::ModifierExpression> {
|
||||||
using BuilderTaskBase<nodes::ModifierExpression>::BuilderTaskBase;
|
using BuilderTaskBase<nodes::ModifierExpression>::BuilderTaskBase;
|
||||||
|
|
||||||
nodes::ModifierExpression
|
nodes::ModifierExpression operator()(const ParserNode &parser_node,
|
||||||
operator()(const parser::ParseTree::Node &parser_node,
|
|
||||||
const utils::None &args) override;
|
const utils::None &args) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -179,8 +178,7 @@ struct BuilderTask<nodes::ModifierExpression, utils::SuffixTag>
|
||||||
: public BuilderTaskBase<nodes::ModifierExpression> {
|
: public BuilderTaskBase<nodes::ModifierExpression> {
|
||||||
using BuilderTaskBase<nodes::ModifierExpression>::BuilderTaskBase;
|
using BuilderTaskBase<nodes::ModifierExpression>::BuilderTaskBase;
|
||||||
|
|
||||||
nodes::ModifierExpression
|
nodes::ModifierExpression operator()(const ParserNode &parser_node,
|
||||||
operator()(const parser::ParseTree::Node &parser_node,
|
|
||||||
const utils::None &args) override;
|
const utils::None &args) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -194,8 +192,7 @@ struct BuilderTask<nodes::ModifierExpression, T>
|
||||||
// _reference_ expression
|
// _reference_ expression
|
||||||
// or
|
// or
|
||||||
// expression ('?' | '!')
|
// expression ('?' | '!')
|
||||||
nodes::ModifierExpression
|
nodes::ModifierExpression operator()(const ParserNode &parser_node,
|
||||||
operator()(const parser::ParseTree::Node &parser_node,
|
|
||||||
const utils::None &) override {
|
const utils::None &) 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;
|
||||||
|
|
@ -214,7 +211,7 @@ struct BuilderTask<nodes::NameExpression, utils::FuncCallTag>
|
||||||
: public BuilderTaskBase<nodes::NameExpression> {
|
: public BuilderTaskBase<nodes::NameExpression> {
|
||||||
using BuilderTaskBase<nodes::NameExpression>::BuilderTaskBase;
|
using BuilderTaskBase<nodes::NameExpression>::BuilderTaskBase;
|
||||||
|
|
||||||
nodes::NameExpression operator()(const parser::ParseTree::Node &parser_node,
|
nodes::NameExpression operator()(const ParserNode &parser_node,
|
||||||
const utils::None &args) override;
|
const utils::None &args) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -223,7 +220,7 @@ struct BuilderTask<nodes::Constructor>
|
||||||
: public BuilderTaskBase<nodes::Constructor> {
|
: public BuilderTaskBase<nodes::Constructor> {
|
||||||
using BuilderTaskBase<nodes::Constructor>::BuilderTaskBase;
|
using BuilderTaskBase<nodes::Constructor>::BuilderTaskBase;
|
||||||
|
|
||||||
nodes::Constructor operator()(const parser::ParseTree::Node &parser_node,
|
nodes::Constructor operator()(const ParserNode &parser_node,
|
||||||
const utils::None &args) override;
|
const utils::None &args) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -231,7 +228,7 @@ template <>
|
||||||
struct BuilderTask<nodes::Lambda> : public BuilderTaskBase<nodes::Lambda> {
|
struct BuilderTask<nodes::Lambda> : public BuilderTaskBase<nodes::Lambda> {
|
||||||
using BuilderTaskBase<nodes::Lambda>::BuilderTaskBase;
|
using BuilderTaskBase<nodes::Lambda>::BuilderTaskBase;
|
||||||
|
|
||||||
nodes::Lambda operator()(const parser::ParseTree::Node &parser_node,
|
nodes::Lambda operator()(const ParserNode &parser_node,
|
||||||
const utils::None &args) override;
|
const utils::None &args) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,9 @@
|
||||||
|
|
||||||
namespace builders {
|
namespace builders {
|
||||||
|
|
||||||
nodes::ExpressionProxy BuilderTask<nodes::ExpressionProxy>::operator()(
|
nodes::ExpressionProxy
|
||||||
const parser::ParseTree::Node &parser_node, const utils::None &) {
|
BuilderTask<nodes::ExpressionProxy>::operator()(const ParserNode &parser_node,
|
||||||
|
const utils::None &) {
|
||||||
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();
|
||||||
|
|
@ -19,150 +20,141 @@ nodes::ExpressionProxy BuilderTask<nodes::ExpressionProxy>::operator()(
|
||||||
(!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::Expression::Type> expr;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
// --- flow control
|
// --- flow control
|
||||||
case tokens::Type::MATCH:
|
case tokens::Type::MATCH:
|
||||||
return state<Exprs>().add_expression(nodes::Expression(
|
expr = Run<nodes::Match>(parser_node);
|
||||||
build_node(parser_node), Run<nodes::Match>(parser_node), is_scoped));
|
break;
|
||||||
case tokens::Type::CONDITION:
|
case tokens::Type::CONDITION:
|
||||||
return state<Exprs>().add_expression(
|
return state<Exprs>().add_expression({build_node(parser_node),
|
||||||
nodes::Expression(build_node(parser_node),
|
Run<nodes::Condition>(parser_node),
|
||||||
Run<nodes::Condition>(parser_node), is_scoped));
|
is_scoped});
|
||||||
|
expr = Run<nodes::Match>(parser_node);
|
||||||
|
break;
|
||||||
case tokens::Type::LOOP:
|
case tokens::Type::LOOP:
|
||||||
return state<Exprs>().add_expression(nodes::Expression(
|
return state<Exprs>().add_expression(
|
||||||
build_node(parser_node), 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:
|
||||||
return state<Exprs>().add_expression(nodes::Expression(
|
expr = Run<nodes::NameExpression, utils::CommaTag>(parser_node);
|
||||||
build_node(parser_node),
|
break;
|
||||||
Run<nodes::NameExpression, utils::CommaTag>(parser_node), is_scoped));
|
|
||||||
case tokens::Type::OPERATOR_EXPRESSION:
|
case tokens::Type::OPERATOR_EXPRESSION:
|
||||||
return state<Exprs>().add_expression(nodes::Expression(
|
expr = Run<nodes::NameExpression, utils::OperatorTag>(parser_node);
|
||||||
build_node(parser_node),
|
break;
|
||||||
Run<nodes::NameExpression, utils::OperatorTag>(parser_node),
|
|
||||||
is_scoped));
|
|
||||||
// --- containers
|
// --- containers
|
||||||
case tokens::Type::BLOCK:
|
case tokens::Type::BLOCK:
|
||||||
return state<Exprs>().add_expression(nodes::Expression(
|
expr = Run<nodes::Container, utils::BlockTag>(parser_node);
|
||||||
build_node(parser_node),
|
break;
|
||||||
Run<nodes::Container, utils::BlockTag>(parser_node), is_scoped));
|
|
||||||
case tokens::Type::ARRAY:
|
case tokens::Type::ARRAY:
|
||||||
return state<Exprs>().add_expression(nodes::Expression(
|
expr = Run<nodes::Container, utils::ArrayTag>(parser_node);
|
||||||
build_node(parser_node),
|
break;
|
||||||
Run<nodes::Container, utils::ArrayTag>(parser_node), is_scoped));
|
|
||||||
// --- modifiers
|
// --- modifiers
|
||||||
case tokens::Type::RETURN:
|
case tokens::Type::RETURN:
|
||||||
return state<Exprs>().add_expression(nodes::Expression(
|
expr = Run<nodes::Return>(parser_node);
|
||||||
build_node(parser_node), Run<nodes::Return>(parser_node), is_scoped));
|
break;
|
||||||
case tokens::Type::NAME_DEFINITION:
|
case tokens::Type::NAME_DEFINITION:
|
||||||
return state<Exprs>().add_expression(
|
expr = Run<nodes::NameDefinition>(parser_node);
|
||||||
nodes::Expression(build_node(parser_node),
|
break;
|
||||||
Run<nodes::NameDefinition>(parser_node), is_scoped));
|
|
||||||
case tokens::Type::ARRAY_ACCESS:
|
case tokens::Type::ARRAY_ACCESS:
|
||||||
return state<Exprs>().add_expression(nodes::Expression(
|
expr = Run<nodes::Access, utils::ArrayAccessTag>(parser_node);
|
||||||
build_node(parser_node),
|
break;
|
||||||
Run<nodes::Access, utils::ArrayAccessTag>(parser_node), is_scoped));
|
|
||||||
case tokens::Type::TUPLE_ACCESS:
|
case tokens::Type::TUPLE_ACCESS:
|
||||||
return state<Exprs>().add_expression(nodes::Expression(
|
expr = Run<nodes::Access, utils::TupleAccessTag>(parser_node);
|
||||||
build_node(parser_node),
|
break;
|
||||||
Run<nodes::Access, utils::TupleAccessTag>(parser_node), is_scoped));
|
|
||||||
case tokens::Type::LOOP_CONTROL:
|
case tokens::Type::LOOP_CONTROL:
|
||||||
return state<Exprs>().add_expression(
|
expr = Run<nodes::LoopControl>(parser_node);
|
||||||
nodes::Expression(build_node(parser_node),
|
break;
|
||||||
Run<nodes::LoopControl>(parser_node), is_scoped));
|
|
||||||
case tokens::Type::REFERENCE_EXPRESSION:
|
case tokens::Type::REFERENCE_EXPRESSION:
|
||||||
return state<Exprs>().add_expression(nodes::Expression(
|
expr = Run<nodes::ModifierExpression, utils::RefTag>(parser_node);
|
||||||
build_node(parser_node),
|
break;
|
||||||
Run<nodes::ModifierExpression, utils::RefTag>(parser_node), is_scoped));
|
|
||||||
case tokens::Type::SUFFIX_EXPRESSION:
|
case tokens::Type::SUFFIX_EXPRESSION:
|
||||||
return state<Exprs>().add_expression(nodes::Expression(
|
expr = Run<nodes::ModifierExpression, utils::SuffixTag>(parser_node);
|
||||||
build_node(parser_node),
|
break;
|
||||||
Run<nodes::ModifierExpression, utils::SuffixTag>(parser_node),
|
|
||||||
is_scoped));
|
|
||||||
// --- other
|
// --- other
|
||||||
case tokens::Type::NAME_EXPRESSION:
|
case tokens::Type::NAME_EXPRESSION:
|
||||||
return state<Exprs>().add_expression(nodes::Expression(
|
expr = Run<nodes::NameExpression, utils::FuncCallTag>(parser_node);
|
||||||
build_node(parser_node),
|
break;
|
||||||
Run<nodes::NameExpression, utils::FuncCallTag>(parser_node),
|
|
||||||
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:
|
||||||
return state<Exprs>().add_expression(
|
expr = nodes::NameExpression(build_node(parser_node),
|
||||||
nodes::Expression(build_node(parser_node),
|
build_identifier(parser_node));
|
||||||
nodes::NameExpression(build_node(parser_node),
|
break;
|
||||||
build_identifier(parser_node)),
|
|
||||||
is_scoped));
|
|
||||||
case tokens::Type::CONSTRUCTOR:
|
case tokens::Type::CONSTRUCTOR:
|
||||||
return state<Exprs>().add_expression(
|
expr = Run<nodes::Constructor>(parser_node);
|
||||||
nodes::Expression(build_node(parser_node),
|
break;
|
||||||
Run<nodes::Constructor>(parser_node), is_scoped));
|
|
||||||
case tokens::Type::LAMBDA:
|
case tokens::Type::LAMBDA:
|
||||||
return state<Exprs>().add_expression(nodes::Expression(
|
expr = Run<nodes::Lambda>(parser_node);
|
||||||
build_node(parser_node), Run<nodes::Lambda>(parser_node), is_scoped));
|
break;
|
||||||
// --- literals
|
// --- literals
|
||||||
case tokens::Type::FLOAT_LITERAL:
|
case tokens::Type::FLOAT_LITERAL:
|
||||||
return state<Exprs>().add_expression(nodes::Expression(
|
expr = build_float_literal(parser_node);
|
||||||
build_node(parser_node), build_float_literal(parser_node), is_scoped));
|
break;
|
||||||
case tokens::Type::DOUBLE_LITERAL:
|
case tokens::Type::DOUBLE_LITERAL:
|
||||||
return state<Exprs>().add_expression(nodes::Expression(
|
expr = build_double_literal(parser_node);
|
||||||
build_node(parser_node), build_double_literal(parser_node), is_scoped));
|
break;
|
||||||
case tokens::Type::INT_LITERAL:
|
case tokens::Type::INT_LITERAL:
|
||||||
return state<Exprs>().add_expression(nodes::Expression(
|
expr = build_int_literal(parser_node);
|
||||||
build_node(parser_node), build_int_literal(parser_node), is_scoped));
|
break;
|
||||||
case tokens::Type::LONG_LITERAL:
|
case tokens::Type::LONG_LITERAL:
|
||||||
return state<Exprs>().add_expression(nodes::Expression(
|
expr = build_long_literal(parser_node);
|
||||||
build_node(parser_node), build_long_literal(parser_node), is_scoped));
|
break;
|
||||||
case tokens::Type::INDEX_LITERAL:
|
case tokens::Type::INDEX_LITERAL:
|
||||||
return state<Exprs>().add_expression(nodes::Expression(
|
expr = build_index_literal(parser_node);
|
||||||
build_node(parser_node), build_index_literal(parser_node), is_scoped));
|
break;
|
||||||
case tokens::Type::STRING_LITERAL:
|
case tokens::Type::STRING_LITERAL:
|
||||||
return state<Exprs>().add_expression(nodes::Expression(
|
expr = build_string_literal(parser_node);
|
||||||
build_node(parser_node), build_string_literal(parser_node), is_scoped));
|
break;
|
||||||
case tokens::Type::UNICODE_STRING_LITERAL:
|
case tokens::Type::UNICODE_STRING_LITERAL:
|
||||||
return state<Exprs>().add_expression(nodes::Expression(
|
expr = build_unicode_string_literal(parser_node);
|
||||||
build_node(parser_node), build_unicode_string_literal(parser_node),
|
break;
|
||||||
is_scoped));
|
|
||||||
case tokens::Type::CHAR_LITERAL:
|
case tokens::Type::CHAR_LITERAL:
|
||||||
return state<Exprs>().add_expression(nodes::Expression(
|
expr = build_char_literal(parser_node);
|
||||||
build_node(parser_node), build_char_literal(parser_node), is_scoped));
|
break;
|
||||||
case tokens::Type::UNICODE_LITERAL:
|
case tokens::Type::UNICODE_LITERAL:
|
||||||
return state<Exprs>().add_expression(
|
expr = build_unicode_literal(parser_node);
|
||||||
nodes::Expression(build_node(parser_node),
|
break;
|
||||||
build_unicode_literal(parser_node), is_scoped));
|
|
||||||
case tokens::Type::BOOL_LITERAL:
|
case tokens::Type::BOOL_LITERAL:
|
||||||
return state<Exprs>().add_expression(nodes::Expression(
|
expr = build_bool_literal(parser_node);
|
||||||
build_node(parser_node), build_bool_literal(parser_node), is_scoped));
|
break;
|
||||||
case tokens::Type::UNIT_LITERAL:
|
case tokens::Type::UNIT_LITERAL:
|
||||||
return state<Exprs>().add_expression(nodes::Expression(
|
expr = build_unit_literal(parser_node);
|
||||||
build_node(parser_node), build_unit_literal(parser_node), is_scoped));
|
break;
|
||||||
case tokens::Type::NULL_LITERAL:
|
case tokens::Type::NULL_LITERAL:
|
||||||
return state<Exprs>().add_expression(nodes::Expression(
|
expr = build_null_literal(parser_node);
|
||||||
build_node(parser_node), build_null_literal(parser_node), is_scoped));
|
break;
|
||||||
case tokens::Type::EXTRA:
|
case tokens::Type::EXTRA:
|
||||||
return state<Exprs>().add_expression(nodes::Expression(
|
expr = build_extra(parser_node);
|
||||||
build_node(parser_node), build_extra(parser_node), is_scoped));
|
break;
|
||||||
case tokens::Type::EMPTY_LINES:
|
case tokens::Type::EMPTY_LINES:
|
||||||
return state<Exprs>().add_expression(nodes::Expression(
|
expr = build_empty_lines(parser_node);
|
||||||
build_node(parser_node), build_empty_lines(parser_node), is_scoped));
|
break;
|
||||||
default:
|
default:
|
||||||
error_handling::handle_parsing_error("Unexprected expression node type",
|
utils::Assert(true,
|
||||||
parser_node);
|
std::format("Unexpected expression node type {}",
|
||||||
|
static_cast<int>(type))); // TODO: magic_enum
|
||||||
|
// FIXME: change to fatal error ?
|
||||||
}
|
}
|
||||||
|
|
||||||
error_handling::handle_general_error("Unreachable");
|
utils::Assert(expr.has_value(), "Expression should have value");
|
||||||
exit(1); // unreachable
|
|
||||||
|
return state<Exprs>().add_expression(
|
||||||
|
{build_node(parser_node), expr.value(), is_scoped});
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- flow control
|
// --- flow control
|
||||||
|
|
||||||
// (':=' | '=:') expression (('??' | 'if') expression)? (_do_ expression)?
|
// (':=' | '=:') expression (('??' | 'if') expression)? (_do_ expression)?
|
||||||
nodes::Match::Case BuilderTask<nodes::Match::Case>::operator()(
|
nodes::Match::Case
|
||||||
const parser::ParseTree::Node &parser_node, const utils::None &) {
|
BuilderTask<nodes::Match::Case>::operator()(const ParserNode &parser_node,
|
||||||
|
const utils::None &) {
|
||||||
std::string case_type = parser_node.nth_child(0).get_value();
|
std::string case_type = parser_node.nth_child(0).get_value();
|
||||||
|
|
||||||
std::optional<parser::ParseTree::Node> condition_node;
|
std::optional<ParserNode> condition_node;
|
||||||
std::optional<parser::ParseTree::Node> expression_node;
|
std::optional<ParserNode> expression_node;
|
||||||
|
|
||||||
auto current_node = parser_node.nth_named_child(1);
|
auto current_node = parser_node.nth_named_child(1);
|
||||||
|
|
||||||
|
|
@ -192,8 +184,9 @@ nodes::Match::Case BuilderTask<nodes::Match::Case>::operator()(
|
||||||
}
|
}
|
||||||
|
|
||||||
// expression case+
|
// expression case+
|
||||||
nodes::Match BuilderTask<nodes::Match>::operator()(
|
nodes::Match
|
||||||
const parser::ParseTree::Node &parser_node, const utils::None &) {
|
BuilderTask<nodes::Match>::operator()(const ParserNode &parser_node,
|
||||||
|
const utils::None &) {
|
||||||
std::vector<nodes::Match::Case> cases;
|
std::vector<nodes::Match::Case> cases;
|
||||||
|
|
||||||
auto current_node = parser_node.nth_named_child(1);
|
auto current_node = parser_node.nth_named_child(1);
|
||||||
|
|
@ -210,8 +203,9 @@ nodes::Match BuilderTask<nodes::Match>::operator()(
|
||||||
|
|
||||||
// ('??' | 'if') expression _do_ expression (('!!' | 'elif') expression _do_
|
// ('??' | 'if') expression _do_ expression (('!!' | 'elif') expression _do_
|
||||||
// expression)* (('!!=>', 'else') expression)?
|
// expression)* (('!!=>', 'else') expression)?
|
||||||
nodes::Condition BuilderTask<nodes::Condition>::operator()(
|
nodes::Condition
|
||||||
const parser::ParseTree::Node &parser_node, const utils::None &) {
|
BuilderTask<nodes::Condition>::operator()(const ParserNode &parser_node,
|
||||||
|
const utils::None &) {
|
||||||
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::ExpressionProxy, nodes::ExpressionProxy>> cases;
|
std::vector<std::pair<nodes::ExpressionProxy, nodes::ExpressionProxy>> cases;
|
||||||
|
|
@ -238,8 +232,7 @@ nodes::Condition BuilderTask<nodes::Condition>::operator()(
|
||||||
}
|
}
|
||||||
|
|
||||||
// ('@' | 'for') (expression | expression ':' expression)? _do_ expression
|
// ('@' | 'for') (expression | expression ':' expression)? _do_ expression
|
||||||
nodes::Loop
|
nodes::Loop BuilderTask<nodes::Loop>::operator()(const ParserNode &parser_node,
|
||||||
BuilderTask<nodes::Loop>::operator()(const parser::ParseTree::Node &parser_node,
|
|
||||||
const utils::None &) {
|
const utils::None &) {
|
||||||
size_t named_child_count = parser_node.named_child_count();
|
size_t named_child_count = parser_node.named_child_count();
|
||||||
|
|
||||||
|
|
@ -247,23 +240,40 @@ BuilderTask<nodes::Loop>::operator()(const parser::ParseTree::Node &parser_node,
|
||||||
return nodes::Loop(
|
return nodes::Loop(
|
||||||
build_node(parser_node),
|
build_node(parser_node),
|
||||||
Run<nodes::ExpressionProxy>(parser_node.nth_named_child(0)));
|
Run<nodes::ExpressionProxy>(parser_node.nth_named_child(0)));
|
||||||
} else if (named_child_count == 2) { // condition, body
|
} else if (named_child_count == 2) { // condition,
|
||||||
|
// body
|
||||||
return nodes::Loop(
|
return nodes::Loop(
|
||||||
build_node(parser_node),
|
build_node(parser_node),
|
||||||
Run<nodes::ExpressionProxy>(parser_node.nth_named_child(0)),
|
Run<nodes::ExpressionProxy>(parser_node.nth_named_child(0)),
|
||||||
Run<nodes::ExpressionProxy>(parser_node.nth_named_child(1)));
|
Run<nodes::ExpressionProxy>(parser_node.nth_named_child(1)));
|
||||||
} else if (named_child_count == 3) { // variable, interval, body
|
} else if (named_child_count == 3) { // variable,
|
||||||
|
// interval,
|
||||||
|
// body
|
||||||
return nodes::Loop(
|
return nodes::Loop(
|
||||||
build_node(parser_node),
|
build_node(parser_node),
|
||||||
Run<nodes::ExpressionProxy>(parser_node.nth_named_child(0)),
|
Run<nodes::ExpressionProxy>(parser_node.nth_named_child(0)),
|
||||||
Run<nodes::ExpressionProxy>(parser_node.nth_named_child(1)),
|
Run<nodes::ExpressionProxy>(parser_node.nth_named_child(1)),
|
||||||
Run<nodes::ExpressionProxy>(parser_node.nth_named_child(2)));
|
Run<nodes::ExpressionProxy>(parser_node.nth_named_child(2)));
|
||||||
} else {
|
} else {
|
||||||
error_handling::handle_parsing_error(
|
error_handling::handle_parsing_error("Unex"
|
||||||
"Unexprected named expression amount in loop", parser_node);
|
"prec"
|
||||||
|
"ted "
|
||||||
|
"name"
|
||||||
|
"d "
|
||||||
|
"expr"
|
||||||
|
"essi"
|
||||||
|
"on "
|
||||||
|
"amou"
|
||||||
|
"nt "
|
||||||
|
"in "
|
||||||
|
"loo"
|
||||||
|
"p",
|
||||||
|
parser_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
error_handling::handle_general_error("Unreachable");
|
error_handling::handle_general_error("Unreac"
|
||||||
|
"habl"
|
||||||
|
"e");
|
||||||
exit(1); // unreachable
|
exit(1); // unreachable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -272,7 +282,7 @@ BuilderTask<nodes::Loop>::operator()(const parser::ParseTree::Node &parser_node,
|
||||||
// expression ',' expression
|
// expression ',' expression
|
||||||
nodes::NameExpression
|
nodes::NameExpression
|
||||||
BuilderTask<nodes::NameExpression, utils::CommaTag>::operator()(
|
BuilderTask<nodes::NameExpression, utils::CommaTag>::operator()(
|
||||||
const parser::ParseTree::Node &parser_node, const utils::None &) {
|
const ParserNode &parser_node, const utils::None &) {
|
||||||
std::vector<std::pair<std::optional<std::string>, nodes::ExpressionProxy>>
|
std::vector<std::pair<std::optional<std::string>, nodes::ExpressionProxy>>
|
||||||
arguments;
|
arguments;
|
||||||
|
|
||||||
|
|
@ -293,8 +303,10 @@ BuilderTask<nodes::NameExpression, utils::CommaTag>::operator()(
|
||||||
// expression operator expression
|
// expression operator expression
|
||||||
nodes::NameExpression
|
nodes::NameExpression
|
||||||
BuilderTask<nodes::NameExpression, utils::OperatorTag>::operator()(
|
BuilderTask<nodes::NameExpression, utils::OperatorTag>::operator()(
|
||||||
const parser::ParseTree::Node &parser_node, const utils::None &) {
|
const ParserNode &parser_node, const utils::None &) {
|
||||||
auto name_node = parser_node.child_by_field_name("name");
|
auto name_node = parser_node.child_by_field_name("na"
|
||||||
|
"m"
|
||||||
|
"e");
|
||||||
|
|
||||||
std::vector<std::pair<std::optional<std::string>, nodes::ExpressionProxy>>
|
std::vector<std::pair<std::optional<std::string>, nodes::ExpressionProxy>>
|
||||||
arguments;
|
arguments;
|
||||||
|
|
@ -317,19 +329,25 @@ BuilderTask<nodes::NameExpression, utils::OperatorTag>::operator()(
|
||||||
// --- modifiers
|
// --- modifiers
|
||||||
|
|
||||||
// ('return' | 'bring') expression
|
// ('return' | 'bring') expression
|
||||||
nodes::Return BuilderTask<nodes::Return>::operator()(
|
nodes::Return
|
||||||
const parser::ParseTree::Node &parser_node, const utils::None &) {
|
BuilderTask<nodes::Return>::operator()(const ParserNode &parser_node,
|
||||||
|
const utils::None &) {
|
||||||
std::string modifier = parser_node.nth_child(0).get_value();
|
std::string modifier = parser_node.nth_child(0).get_value();
|
||||||
|
|
||||||
return nodes::Return(
|
return nodes::Return(
|
||||||
build_node(parser_node),
|
build_node(parser_node),
|
||||||
modifier == "return" ? nodes::Return::RETURN : nodes::Return::BRING,
|
modifier == "re"
|
||||||
|
"tu"
|
||||||
|
"rn"
|
||||||
|
? nodes::Return::RETURN
|
||||||
|
: nodes::Return::BRING,
|
||||||
Run<nodes::ExpressionProxy>(parser_node.nth_named_child(0)));
|
Run<nodes::ExpressionProxy>(parser_node.nth_named_child(0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// _var_let_ (simple_name_identifier | placeholder)
|
// _var_let_ (simple_name_identifier | placeholder)
|
||||||
nodes::NameDefinition BuilderTask<nodes::NameDefinition>::operator()(
|
nodes::NameDefinition
|
||||||
const parser::ParseTree::Node &parser_node, const utils::None &) {
|
BuilderTask<nodes::NameDefinition>::operator()(const ParserNode &parser_node,
|
||||||
|
const utils::None &) {
|
||||||
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);
|
||||||
|
|
@ -343,7 +361,7 @@ nodes::NameDefinition BuilderTask<nodes::NameDefinition>::operator()(
|
||||||
|
|
||||||
// expression '[' expression ']'
|
// expression '[' expression ']'
|
||||||
nodes::Access BuilderTask<nodes::Access, utils::ArrayAccessTag>::operator()(
|
nodes::Access BuilderTask<nodes::Access, utils::ArrayAccessTag>::operator()(
|
||||||
const parser::ParseTree::Node &parser_node, const utils::None &) {
|
const ParserNode &parser_node, const utils::None &) {
|
||||||
return nodes::Access(
|
return nodes::Access(
|
||||||
build_node(parser_node), nodes::Access::ARRAY,
|
build_node(parser_node), nodes::Access::ARRAY,
|
||||||
Run<nodes::ExpressionProxy>(parser_node.nth_named_child(0)),
|
Run<nodes::ExpressionProxy>(parser_node.nth_named_child(0)),
|
||||||
|
|
@ -352,20 +370,23 @@ nodes::Access BuilderTask<nodes::Access, utils::ArrayAccessTag>::operator()(
|
||||||
|
|
||||||
// expression '.' number_literal
|
// expression '.' number_literal
|
||||||
nodes::Access BuilderTask<nodes::Access, utils::TupleAccessTag>::operator()(
|
nodes::Access BuilderTask<nodes::Access, utils::TupleAccessTag>::operator()(
|
||||||
const parser::ParseTree::Node &parser_node, const utils::None &) {
|
const ParserNode &parser_node, const utils::None &) {
|
||||||
return nodes::Access(
|
return nodes::Access(
|
||||||
build_node(parser_node), nodes::Access::TUPLE,
|
build_node(parser_node), nodes::Access::TUPLE,
|
||||||
Run<nodes::ExpressionProxy>(parser_node.nth_named_child(0)),
|
Run<nodes::ExpressionProxy>(parser_node.nth_named_child(0)),
|
||||||
state<Exprs>().add_expression(nodes::Expression(
|
state<Exprs>().add_expression(
|
||||||
build_node(parser_node.nth_named_child(1)),
|
{build_node(parser_node.nth_named_child(1)),
|
||||||
build_index_literal(parser_node.nth_named_child(1)), false)));
|
build_index_literal(parser_node.nth_named_child(1)), false}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 'break' | 'continue'
|
// 'break' | 'continue'
|
||||||
nodes::LoopControl BuilderTask<nodes::LoopControl>::operator()(
|
nodes::LoopControl
|
||||||
const parser::ParseTree::Node &parser_node, const utils::None &) {
|
BuilderTask<nodes::LoopControl>::operator()(const ParserNode &parser_node,
|
||||||
|
const utils::None &) {
|
||||||
return nodes::LoopControl(build_node(parser_node),
|
return nodes::LoopControl(build_node(parser_node),
|
||||||
parser_node.get_value() == "break"
|
parser_node.get_value() == "br"
|
||||||
|
"ea"
|
||||||
|
"k"
|
||||||
? nodes::LoopControl::BREAK
|
? nodes::LoopControl::BREAK
|
||||||
: nodes::LoopControl::CONTINUE);
|
: nodes::LoopControl::CONTINUE);
|
||||||
}
|
}
|
||||||
|
|
@ -375,9 +396,8 @@ nodes::LoopControl BuilderTask<nodes::LoopControl>::operator()(
|
||||||
// --- other
|
// --- other
|
||||||
|
|
||||||
void build_arguments_until_end(
|
void build_arguments_until_end(
|
||||||
parser::ParseTree::Node first_parse_node, Executor &executor,
|
ParserNode first_parse_node, Executor &executor,
|
||||||
std::vector<nodes::AnnotatedArgument> &arguments) {
|
std::vector<nodes::AnnotatedArgument> &arguments) {
|
||||||
|
|
||||||
auto current_node = first_parse_node;
|
auto current_node = first_parse_node;
|
||||||
|
|
||||||
std::optional<std::string> last_annotation;
|
std::optional<std::string> last_annotation;
|
||||||
|
|
@ -399,16 +419,18 @@ void build_arguments_until_end(
|
||||||
// ')') (annotation? expression)*
|
// ')') (annotation? expression)*
|
||||||
nodes::NameExpression
|
nodes::NameExpression
|
||||||
BuilderTask<nodes::NameExpression, utils::FuncCallTag>::operator()(
|
BuilderTask<nodes::NameExpression, utils::FuncCallTag>::operator()(
|
||||||
const parser::ParseTree::Node &parser_node, const utils::None &) {
|
const ParserNode &parser_node, const utils::None &) {
|
||||||
std::vector<nodes::AnnotatedArgument> arguments;
|
std::vector<nodes::AnnotatedArgument> arguments;
|
||||||
|
|
||||||
std::optional<nodes::Type> prefix;
|
std::optional<nodes::Type> prefix;
|
||||||
|
|
||||||
bool is_point_call = false;
|
bool is_point_call = false;
|
||||||
|
|
||||||
auto name_node = parser_node.child_by_field_name("name");
|
auto name_node = parser_node.child_by_field_name("na"
|
||||||
|
"m"
|
||||||
|
"e");
|
||||||
|
|
||||||
std::optional<parser::ParseTree::Node> prefix_node;
|
std::optional<ParserNode> prefix_node;
|
||||||
|
|
||||||
auto current_node = name_node.previous_named_sibling();
|
auto current_node = name_node.previous_named_sibling();
|
||||||
if (!current_node.is_null()) {
|
if (!current_node.is_null()) {
|
||||||
|
|
@ -442,13 +464,17 @@ BuilderTask<nodes::NameExpression, utils::FuncCallTag>::operator()(
|
||||||
}
|
}
|
||||||
|
|
||||||
// type (annotation? expression)*
|
// type (annotation? expression)*
|
||||||
nodes::Constructor BuilderTask<nodes::Constructor>::operator()(
|
nodes::Constructor
|
||||||
const parser::ParseTree::Node &parser_node, const utils::None &) {
|
BuilderTask<nodes::Constructor>::operator()(const ParserNode &parser_node,
|
||||||
|
const utils::None &) {
|
||||||
std::vector<nodes::AnnotatedArgument> arguments;
|
std::vector<nodes::AnnotatedArgument> arguments;
|
||||||
|
|
||||||
build_arguments_until_end(
|
build_arguments_until_end(parser_node
|
||||||
parser_node.child_by_field_name("type").next_named_sibling(), executor,
|
.child_by_field_name("ty"
|
||||||
arguments);
|
"p"
|
||||||
|
"e")
|
||||||
|
.next_named_sibling(),
|
||||||
|
executor, arguments);
|
||||||
|
|
||||||
return nodes::Constructor(
|
return nodes::Constructor(
|
||||||
build_node(parser_node),
|
build_node(parser_node),
|
||||||
|
|
@ -457,8 +483,9 @@ nodes::Constructor BuilderTask<nodes::Constructor>::operator()(
|
||||||
}
|
}
|
||||||
|
|
||||||
// '\\' argument_name* _do_ expression
|
// '\\' argument_name* _do_ expression
|
||||||
nodes::Lambda BuilderTask<nodes::Lambda>::operator()(
|
nodes::Lambda
|
||||||
const parser::ParseTree::Node &parser_node, const utils::None &) {
|
BuilderTask<nodes::Lambda>::operator()(const ParserNode &parser_node,
|
||||||
|
const utils::None &) {
|
||||||
std::vector<nodes::Identifier> arguments;
|
std::vector<nodes::Identifier> arguments;
|
||||||
|
|
||||||
auto current_node =
|
auto current_node =
|
||||||
|
|
|
||||||
|
|
@ -529,33 +529,7 @@ private:
|
||||||
|
|
||||||
class Expression : public Node {
|
class Expression : public Node {
|
||||||
public:
|
public:
|
||||||
template <typename T>
|
using Type = std::variant<
|
||||||
Expression(Node node, T &&expression, bool is_scoped)
|
|
||||||
: Node(node), expression_(std::forward<T>(expression)),
|
|
||||||
is_scoped_(is_scoped) {}
|
|
||||||
|
|
||||||
template <typename T> std::optional<T *> get() {
|
|
||||||
if (std::holds_alternative<T>(expression_)) {
|
|
||||||
return &std::get<T>(expression_);
|
|
||||||
}
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T> std::optional<const T *> get() const {
|
|
||||||
if (std::holds_alternative<T>(expression_)) {
|
|
||||||
return &std::get<T>(expression_);
|
|
||||||
}
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto get_any() { return &expression_; }
|
|
||||||
|
|
||||||
auto get_any() const { return &expression_; }
|
|
||||||
|
|
||||||
bool is_scoped() const { return is_scoped_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::variant<
|
|
||||||
// --- flow control
|
// --- flow control
|
||||||
Match, Condition, Loop,
|
Match, Condition, Loop,
|
||||||
|
|
||||||
|
|
@ -585,8 +559,36 @@ private:
|
||||||
Extra,
|
Extra,
|
||||||
|
|
||||||
// --- empty lines
|
// --- empty lines
|
||||||
EmptyLines>
|
EmptyLines>;
|
||||||
expression_;
|
|
||||||
|
public:
|
||||||
|
template <typename T>
|
||||||
|
Expression(Node node, T &&expression, bool is_scoped)
|
||||||
|
: Node(node), expression_(std::forward<T>(expression)),
|
||||||
|
is_scoped_(is_scoped) {}
|
||||||
|
|
||||||
|
template <typename T> std::optional<T *> get() {
|
||||||
|
if (std::holds_alternative<T>(expression_)) {
|
||||||
|
return &std::get<T>(expression_);
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> std::optional<const T *> get() const {
|
||||||
|
if (std::holds_alternative<T>(expression_)) {
|
||||||
|
return &std::get<T>(expression_);
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto get_any() { return &expression_; }
|
||||||
|
|
||||||
|
auto get_any() const { return &expression_; }
|
||||||
|
|
||||||
|
bool is_scoped() const { return is_scoped_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Type expression_;
|
||||||
|
|
||||||
bool is_scoped_ = false;
|
bool is_scoped_ = false;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue