better expr proxy builder task

This commit is contained in:
dragon 2024-08-16 21:27:57 +03:00
parent f5856734c6
commit cbbf626232
4 changed files with 217 additions and 189 deletions

View file

@ -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>

View file

@ -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,9 +169,8 @@ 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;
}; };
template <> template <>
@ -179,9 +178,8 @@ 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;
}; };
template <typename T> template <typename T>
@ -194,9 +192,8 @@ 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;
}; };

View file

@ -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,32 +232,48 @@ 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();
if (named_child_count == 1) { // body if (named_child_count == 1) { // 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)));
} 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 =

View file

@ -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;
}; };