diff --git a/lang/builders/include/builders_utils.hpp b/lang/builders/include/builders_utils.hpp index ec17a44..7323cab 100644 --- a/lang/builders/include/builders_utils.hpp +++ b/lang/builders/include/builders_utils.hpp @@ -6,7 +6,7 @@ namespace builders { -using Code = parser::ParseTree; +// using Code = parser::ParseTree; using Exprs = nodes::ExpressionStorage; using Types = nodes::TypeStorage; using Names = names::NameTree; @@ -18,29 +18,19 @@ using Node = nodes::Node_>; // TODO template using Task = utils::Task; -template struct BuilderTask { +template struct BuilderTask { static_assert(false); }; template struct BuilderTaskBase : public Task { using Task::Task; - template + template OtherN Run(const parser::ParseTree::Node &node, const utils::None &args = {}) { - BuilderTask task(this->executor); + BuilderTask task(this->executor); return task(node, args); } }; -// TODO -// template <> -// struct BuilderTask -// : public BuilderTaskBase { -// using BuilderTaskBase::BuilderTaskBase; - -// nodes::ExpressionProxy operator()(const parser::ParseTree::Node &expr, -// const utils::None &args) override; -// }; - } // namespace builders diff --git a/lang/builders/include/expression_builders.hpp b/lang/builders/include/expression_builders.hpp index 9a07ed4..5a52b6a 100644 --- a/lang/builders/include/expression_builders.hpp +++ b/lang/builders/include/expression_builders.hpp @@ -1,94 +1,238 @@ #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 -nodes::ExpressionProxy -build_expression(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage); +template <> +struct BuilderTask + : public BuilderTaskBase { + using BuilderTaskBase::BuilderTaskBase; -nodes::Match build_match(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage); + nodes::ExpressionProxy operator()(const parser::ParseTree::Node &parser_node, + const utils::None &args) override; +}; -nodes::Condition build_condition(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage); +template <> +struct BuilderTask + : public BuilderTaskBase { + using BuilderTaskBase::BuilderTaskBase; -nodes::Loop build_loop(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage); + nodes::Match::Case operator()(const parser::ParseTree::Node &parser_node, + const utils::None &args) override; +}; + +template <> +struct BuilderTask : public BuilderTaskBase { + using BuilderTaskBase::BuilderTaskBase; + + nodes::Match operator()(const parser::ParseTree::Node &parser_node, + const utils::None &args) override; +}; + +template <> +struct BuilderTask + : public BuilderTaskBase { + using BuilderTaskBase::BuilderTaskBase; + + nodes::Condition operator()(const parser::ParseTree::Node &parser_node, + const utils::None &args) override; +}; + +template <> +struct BuilderTask : public BuilderTaskBase { + using BuilderTaskBase::BuilderTaskBase; + + nodes::Loop operator()(const parser::ParseTree::Node &parser_node, + const utils::None &args) override; +}; // --- operators -nodes::NameExpression -build_comma_expression(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage); +template <> +struct BuilderTask + : public BuilderTaskBase { + using BuilderTaskBase::BuilderTaskBase; -nodes::NameExpression -build_operator_expression(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage); + nodes::NameExpression operator()(const parser::ParseTree::Node &parser_node, + const utils::None &args) override; +}; + +template <> +struct BuilderTask + : public BuilderTaskBase { + using BuilderTaskBase::BuilderTaskBase; + + nodes::NameExpression operator()(const parser::ParseTree::Node &parser_node, + const utils::None &args) override; +}; // --- continers -nodes::Container build_block(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage); +template + requires std::is_same_v or + std::is_same_v +struct BuilderTask + : public BuilderTaskBase { + using BuilderTaskBase::BuilderTaskBase; -nodes::Container build_array(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage); + // '{' (expression ';')* '}' + // or + // '[[' expression+ ']]' + nodes::Container operator()(const parser::ParseTree::Node &parser_node, + const utils::None &) override { + const auto container_type = std::is_same_v + ? nodes::Container::BLOCK + : nodes::Container::ARRAY; + + std::vector expressions; + + auto current_node = parser_node.nth_named_child(0); + + while (!current_node.is_null()) { + expressions.push_back(Run(current_node)); + current_node = current_node.next_named_sibling(); + } + + return nodes::Container(build_node(parser_node), container_type, + std::move(expressions)); + } +}; // --- modifiers -nodes::Return build_return(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage); +template <> +struct BuilderTask : public BuilderTaskBase { + using BuilderTaskBase::BuilderTaskBase; -nodes::NameDefinition -build_name_definition(parser::ParseTree::Node parser_node); + nodes::Return operator()(const parser::ParseTree::Node &parser_node, + const utils::None &args) override; +}; -nodes::Access build_array_access(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage); +template <> +struct BuilderTask + : public BuilderTaskBase { + using BuilderTaskBase::BuilderTaskBase; -nodes::Access build_tuple_access(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage); + nodes::NameDefinition operator()(const parser::ParseTree::Node &parser_node, + const utils::None &args) override; +}; -nodes::LoopControl build_loop_control(parser::ParseTree::Node parser_node); +template <> +struct BuilderTask + : public BuilderTaskBase { + using BuilderTaskBase::BuilderTaskBase; -nodes::ModifierExpression -build_reference_expression(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage); + nodes::Access operator()(const parser::ParseTree::Node &parser_node, + const utils::None &args) override; +}; -nodes::ModifierExpression -build_suffix_expression(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage); +template <> +struct BuilderTask + : public BuilderTaskBase { + using BuilderTaskBase::BuilderTaskBase; + + nodes::Access operator()(const parser::ParseTree::Node &parser_node, + const utils::None &args) override; +}; + +template <> +struct BuilderTask + : public BuilderTaskBase { + using BuilderTaskBase::BuilderTaskBase; + + nodes::LoopControl operator()(const parser::ParseTree::Node &parser_node, + const utils::None &args) override; +}; + +template <> +struct BuilderTask + : public BuilderTaskBase { + using BuilderTaskBase::BuilderTaskBase; + + nodes::ModifierExpression + operator()(const parser::ParseTree::Node &parser_node, + const utils::None &args) override; +}; + +template <> +struct BuilderTask + : public BuilderTaskBase { + using BuilderTaskBase::BuilderTaskBase; + + nodes::ModifierExpression + operator()(const parser::ParseTree::Node &parser_node, + const utils::None &args) override; +}; + +template + requires std::is_same_v or + std::is_same_v +struct BuilderTask + : public BuilderTaskBase { + using BuilderTaskBase::BuilderTaskBase; + + // _reference_ expression + // or + // expression ('?' | '!') + nodes::ModifierExpression + operator()(const parser::ParseTree::Node &parser_node, + const utils::None &) override { + const size_t modifier_pos = + std::is_same_v ? 0 : parser_node.child_count() - 1; + + return nodes::ModifierExpression( + build_node(parser_node), + build_modifier(parser_node.nth_child(modifier_pos)), + Run(parser_node.nth_named_child(0))); + } +}; // --- other -nodes::NameExpression -build_name_expression(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage); +template <> +struct BuilderTask + : public BuilderTaskBase { + using BuilderTaskBase::BuilderTaskBase; -nodes::Constructor -build_constructor(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage); + nodes::NameExpression operator()(const parser::ParseTree::Node &parser_node, + const utils::None &args) override; +}; -nodes::Lambda build_lambda(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage); +template <> +struct BuilderTask + : public BuilderTaskBase { + using BuilderTaskBase::BuilderTaskBase; + + nodes::Constructor operator()(const parser::ParseTree::Node &parser_node, + const utils::None &args) override; +}; + +template <> +struct BuilderTask : public BuilderTaskBase { + using BuilderTaskBase::BuilderTaskBase; + + nodes::Lambda operator()(const parser::ParseTree::Node &parser_node, + const utils::None &args) override; +}; } // namespace builders diff --git a/lang/builders/src/expression_builders.cpp b/lang/builders/src/expression_builders.cpp index 89a2066..65f6175 100644 --- a/lang/builders/src/expression_builders.cpp +++ b/lang/builders/src/expression_builders.cpp @@ -10,10 +10,8 @@ namespace builders { -nodes::ExpressionProxy -build_expression(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage) { +nodes::ExpressionProxy BuilderTask::operator()( + const parser::ParseTree::Node &parser_node, const utils::None &) { tokens::Type type = tokens::string_to_type(parser_node.get_type()); auto maybe_parenthesis = parser_node.previous_sibling(); @@ -24,141 +22,128 @@ build_expression(parser::ParseTree::Node parser_node, switch (type) { // --- flow control case tokens::Type::MATCH: - return expression_storage.add_expression(nodes::Expression( - build_node(parser_node), - build_match(parser_node, expression_storage, type_storage), is_scoped)); + return state().add_expression(nodes::Expression( + build_node(parser_node), Run(parser_node), is_scoped)); case tokens::Type::CONDITION: - return expression_storage.add_expression(nodes::Expression( - build_node(parser_node), - build_condition(parser_node, expression_storage, type_storage), - is_scoped)); + return state().add_expression( + nodes::Expression(build_node(parser_node), + Run(parser_node), is_scoped)); case tokens::Type::LOOP: - return expression_storage.add_expression(nodes::Expression( - build_node(parser_node), - build_loop(parser_node, expression_storage, type_storage), is_scoped)); + return state().add_expression(nodes::Expression( + build_node(parser_node), Run(parser_node), is_scoped)); // --- operators case tokens::Type::COMMA_EXPRESSION: - return expression_storage.add_expression(nodes::Expression( + return state().add_expression(nodes::Expression( build_node(parser_node), - build_comma_expression(parser_node, expression_storage, type_storage), - is_scoped)); + Run(parser_node), is_scoped)); case tokens::Type::OPERATOR_EXPRESSION: - return expression_storage.add_expression( - nodes::Expression(build_node(parser_node), - build_operator_expression( - parser_node, expression_storage, type_storage), - is_scoped)); + return state().add_expression(nodes::Expression( + build_node(parser_node), + Run(parser_node), + is_scoped)); // --- containers case tokens::Type::BLOCK: - return expression_storage.add_expression(nodes::Expression( + return state().add_expression(nodes::Expression( build_node(parser_node), - build_block(parser_node, expression_storage, type_storage), is_scoped)); + Run(parser_node), is_scoped)); case tokens::Type::ARRAY: - return expression_storage.add_expression(nodes::Expression( + return state().add_expression(nodes::Expression( build_node(parser_node), - build_array(parser_node, expression_storage, type_storage), is_scoped)); + Run(parser_node), is_scoped)); // --- modifiers case tokens::Type::RETURN: - return expression_storage.add_expression(nodes::Expression( - build_node(parser_node), - build_return(parser_node, expression_storage, type_storage), - is_scoped)); + return state().add_expression(nodes::Expression( + build_node(parser_node), Run(parser_node), is_scoped)); case tokens::Type::NAME_DEFINITION: - return expression_storage.add_expression( + return state().add_expression( nodes::Expression(build_node(parser_node), - build_name_definition(parser_node), is_scoped)); + Run(parser_node), is_scoped)); case tokens::Type::ARRAY_ACCESS: - return expression_storage.add_expression(nodes::Expression( + return state().add_expression(nodes::Expression( build_node(parser_node), - build_array_access(parser_node, expression_storage, type_storage), - is_scoped)); + Run(parser_node), is_scoped)); case tokens::Type::TUPLE_ACCESS: - return expression_storage.add_expression(nodes::Expression( + return state().add_expression(nodes::Expression( build_node(parser_node), - build_tuple_access(parser_node, expression_storage, type_storage), - is_scoped)); + Run(parser_node), is_scoped)); case tokens::Type::LOOP_CONTROL: - return expression_storage.add_expression(nodes::Expression( - build_node(parser_node), build_loop_control(parser_node), is_scoped)); - case tokens::Type::REFERENCE_EXPRESSION: - return expression_storage.add_expression( + return state().add_expression( nodes::Expression(build_node(parser_node), - build_reference_expression( - parser_node, expression_storage, type_storage), - is_scoped)); - case tokens::Type::SUFFIX_EXPRESSION: - return expression_storage.add_expression(nodes::Expression( + Run(parser_node), is_scoped)); + case tokens::Type::REFERENCE_EXPRESSION: + return state().add_expression(nodes::Expression( build_node(parser_node), - build_suffix_expression(parser_node, expression_storage, type_storage), + Run(parser_node), is_scoped)); + case tokens::Type::SUFFIX_EXPRESSION: + return state().add_expression(nodes::Expression( + build_node(parser_node), + Run(parser_node), is_scoped)); // --- other case tokens::Type::NAME_EXPRESSION: - return expression_storage.add_expression(nodes::Expression( + return state().add_expression(nodes::Expression( build_node(parser_node), - build_name_expression(parser_node, expression_storage, type_storage), + Run(parser_node), is_scoped)); case tokens::Type::ARGUMENT_NAME_IDENTIFIER: case tokens::Type::SIMPLE_NAME_IDENTIFIER: case tokens::Type::PLACEHOLDER: - return expression_storage.add_expression( + return state().add_expression( nodes::Expression(build_node(parser_node), nodes::NameExpression(build_node(parser_node), build_identifier(parser_node)), is_scoped)); case tokens::Type::CONSTRUCTOR: - return expression_storage.add_expression(nodes::Expression( - build_node(parser_node), - build_constructor(parser_node, expression_storage, type_storage), - is_scoped)); + return state().add_expression( + nodes::Expression(build_node(parser_node), + Run(parser_node), is_scoped)); case tokens::Type::LAMBDA: - return expression_storage.add_expression(nodes::Expression( - build_node(parser_node), - build_lambda(parser_node, expression_storage, type_storage), - is_scoped)); + return state().add_expression(nodes::Expression( + build_node(parser_node), Run(parser_node), is_scoped)); // --- literals case tokens::Type::FLOAT_LITERAL: - return expression_storage.add_expression(nodes::Expression( + return state().add_expression(nodes::Expression( build_node(parser_node), build_float_literal(parser_node), is_scoped)); case tokens::Type::DOUBLE_LITERAL: - return expression_storage.add_expression(nodes::Expression( + return state().add_expression(nodes::Expression( build_node(parser_node), build_double_literal(parser_node), is_scoped)); case tokens::Type::INT_LITERAL: - return expression_storage.add_expression(nodes::Expression( + return state().add_expression(nodes::Expression( build_node(parser_node), build_int_literal(parser_node), is_scoped)); case tokens::Type::LONG_LITERAL: - return expression_storage.add_expression(nodes::Expression( + return state().add_expression(nodes::Expression( build_node(parser_node), build_long_literal(parser_node), is_scoped)); case tokens::Type::INDEX_LITERAL: - return expression_storage.add_expression(nodes::Expression( + return state().add_expression(nodes::Expression( build_node(parser_node), build_index_literal(parser_node), is_scoped)); case tokens::Type::STRING_LITERAL: - return expression_storage.add_expression(nodes::Expression( + return state().add_expression(nodes::Expression( build_node(parser_node), build_string_literal(parser_node), is_scoped)); case tokens::Type::UNICODE_STRING_LITERAL: - return expression_storage.add_expression(nodes::Expression( + return state().add_expression(nodes::Expression( build_node(parser_node), build_unicode_string_literal(parser_node), is_scoped)); case tokens::Type::CHAR_LITERAL: - return expression_storage.add_expression(nodes::Expression( + return state().add_expression(nodes::Expression( build_node(parser_node), build_char_literal(parser_node), is_scoped)); case tokens::Type::UNICODE_LITERAL: - return expression_storage.add_expression( + return state().add_expression( nodes::Expression(build_node(parser_node), build_unicode_literal(parser_node), is_scoped)); case tokens::Type::BOOL_LITERAL: - return expression_storage.add_expression(nodes::Expression( + return state().add_expression(nodes::Expression( build_node(parser_node), build_bool_literal(parser_node), is_scoped)); case tokens::Type::UNIT_LITERAL: - return expression_storage.add_expression(nodes::Expression( + return state().add_expression(nodes::Expression( build_node(parser_node), build_unit_literal(parser_node), is_scoped)); case tokens::Type::NULL_LITERAL: - return expression_storage.add_expression(nodes::Expression( + return state().add_expression(nodes::Expression( build_node(parser_node), build_null_literal(parser_node), is_scoped)); case tokens::Type::EXTRA: - return expression_storage.add_expression(nodes::Expression( + return state().add_expression(nodes::Expression( build_node(parser_node), build_extra(parser_node), is_scoped)); case tokens::Type::EMPTY_LINES: - return expression_storage.add_expression(nodes::Expression( + return state().add_expression(nodes::Expression( build_node(parser_node), build_empty_lines(parser_node), is_scoped)); default: error_handling::handle_parsing_error("Unexprected expression node type", @@ -172,9 +157,8 @@ build_expression(parser::ParseTree::Node parser_node, // --- flow control // (':=' | '=:') expression (('??' | 'if') expression)? (_do_ expression)? -nodes::Match::Case build_case(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage) { +nodes::Match::Case BuilderTask::operator()( + const parser::ParseTree::Node &parser_node, const utils::None &) { std::string case_type = parser_node.nth_child(0).get_value(); std::optional condition_node; @@ -198,41 +182,36 @@ nodes::Match::Case build_case(parser::ParseTree::Node parser_node, build_node(parser_node), case_type == ":=" ? nodes::Match::Case::PATTERN_VALUE : nodes::Match::Case::VALUE_PATTERN, - build_expression(parser_node.nth_named_child(0), expression_storage, - type_storage), + Run(parser_node.nth_named_child(0)), condition_node.has_value() - ? build_expression(condition_node.value(), expression_storage, - type_storage) + ? Run(condition_node.value()) : std::optional(), expression_node.has_value() - ? build_expression(expression_node.value(), expression_storage, - type_storage) + ? Run(expression_node.value()) : std::optional()); } // expression case+ -nodes::Match build_match(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage) { +nodes::Match BuilderTask::operator()( + const parser::ParseTree::Node &parser_node, const utils::None &) { std::vector cases; auto current_node = parser_node.nth_named_child(1); while (!current_node.is_null()) { - cases.push_back(build_case(current_node, expression_storage, type_storage)); + cases.push_back(Run(current_node)); current_node = current_node.next_named_sibling(); } - return nodes::Match(build_node(parser_node), - build_expression(parser_node.nth_named_child(0), - expression_storage, type_storage), - std::move(cases)); + return nodes::Match( + build_node(parser_node), + Run(parser_node.nth_named_child(0)), + std::move(cases)); } // ('??' | 'if') expression _do_ expression (('!!' | 'elif') expression _do_ // expression)* (('!!=>', 'else') expression)? -nodes::Condition build_condition(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage) { +nodes::Condition BuilderTask::operator()( + const parser::ParseTree::Node &parser_node, const utils::None &) { size_t named_child_count = parser_node.named_child_count(); std::vector> cases; @@ -241,9 +220,8 @@ nodes::Condition build_condition(parser::ParseTree::Node parser_node, auto next_node = current_node.next_named_sibling(); while (!current_node.is_null() && !next_node.is_null()) { - cases.push_back( - {build_expression(current_node, expression_storage, type_storage), - build_expression(next_node, expression_storage, type_storage)}); + cases.push_back({Run(current_node), + Run(next_node)}); current_node = next_node.next_named_sibling(); if (current_node.is_null()) { break; @@ -254,35 +232,32 @@ nodes::Condition build_condition(parser::ParseTree::Node parser_node, return nodes::Condition( build_node(parser_node), std::move(cases), named_child_count % 2 == 1 - ? build_expression(parser_node.nth_named_child(named_child_count - 1), - expression_storage, type_storage) + ? Run( + parser_node.nth_named_child(named_child_count - 1)) : std::optional()); } // ('@' | 'for') (expression | expression ':' expression)? _do_ expression -nodes::Loop build_loop(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage) { +nodes::Loop +BuilderTask::operator()(const parser::ParseTree::Node &parser_node, + const utils::None &) { size_t named_child_count = parser_node.named_child_count(); if (named_child_count == 1) { // body - return nodes::Loop(build_node(parser_node), - build_expression(parser_node.nth_named_child(0), - expression_storage, type_storage)); + return nodes::Loop( + build_node(parser_node), + Run(parser_node.nth_named_child(0))); } else if (named_child_count == 2) { // condition, body - return nodes::Loop(build_node(parser_node), - build_expression(parser_node.nth_named_child(0), - expression_storage, type_storage), - build_expression(parser_node.nth_named_child(1), - expression_storage, type_storage)); + return nodes::Loop( + build_node(parser_node), + Run(parser_node.nth_named_child(0)), + Run(parser_node.nth_named_child(1))); } else if (named_child_count == 3) { // variable, interval, body - return nodes::Loop(build_node(parser_node), - build_expression(parser_node.nth_named_child(0), - expression_storage, type_storage), - build_expression(parser_node.nth_named_child(1), - expression_storage, type_storage), - build_expression(parser_node.nth_named_child(2), - expression_storage, type_storage)); + return nodes::Loop( + build_node(parser_node), + Run(parser_node.nth_named_child(0)), + Run(parser_node.nth_named_child(1)), + Run(parser_node.nth_named_child(2))); } else { error_handling::handle_parsing_error( "Unexprected named expression amount in loop", parser_node); @@ -296,19 +271,16 @@ nodes::Loop build_loop(parser::ParseTree::Node parser_node, // expression ',' expression nodes::NameExpression -build_comma_expression(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage) { +BuilderTask::operator()( + const parser::ParseTree::Node &parser_node, const utils::None &) { std::vector, nodes::ExpressionProxy>> arguments; - arguments.emplace_back(std::nullopt, - build_expression(parser_node.nth_named_child(0), - expression_storage, type_storage)); + arguments.emplace_back(std::nullopt, Run( + parser_node.nth_named_child(0))); - arguments.emplace_back(std::nullopt, - build_expression(parser_node.nth_named_child(1), - expression_storage, type_storage)); + arguments.emplace_back(std::nullopt, Run( + parser_node.nth_named_child(1))); return nodes::NameExpression( build_node(parser_node), @@ -320,21 +292,18 @@ build_comma_expression(parser::ParseTree::Node parser_node, // expression operator expression nodes::NameExpression -build_operator_expression(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage) { +BuilderTask::operator()( + const parser::ParseTree::Node &parser_node, const utils::None &) { auto name_node = parser_node.child_by_field_name("name"); std::vector, nodes::ExpressionProxy>> arguments; - arguments.emplace_back(std::nullopt, - build_expression(name_node.previous_named_sibling(), - expression_storage, type_storage)); + arguments.emplace_back(std::nullopt, Run( + name_node.previous_named_sibling())); - arguments.emplace_back(std::nullopt, - build_expression(name_node.next_named_sibling(), - expression_storage, type_storage)); + arguments.emplace_back(std::nullopt, Run( + name_node.next_named_sibling())); return nodes::NameExpression(build_node(parser_node), build_operator(name_node), std::move(arguments), @@ -343,59 +312,24 @@ build_operator_expression(parser::ParseTree::Node parser_node, // --- continers -nodes::Container -build_container(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage, - nodes::Container::ContainerType container_type) { - std::vector expressions; - - auto current_node = parser_node.nth_named_child(0); - - while (!current_node.is_null()) { - expressions.push_back( - build_expression(current_node, expression_storage, type_storage)); - current_node = current_node.next_named_sibling(); - } - - return nodes::Container(build_node(parser_node), container_type, - std::move(expressions)); -} - -// '{' (expression ';')* '}' -nodes::Container build_block(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage) { - return build_container(parser_node, expression_storage, type_storage, - nodes::Container::BLOCK); -} - -// '[[' expression+ ']]' -nodes::Container build_array(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage) { - return build_container(parser_node, expression_storage, type_storage, - nodes::Container::ARRAY); -} +// // Container -> .hpp // --- modifiers // ('return' | 'bring') expression -nodes::Return build_return(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage) { +nodes::Return BuilderTask::operator()( + const parser::ParseTree::Node &parser_node, const utils::None &) { std::string modifier = parser_node.nth_child(0).get_value(); - return nodes::Return(build_node(parser_node), - modifier == "return" ? nodes::Return::RETURN - : nodes::Return::BRING, - build_expression(parser_node.nth_named_child(0), - expression_storage, type_storage)); + return nodes::Return( + build_node(parser_node), + modifier == "return" ? nodes::Return::RETURN : nodes::Return::BRING, + Run(parser_node.nth_named_child(0))); } // _var_let_ (simple_name_identifier | placeholder) -nodes::NameDefinition -build_name_definition(parser::ParseTree::Node parser_node) { +nodes::NameDefinition BuilderTask::operator()( + const parser::ParseTree::Node &parser_node, const utils::None &) { std::string modifier = parser_node.nth_child(0).get_value(); auto name_node = parser_node.nth_named_child(0); @@ -408,76 +342,41 @@ build_name_definition(parser::ParseTree::Node parser_node) { } // IN PROGRESS // expression '[' expression ']' -nodes::Access build_array_access(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage) { - return nodes::Access(build_node(parser_node), nodes::Access::ARRAY, - build_expression(parser_node.nth_named_child(0), - expression_storage, type_storage), - build_expression(parser_node.nth_named_child(1), - expression_storage, type_storage)); +nodes::Access BuilderTask::operator()( + const parser::ParseTree::Node &parser_node, const utils::None &) { + return nodes::Access( + build_node(parser_node), nodes::Access::ARRAY, + Run(parser_node.nth_named_child(0)), + Run(parser_node.nth_named_child(1))); } // expression '.' number_literal -nodes::Access build_tuple_access(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage) { +nodes::Access BuilderTask::operator()( + const parser::ParseTree::Node &parser_node, const utils::None &) { return nodes::Access( build_node(parser_node), nodes::Access::TUPLE, - build_expression(parser_node.nth_named_child(0), expression_storage, - type_storage), - expression_storage.add_expression(nodes::Expression( + Run(parser_node.nth_named_child(0)), + state().add_expression(nodes::Expression( build_node(parser_node.nth_named_child(1)), build_index_literal(parser_node.nth_named_child(1)), false))); } // 'break' | 'continue' -nodes::LoopControl build_loop_control(parser::ParseTree::Node parser_node) { +nodes::LoopControl BuilderTask::operator()( + const parser::ParseTree::Node &parser_node, const utils::None &) { return nodes::LoopControl(build_node(parser_node), parser_node.get_value() == "break" ? nodes::LoopControl::BREAK : nodes::LoopControl::CONTINUE); } -nodes::ModifierExpression -build_modifier_expression(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage, - size_t modifier_position) { - - return nodes::ModifierExpression( - build_node(parser_node), - build_modifier(parser_node.nth_child(modifier_position)), - build_expression(parser_node.nth_named_child(0), expression_storage, - type_storage)); -} - -// _reference_ expression -nodes::ModifierExpression -build_reference_expression(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage) { - return build_modifier_expression(parser_node, expression_storage, - type_storage, 0); -} - -// expression ('?' | '!') -nodes::ModifierExpression -build_suffix_expression(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage) { - return build_modifier_expression(parser_node, expression_storage, - type_storage, parser_node.child_count() - 1); -} +// // ModifierExpression -> .hpp // --- other void build_arguments_until_end( - parser::ParseTree::Node first_parse_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage, - std::vector, nodes::ExpressionProxy>> - &arguments) { + parser::ParseTree::Node first_parse_node, Executor &executor, + std::vector &arguments) { auto current_node = first_parse_node; @@ -489,7 +388,7 @@ void build_arguments_until_end( } else { arguments.emplace_back( std::move(last_annotation), - build_expression(current_node, expression_storage, type_storage)); + executor.Run(current_node)); last_annotation = std::nullopt; } current_node = current_node.next_named_sibling(); @@ -499,11 +398,9 @@ void build_arguments_until_end( // (type '.' simple_name | expression '.' simple_name | name | '(' operator // ')') (annotation? expression)* nodes::NameExpression -build_name_expression(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage) { - std::vector, nodes::ExpressionProxy>> - arguments; +BuilderTask::operator()( + const parser::ParseTree::Node &parser_node, const utils::None &) { + std::vector arguments; std::optional prefix; @@ -528,45 +425,40 @@ build_name_expression(parser::ParseTree::Node parser_node, prefix_node = current_node; } else { is_point_call = true; - arguments.emplace_back( - std::nullopt, - build_expression(current_node, expression_storage, type_storage)); + arguments.emplace_back(std::nullopt, + Run(current_node)); } } - build_arguments_until_end(name_node.next_named_sibling(), expression_storage, - type_storage, arguments); + build_arguments_until_end(name_node.next_named_sibling(), executor, + arguments); return nodes::NameExpression( build_node(parser_node), build_identifier(name_node), std::move(arguments), - prefix_node.has_value() ? build_type(prefix_node.value(), type_storage) + prefix_node.has_value() ? build_type(prefix_node.value(), state()) : nodes::MaybeTypeProxy(), is_point_call, false); } // type (annotation? expression)* -nodes::Constructor -build_constructor(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage) { - std::vector, nodes::ExpressionProxy>> - arguments; +nodes::Constructor BuilderTask::operator()( + const parser::ParseTree::Node &parser_node, const utils::None &) { + std::vector arguments; build_arguments_until_end( - parser_node.child_by_field_name("type").next_named_sibling(), - expression_storage, type_storage, arguments); + parser_node.child_by_field_name("type").next_named_sibling(), executor, + arguments); return nodes::Constructor( build_node(parser_node), - build_type(parser_node.child_by_field_name("type"), type_storage), + build_type(parser_node.child_by_field_name("type"), state()), std::move(arguments)); } // '\\' argument_name* _do_ expression -nodes::Lambda build_lambda(parser::ParseTree::Node parser_node, - nodes::ExpressionStorage &expression_storage, - nodes::TypeStorage &type_storage) { +nodes::Lambda BuilderTask::operator()( + const parser::ParseTree::Node &parser_node, const utils::None &) { std::vector arguments; auto current_node = @@ -580,9 +472,8 @@ nodes::Lambda build_lambda(parser::ParseTree::Node parser_node, // skip '=>' current_node = current_node.next_named_sibling(); - return nodes::Lambda( - build_node(parser_node), std::move(arguments), - build_expression(current_node, expression_storage, type_storage)); + return nodes::Lambda(build_node(parser_node), std::move(arguments), + Run(current_node)); } } // namespace builders diff --git a/lang/nodes/include/expression_nodes.hpp b/lang/nodes/include/expression_nodes.hpp index 3001b35..8ffded9 100644 --- a/lang/nodes/include/expression_nodes.hpp +++ b/lang/nodes/include/expression_nodes.hpp @@ -379,6 +379,9 @@ private: // --- other +using AnnotatedArgument = + std::pair, ExpressionProxy>; + class NameExpression : public TypedNode { public: NameExpression(Node node, Identifier &&name) @@ -387,12 +390,10 @@ public: NameExpression(Node node, const Identifier &name) : TypedNode(node), name_(name) {} - NameExpression( - Node node, Identifier &&name, - std::vector, ExpressionProxy>> - &&arguments, - std::optional &&prefix, bool is_point_call = false, - bool is_operator_call = false) + NameExpression(Node node, Identifier &&name, + std::vector &&arguments, + std::optional &&prefix, bool is_point_call = false, + bool is_operator_call = false) : TypedNode(node), name_(std::move(name)), arguments_(std::move(arguments)), prefix_(std::move(prefix)), is_point_call_(is_point_call), is_operator_call_(is_operator_call) {} @@ -446,8 +447,7 @@ public: private: Identifier name_; // universal function call syntax - std::vector, ExpressionProxy>> - arguments_; + std::vector arguments_; std::optional prefix_; // for static methods bool is_point_call_ = false; // x.f ... or f x ... @@ -456,17 +456,13 @@ private: class Constructor : public TypedNode { public: - Constructor( - Node node, TypeProxy type, - std::vector, ExpressionProxy>> - &&arguments) + Constructor(Node node, TypeProxy type, + std::vector &&arguments) : TypedNode(node), constructor_type_(type), arguments_(std::move(arguments)) {} - Constructor( - Node node, TypeProxy type, - const std::vector, ExpressionProxy>> - &arguments) + Constructor(Node node, TypeProxy type, + const std::vector &arguments) : TypedNode(node), constructor_type_(type), arguments_(arguments) {} Type *get_type() { return constructor_type_.get(); }