diff --git a/lang/app/sources_manager.hpp b/lang/app/sources_manager.hpp index 00a059c..a9b8574 100644 --- a/lang/app/sources_manager.hpp +++ b/lang/app/sources_manager.hpp @@ -17,7 +17,7 @@ class SourcesManager { public: void AddFile(const std::string &filename) { - Log::Context logc(executor_.log(), utils::Log::Area::kParse); + Log::Context logc(executor_.log(), Log::Area::kParse); std::ifstream in; in.open(filename); @@ -64,6 +64,6 @@ public: private: builders::Executor executor_ = - builders::Executor(utils::BuildPrintLog(std::cout), {}, {}, {}, {}); + builders::Executor(utils::BuildPrintLog(std::cout), {}, {}, {}, {}, {}); std::vector statements_ = {}; }; diff --git a/lang/builders/include/basic_builders.hpp b/lang/builders/include/basic_builders.hpp index 1479756..3fe823d 100644 --- a/lang/builders/include/basic_builders.hpp +++ b/lang/builders/include/basic_builders.hpp @@ -1,69 +1,260 @@ #pragma once #include "basic_nodes.hpp" +#include "builders_utils.hpp" #include "tree_sitter_wrapper.hpp" +namespace utils { + +struct SimpleNameIdTag {}; +struct SimpleTypeIdTag {}; +struct TypeclassIdTag {}; +struct ArgNameIdTag {}; +struct ArgTypeIdTag {}; +struct OperatorIdTag {}; +struct PlaceholderIdTag {}; +struct GenericTypeIdTag {}; + +}; // namespace utils + namespace builders { // returns Modifier::NONE for incorrecnt input -nodes::Modifier build_modifier(parser::ParseTree::Node parser_node); +template <> +struct BuilderTask + : public BasicBuilderTaskBase { + using BasicBuilderTaskBase::BasicBuilderTaskBase; -nodes::Node build_node(parser::ParseTree::Node parser_node); + nodes::Modifier operator()(const ParserNode &parser_node, + const Args &args) override; +}; // --- literals -nodes::Literal build_float_literal(parser::ParseTree::Node parser_node); +// nodes::Literal build_float_literal(parser::ParseTree::Node parser_node); +template <> +struct BuilderTask + : public BasicBuilderTaskBase { + using BasicBuilderTaskBase::BasicBuilderTaskBase; -nodes::Literal build_double_literal(parser::ParseTree::Node parser_node); + nodes::Literal operator()(const ParserNode &parser_node, + const Args &args) override; +}; -nodes::Literal build_int_literal(parser::ParseTree::Node parser_node); +// nodes::Literal build_double_literal(parser::ParseTree::Node parser_node); +template <> +struct BuilderTask + : public BasicBuilderTaskBase { + using BasicBuilderTaskBase::BasicBuilderTaskBase; -nodes::Literal build_long_literal(parser::ParseTree::Node parser_node); + nodes::Literal operator()(const ParserNode &parser_node, + const Args &args) override; +}; -nodes::Literal build_index_literal(parser::ParseTree::Node parser_node); +// nodes::Literal build_int_literal(parser::ParseTree::Node parser_node); +template <> +struct BuilderTask // int + : public BasicBuilderTaskBase { + using BasicBuilderTaskBase::BasicBuilderTaskBase; -nodes::Literal build_string_literal(parser::ParseTree::Node parser_node); + nodes::Literal operator()(const ParserNode &parser_node, + const Args &args) override; +}; -nodes::Literal -build_unicode_string_literal(parser::ParseTree::Node parser_node); +// nodes::Literal build_long_literal(parser::ParseTree::Node parser_node); +template <> +struct BuilderTask // long + : public BasicBuilderTaskBase { + using BasicBuilderTaskBase::BasicBuilderTaskBase; -nodes::Literal build_char_literal(parser::ParseTree::Node parser_node); + nodes::Literal operator()(const ParserNode &parser_node, + const Args &args) override; +}; -nodes::Literal build_unicode_literal(parser::ParseTree::Node parser_node); +// nodes::Literal build_index_literal(parser::ParseTree::Node parser_node); +template <> +struct BuilderTask // index + : public BasicBuilderTaskBase { + using BasicBuilderTaskBase::BasicBuilderTaskBase; -nodes::Literal build_bool_literal(parser::ParseTree::Node parser_node); + nodes::Literal operator()(const ParserNode &parser_node, + const Args &args) override; +}; -nodes::Literal build_unit_literal(parser::ParseTree::Node parser_node); +// nodes::Literal build_string_literal(parser::ParseTree::Node parser_node); +template <> +struct BuilderTask // string + : public BasicBuilderTaskBase { + using BasicBuilderTaskBase::BasicBuilderTaskBase; -nodes::Literal build_null_literal(parser::ParseTree::Node parser_node); + nodes::Literal operator()(const ParserNode &parser_node, + const Args &args) override; +}; + +// nodes::Literal +// build_unicode_string_literal(parser::ParseTree::Node parser_node); +template <> +struct BuilderTask + : public BasicBuilderTaskBase { + using BasicBuilderTaskBase::BasicBuilderTaskBase; + + nodes::Literal operator()(const ParserNode &parser_node, + const Args &args) override; +}; + +// nodes::Literal build_char_literal(parser::ParseTree::Node parser_node); +template <> +struct BuilderTask + : public BasicBuilderTaskBase { + using BasicBuilderTaskBase::BasicBuilderTaskBase; + + nodes::Literal operator()(const ParserNode &parser_node, + const Args &args) override; +}; + +// nodes::Literal build_unicode_literal(parser::ParseTree::Node parser_node); +template <> +struct BuilderTask + : public BasicBuilderTaskBase { + using BasicBuilderTaskBase::BasicBuilderTaskBase; + + nodes::Literal operator()(const ParserNode &parser_node, + const Args &args) override; +}; + +// nodes::Literal build_bool_literal(parser::ParseTree::Node parser_node); +template <> +struct BuilderTask + : public BasicBuilderTaskBase { + using BasicBuilderTaskBase::BasicBuilderTaskBase; + + nodes::Literal operator()(const ParserNode &parser_node, + const Args &args) override; +}; + +// nodes::Literal build_unit_literal(parser::ParseTree::Node parser_node); +template <> +struct BuilderTask + : public BasicBuilderTaskBase { + using BasicBuilderTaskBase::BasicBuilderTaskBase; + + nodes::Literal operator()(const ParserNode &parser_node, + const Args &args) override; +}; + +// nodes::Literal build_null_literal(parser::ParseTree::Node parser_node); +template <> +struct BuilderTask + : public BasicBuilderTaskBase { + using BasicBuilderTaskBase::BasicBuilderTaskBase; + + nodes::Literal operator()(const ParserNode &parser_node, + const Args &args) override; +}; // --- identifiers -nodes::Identifier build_identifier(parser::ParseTree::Node parser_node); +template <> +struct BuilderTask + : public BasicBuilderTaskBase { + using BasicBuilderTaskBase::BasicBuilderTaskBase; -nodes::Identifier build_simple_name(parser::ParseTree::Node parser_node); + nodes::Identifier operator()(const ParserNode &parser_node, + const Args &args) override; +}; -nodes::Identifier build_simple_type(parser::ParseTree::Node parser_node); +template <> +struct BuilderTask + : public BasicBuilderTaskBase { + using BasicBuilderTaskBase::BasicBuilderTaskBase; -nodes::Identifier build_typeclass(parser::ParseTree::Node parser_node); + nodes::Identifier operator()(const ParserNode &parser_node, + const Args &args) override; +}; -nodes::Identifier build_argument_name(parser::ParseTree::Node parser_node); +template <> +struct BuilderTask + : public BasicBuilderTaskBase { + using BasicBuilderTaskBase::BasicBuilderTaskBase; -nodes::Identifier build_argument_type(parser::ParseTree::Node parser_node); + nodes::Identifier operator()(const ParserNode &parser_node, + const Args &args) override; +}; + +template <> +struct BuilderTask + : public BasicBuilderTaskBase { + using BasicBuilderTaskBase::BasicBuilderTaskBase; + + nodes::Identifier operator()(const ParserNode &parser_node, + const Args &args) override; +}; + +template <> +struct BuilderTask + : public BasicBuilderTaskBase { + using BasicBuilderTaskBase::BasicBuilderTaskBase; + + nodes::Identifier operator()(const ParserNode &parser_node, + const Args &args) override; +}; + +template <> +struct BuilderTask + : public BasicBuilderTaskBase { + using BasicBuilderTaskBase::BasicBuilderTaskBase; + + nodes::Identifier operator()(const ParserNode &parser_node, + const Args &args) override; +}; // Annotations are used as strings -std::string build_annotation(parser::ParseTree::Node parser_node); +template <> +struct BuilderTask + : public BasicBuilderTaskBase { + using BasicBuilderTaskBase::BasicBuilderTaskBase; -nodes::Identifier build_operator(parser::ParseTree::Node parser_node); + nodes::Annotation operator()(const ParserNode &parser_node, + const Args &args) override; +}; -nodes::Identifier build_placeholder(parser::ParseTree::Node parser_node); +template <> +struct BuilderTask + : public BasicBuilderTaskBase { + using BasicBuilderTaskBase::BasicBuilderTaskBase; + + nodes::Identifier operator()(const ParserNode &parser_node, + const Args &args) override; +}; + +template <> +struct BuilderTask + : public BasicBuilderTaskBase { + using BasicBuilderTaskBase::BasicBuilderTaskBase; + + nodes::Identifier operator()(const ParserNode &parser_node, + const Args &args) override; +}; // --- extra -nodes::Extra build_extra(parser::ParseTree::Node parser_node); +template <> +struct BuilderTask : public BasicBuilderTaskBase { + using BasicBuilderTaskBase::BasicBuilderTaskBase; + + nodes::Extra operator()(const ParserNode &parser_node, + const Args &args) override; +}; // --- empty lines -nodes::EmptyLines build_empty_lines(parser::ParseTree::Node parser_node); +template <> +struct BuilderTask + : public BasicBuilderTaskBase { + using BasicBuilderTaskBase::BasicBuilderTaskBase; + + nodes::EmptyLines operator()(const ParserNode &parser_node, + const Args &args) override; +}; } // namespace builders diff --git a/lang/builders/include/builders_utils.hpp b/lang/builders/include/builders_utils.hpp index cdd18ac..50bd1c6 100644 --- a/lang/builders/include/builders_utils.hpp +++ b/lang/builders/include/builders_utils.hpp @@ -7,26 +7,28 @@ namespace builders { // using Code = parser::ParseTree; -using Exprs = nodes::ExprStorage; +using Exprs = nodes::NodeStorage; // nodes::ExprStorage; using Types = nodes::TypeStorage; using Names = names::NameTree; +using Positions = core::DependentStorage; // struct State { - std::optional last_defined_type_name; }; // -using Executor = utils::Executor; +using Executor = utils::Executor; using ParserNode = parser::ParseTree::Node; -// using Node = nodes::Node_>; // TODO +using Node = nodes::Node_>; -using Args = utils::None; +struct Args { + bool is_scoped = false; +}; template using Task = utils::Task; @@ -35,11 +37,71 @@ template struct BuilderTask { static_assert(false); }; -template struct BuilderTaskBase : public Task { +template struct BuilderTaskUtils : public Task { using Task::Task; - template - OtherN Run(const parser::ParseTree::Node &node, const Args &args = {}) { + Node Ext(storage::Id id) const { + return Node(id, this->template state(), + this->template state()); + } + + template + Node Expect(Node value, Log::Context &logc, + std::source_location source_location = + std::source_location::current()) const { + logc.Expect(value.Holds(), + {{"value type requirement failed"}}, {}, + source_location); + return value; + } + + template Node Build(T value, utils::Pos pos) { + auto id = this->template state().Insert(std::move(value)); + this->template state().ForceInsert(id, pos); + return GetNode(id); + } +}; + +// + +template struct BasicBuilderTaskBase : public BuilderTaskUtils { + using BuilderTaskUtils::BuilderTaskUtils; + + template + Ret Run(const parser::ParseTree::Node &node, const Args &args = {}) { + BuilderTask task(this->executor); + return task(node, args); + } +}; + +template +struct ExprBuilderTaskBase : public BuilderTaskUtils { + using BuilderTaskUtils::BuilderTaskUtils; + + template + Ret Run(const parser::ParseTree::Node &node, const Args &args = {}) { + BuilderTask task(this->executor); + return task(node, args); + } + + // TODO: rename + template + Ret RunOther(const parser::ParseTree::Node &node, const Args &args = {}) { + BuilderTask task(this->executor); + return task(node, args); + } +}; + +template +struct StatementBuilderTaskBase : public BuilderTaskUtils { + using BuilderTaskUtils::BuilderTaskUtils; + + template + Ret Run(const parser::ParseTree::Node &node, const Args &args = {}) { BuilderTask task(this->executor); return task(node, args); } diff --git a/lang/builders/include/expression_builders.hpp b/lang/builders/include/expression_builders.hpp index 65fdc27..f2c6cfc 100644 --- a/lang/builders/include/expression_builders.hpp +++ b/lang/builders/include/expression_builders.hpp @@ -23,66 +23,58 @@ namespace builders { // --- flow control -template <> -struct BuilderTask : public BuilderTaskBase { - using BuilderTaskBase::BuilderTaskBase; +template <> struct BuilderTask : public ExprBuilderTaskBase { + using ExprBuilderTaskBase::ExprBuilderTaskBase; - nodes::Expr operator()(const ParserNode &parser_node, - const Args &args) override; + Node operator()(const ParserNode &parser_node, const Args &args) override; }; template <> struct BuilderTask - : public BuilderTaskBase { - using BuilderTaskBase::BuilderTaskBase; + : public ExprBuilderTaskBase { + using ExprBuilderTaskBase::ExprBuilderTaskBase; - nodes::Match::Case operator()(const ParserNode &parser_node, - const Args &args) override; + Node operator()(const ParserNode &parser_node, const Args &args) override; }; template <> -struct BuilderTask : public BuilderTaskBase { - using BuilderTaskBase::BuilderTaskBase; +struct BuilderTask : public ExprBuilderTaskBase { + using ExprBuilderTaskBase::ExprBuilderTaskBase; - nodes::Match operator()(const ParserNode &parser_node, - const Args &args) override; + Node operator()(const ParserNode &parser_node, const Args &args) override; }; template <> struct BuilderTask - : public BuilderTaskBase { - using BuilderTaskBase::BuilderTaskBase; + : public ExprBuilderTaskBase { + using ExprBuilderTaskBase::ExprBuilderTaskBase; - nodes::Condition operator()(const ParserNode &parser_node, - const Args &args) override; + Node operator()(const ParserNode &parser_node, const Args &args) override; }; template <> -struct BuilderTask : public BuilderTaskBase { - using BuilderTaskBase::BuilderTaskBase; +struct BuilderTask : public ExprBuilderTaskBase { + using ExprBuilderTaskBase::ExprBuilderTaskBase; - nodes::Loop operator()(const ParserNode &parser_node, - const Args &args) override; + Node operator()(const ParserNode &parser_node, const Args &args) override; }; // --- operators template <> struct BuilderTask - : public BuilderTaskBase { - using BuilderTaskBase::BuilderTaskBase; + : public ExprBuilderTaskBase { + using ExprBuilderTaskBase::ExprBuilderTaskBase; - nodes::NameExpression operator()(const ParserNode &parser_node, - const Args &args) override; + Node operator()(const ParserNode &parser_node, const Args &args) override; }; template <> struct BuilderTask - : public BuilderTaskBase { - using BuilderTaskBase::BuilderTaskBase; + : public ExprBuilderTaskBase { + using ExprBuilderTaskBase::ExprBuilderTaskBase; - nodes::NameExpression operator()(const ParserNode &parser_node, - const Args &args) override; + Node operator()(const ParserNode &parser_node, const Args &args) override; }; // --- continers @@ -91,97 +83,92 @@ template requires std::is_same_v or std::is_same_v struct BuilderTask - : public BuilderTaskBase { - using BuilderTaskBase::BuilderTaskBase; + : public ExprBuilderTaskBase { + using ExprBuilderTaskBase::ExprBuilderTaskBase; // '{' (expression ';')* '}' // or // '[[' expression+ ']]' - nodes::Container operator()(const ParserNode &parser_node, - const Args &) override { - const auto container_type = std::is_same_v - ? nodes::Container::BLOCK - : nodes::Container::ARRAY; + Node operator()(const ParserNode &parser_node, const Args &) override { + const auto kind = std::is_same_v + ? nodes::Container::BLOCK + : nodes::Container::ARRAY; - std::vector expressions; + std::vector exprs; auto current_node = parser_node.nth_named_child(0); while (!current_node.is_null()) { - expressions.push_back(Run(current_node)); + exprs.push_back(Run(current_node)); current_node = current_node.next_named_sibling(); } - return nodes::Container(build_node(parser_node), container_type, - std::move(expressions)); + return state().Insert(nodes::Container{ + .kind = kind, + .exprs = std::move(exprs), + }); } }; // --- modifiers template <> -struct BuilderTask : public BuilderTaskBase { - using BuilderTaskBase::BuilderTaskBase; +struct BuilderTask : public ExprBuilderTaskBase { + using ExprBuilderTaskBase::ExprBuilderTaskBase; - nodes::Return operator()(const ParserNode &parser_node, - const Args &args) override; + Node operator()(const ParserNode &parser_node, const Args &args) override; }; template <> struct BuilderTask - : public BuilderTaskBase { - using BuilderTaskBase::BuilderTaskBase; + : public ExprBuilderTaskBase { + using ExprBuilderTaskBase::ExprBuilderTaskBase; - nodes::NameDefinition operator()(const ParserNode &parser_node, - const Args &args) override; + Node operator()(const ParserNode &parser_node, const Args &args) override; }; template <> struct BuilderTask - : public BuilderTaskBase { - using BuilderTaskBase::BuilderTaskBase; + : public ExprBuilderTaskBase { + using ExprBuilderTaskBase::ExprBuilderTaskBase; - nodes::Access operator()(const ParserNode &parser_node, - const Args &args) override; + Node operator()(const ParserNode &parser_node, const Args &args) override; }; template <> struct BuilderTask - : public BuilderTaskBase { - using BuilderTaskBase::BuilderTaskBase; + : public ExprBuilderTaskBase { + using ExprBuilderTaskBase::ExprBuilderTaskBase; - nodes::Access operator()(const ParserNode &parser_node, - const Args &args) override; + Node operator()(const ParserNode &parser_node, const Args &args) override; }; template <> struct BuilderTask - : public BuilderTaskBase { - using BuilderTaskBase::BuilderTaskBase; + : public ExprBuilderTaskBase { + using ExprBuilderTaskBase::ExprBuilderTaskBase; - nodes::LoopControl operator()(const ParserNode &parser_node, - const Args &args) override; + Node operator()(const ParserNode &parser_node, const Args &args) override; }; template requires std::is_same_v or std::is_same_v struct BuilderTask - : public BuilderTaskBase { - using BuilderTaskBase::BuilderTaskBase; + : public ExprBuilderTaskBase { + using ExprBuilderTaskBase::ExprBuilderTaskBase; // _reference_ expression // or // expression ('?' | '!') - nodes::ModifierExpression operator()(const ParserNode &parser_node, - const Args &) override { + Node operator()(const ParserNode &parser_node, const Args &) 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))); + return state().Insert(nodes::ModifierExpression{ + .modifier = Run(parser_node.nth_child(modifier_pos)), + .expr = Run(parser_node.nth_named_child(0)), + }); } }; @@ -189,28 +176,25 @@ struct BuilderTask template <> struct BuilderTask - : public BuilderTaskBase { - using BuilderTaskBase::BuilderTaskBase; + : public ExprBuilderTaskBase { + using ExprBuilderTaskBase::ExprBuilderTaskBase; - nodes::NameExpression operator()(const ParserNode &parser_node, - const Args &args) override; + Node operator()(const ParserNode &parser_node, const Args &args) override; }; template <> struct BuilderTask - : public BuilderTaskBase { - using BuilderTaskBase::BuilderTaskBase; + : public ExprBuilderTaskBase { + using ExprBuilderTaskBase::ExprBuilderTaskBase; - nodes::Constructor operator()(const ParserNode &parser_node, - const Args &args) override; + Node operator()(const ParserNode &parser_node, const Args &args) override; }; template <> -struct BuilderTask : public BuilderTaskBase { - using BuilderTaskBase::BuilderTaskBase; +struct BuilderTask : public ExprBuilderTaskBase { + using ExprBuilderTaskBase::ExprBuilderTaskBase; - nodes::Lambda operator()(const ParserNode &parser_node, - const Args &args) override; + Node operator()(const ParserNode &parser_node, const Args &args) override; }; } // namespace builders diff --git a/lang/builders/include/statement_builders.hpp b/lang/builders/include/statement_builders.hpp index 88c5e23..5a6e186 100644 --- a/lang/builders/include/statement_builders.hpp +++ b/lang/builders/include/statement_builders.hpp @@ -16,8 +16,8 @@ namespace builders { // translate them in required order template <> struct BuilderTask - : public BuilderTaskBase { - using BuilderTaskBase::BuilderTaskBase; + : public StatementBuilderTaskBase { + using StatementBuilderTaskBase::StatementBuilderTaskBase; nodes::Statements operator()(const ParserNode &parser_node, const Args &args) override; @@ -26,16 +26,17 @@ struct BuilderTask // copy of statement inserted into name_tree template <> struct BuilderTask - : public BuilderTaskBase { - using BuilderTaskBase::BuilderTaskBase; + : public StatementBuilderTaskBase { + using StatementBuilderTaskBase::StatementBuilderTaskBase; nodes::Statement operator()(const ParserNode &parser_node, const Args &args) override; }; template <> -struct BuilderTask : public BuilderTaskBase { - using BuilderTaskBase::BuilderTaskBase; +struct BuilderTask + : public StatementBuilderTaskBase { + using StatementBuilderTaskBase::StatementBuilderTaskBase; nodes::Import operator()(const ParserNode &parser_node, const Args &args) override; @@ -43,8 +44,8 @@ struct BuilderTask : public BuilderTaskBase { template <> struct BuilderTask - : public BuilderTaskBase { - using BuilderTaskBase::BuilderTaskBase; + : public StatementBuilderTaskBase { + using StatementBuilderTaskBase::StatementBuilderTaskBase; nodes::Constraint operator()(const ParserNode &parser_node, const Args &args) override; @@ -52,8 +53,9 @@ struct BuilderTask template <> struct BuilderTask - : public BuilderTaskBase { - using BuilderTaskBase::BuilderTaskBase; + : public StatementBuilderTaskBase { + using StatementBuilderTaskBase< + nodes::TypeDefinition>::StatementBuilderTaskBase; nodes::TypeDefinition operator()(const ParserNode &parser_node, const Args &args) override; @@ -61,8 +63,9 @@ struct BuilderTask template <> struct BuilderTask - : public BuilderTaskBase { - using BuilderTaskBase::BuilderTaskBase; + : public StatementBuilderTaskBase { + using StatementBuilderTaskBase< + nodes::FunctionDefinition>::StatementBuilderTaskBase; nodes::FunctionDefinition operator()(const ParserNode &parser_node, const Args &args) override; diff --git a/lang/builders/src/basic_builders.cpp b/lang/builders/src/basic_builders.cpp index f08b653..8fd0bc7 100644 --- a/lang/builders/src/basic_builders.cpp +++ b/lang/builders/src/basic_builders.cpp @@ -1,7 +1,6 @@ #include "basic_builders.hpp" #include "basic_nodes.hpp" -#include "error_handling.hpp" #include "tokens.hpp" #include "tree_sitter_wrapper.hpp" @@ -39,7 +38,11 @@ std::optional to_escape_symbol(char ch) { } // namespace utils -nodes::Modifier build_modifier(parser::ParseTree::Node parser_node) { +nodes::Modifier +BuilderTask::operator()(const ParserNode &parser_node, + const Args &) { + Log::Context logc(executor.log(), Log::Area::kTypeCheck); + std::string modifier = parser_node.get_value(); if (modifier == "?") { @@ -81,45 +84,60 @@ nodes::Modifier build_modifier(parser::ParseTree::Node parser_node) { } } -nodes::Node build_node(parser::ParseTree::Node parser_node) { - return nodes::Node(parser_node.get_start_point(), - parser_node.get_end_point()); -} - // --- literals -nodes::Literal build_float_literal(parser::ParseTree::Node parser_node) { +nodes::Literal +BuilderTask::operator()(const ParserNode &parser_node, + const Args &) { + Log::Context logc(executor.log(), Log::Area::kTypeCheck); + std::string literal = parser_node.get_value(); - return nodes::Literal( - build_node(parser_node), - std::stof(literal.substr(0, literal.size() - 1))); // remove 'f' suffix + return nodes::Literal{ + .value = + std::stof(literal.substr(0, literal.size() - 1)) // remove 'f' suffix + }; } -nodes::Literal build_double_literal(parser::ParseTree::Node parser_node) { - return nodes::Literal(build_node(parser_node), - std::stod(parser_node.get_value())); +nodes::Literal +BuilderTask::operator()(const ParserNode &parser_node, + const Args &) { + Log::Context logc(executor.log(), Log::Area::kTypeCheck); + + return nodes::Literal{.value = std::stod(parser_node.get_value())}; } -nodes::Literal build_int_literal(parser::ParseTree::Node parser_node) { +nodes::Literal +BuilderTask::operator()(const ParserNode &parser_node, + const Args &) { + Log::Context logc(executor.log(), Log::Area::kTypeCheck); + std::string literal = parser_node.get_value(); - return nodes::Literal(build_node(parser_node), - (int32_t)std::stoll(literal.substr( - 0, literal.size() - 1))); // remove 'i' suffix + return nodes::Literal{.value = (int32_t)std::stoll(literal.substr( + 0, literal.size() - 1))}; // remove 'i' suffix } -nodes::Literal build_long_literal(parser::ParseTree::Node parser_node) { +nodes::Literal +BuilderTask::operator()(const ParserNode &parser_node, + const Args &) { + Log::Context logc(executor.log(), Log::Area::kTypeCheck); + std::string literal = parser_node.get_value(); - return nodes::Literal(build_node(parser_node), - (int64_t)std::stoll(literal.substr( - 0, literal.size() - 1))); // remove 'l' suffix + return nodes::Literal{.value = (int64_t)std::stoll(literal.substr( + 0, literal.size() - 1))}; // remove 'l' suffix } -nodes::Literal build_index_literal(parser::ParseTree::Node parser_node) { - return nodes::Literal(build_node(parser_node), - (size_t)std::stoull(parser_node.get_value())); +nodes::Literal +BuilderTask::operator()(const ParserNode &parser_node, + const Args &) { // index + Log::Context logc(executor.log(), Log::Area::kTypeCheck); + + return nodes::Literal{.value = (size_t)std::stoull(parser_node.get_value())}; } -nodes::Literal build_string_literal(parser::ParseTree::Node parser_node) { +nodes::Literal BuilderTask::operator()( + const ParserNode &parser_node, const Args &) { + Log::Context logc(executor.log(), Log::Area::kTypeCheck); + std::string literal = parser_node.get_value(); // remove " from both sides ("string") @@ -149,20 +167,25 @@ nodes::Literal build_string_literal(parser::ParseTree::Node parser_node) { } literal.resize(j); - return nodes::Literal(build_node(parser_node), literal); + return nodes::Literal{.value = literal}; } // TODO: decode escape characters, etc. -nodes::Literal -build_unicode_string_literal(parser::ParseTree::Node parser_node) { +nodes::Literal BuilderTask::operator()( + const ParserNode &parser_node, const Args &) { + Log::Context logc(executor.log(), Log::Area::kTypeCheck); + std::string literal = parser_node.get_value(); // remove " from both sides + 'u' ("string"u) - return nodes::Literal(build_node(parser_node), - literal.substr(1, literal.size() - 3)); + return nodes::Literal{.value = literal.substr(1, literal.size() - 3)}; } -nodes::Literal build_char_literal(parser::ParseTree::Node parser_node) { +nodes::Literal +BuilderTask::operator()(const ParserNode &parser_node, + const Args &) { + Log::Context logc(executor.log(), Log::Area::kTypeCheck); + std::string literal = parser_node.get_value(); // remove '' from both sides (''x'') @@ -182,108 +205,156 @@ nodes::Literal build_char_literal(parser::ParseTree::Node parser_node) { ch = literal.back(); } - return nodes::Literal(build_node(parser_node), ch); + return nodes::Literal{ch}; } // TODO: decode escape characters, etc. -nodes::Literal build_unicode_literal(parser::ParseTree::Node parser_node) { +nodes::Literal BuilderTask::operator()( + const ParserNode &parser_node, const Args &) { + Log::Context logc(executor.log(), Log::Area::kTypeCheck); + std::string literal = parser_node.get_value(); // remove '' from both sides + 'u' (''x''u) - return nodes::Literal(build_node(parser_node), - nodes::unicode{literal.substr(2, literal.size() - 5)}); + return nodes::Literal{ + .value = nodes::unicode{literal.substr(2, literal.size() - 5)}}; } -nodes::Literal build_bool_literal(parser::ParseTree::Node parser_node) { +nodes::Literal +BuilderTask::operator()(const ParserNode &parser_node, + const Args &) { + Log::Context logc(executor.log(), Log::Area::kTypeCheck); + std::string literal = parser_node.get_value(); - return nodes::Literal(build_node(parser_node), - literal == "true" ? true : false); + return nodes::Literal{literal == "true" ? true : false}; } -nodes::Literal build_unit_literal(parser::ParseTree::Node parser_node) { - return nodes::Literal(build_node(parser_node), nodes::unit{}); +nodes::Literal +BuilderTask::operator()(const ParserNode &, + const Args &) { + Log::Context logc(executor.log(), Log::Area::kTypeCheck); + + return nodes::Literal{.value = nodes::unit{}}; } -nodes::Literal build_null_literal(parser::ParseTree::Node parser_node) { - return nodes::Literal(build_node(parser_node), nodes::null{}); +nodes::Literal +BuilderTask::operator()(const ParserNode &, + const Args &) { + Log::Context logc(executor.log(), Log::Area::kTypeCheck); + + return nodes::Literal{.value = nodes::null{}}; } // --- identifiers -nodes::Identifier build_identifier(parser::ParseTree::Node parser_node) { +nodes::Identifier +BuilderTask::operator()(const ParserNode &parser_node, + const Args &) { + Log::Context logc(executor.log(), Log::Area::kTypeCheck); + tokens::Type type = tokens::string_to_type(parser_node.get_type()); switch (type) { case tokens::Type::PLACEHOLDER: - return build_placeholder(parser_node); + return Run(parser_node); case tokens::Type::SIMPLE_NAME_IDENTIFIER: - return build_simple_name(parser_node); + return Run(parser_node); case tokens::Type::SIMPLE_TYPE_IDENTIFIER: - return build_simple_type(parser_node); + return Run(parser_node); case tokens::Type::TYPECLASS_IDENTIFIER: - return build_typeclass(parser_node); + return Run(parser_node); case tokens::Type::ARGUMENT_NAME_IDENTIFIER: - return build_argument_name(parser_node); + return Run(parser_node); case tokens::Type::ARGUMENT_TYPE_IDENTIFIER: - return build_argument_type(parser_node); + return Run(parser_node); case tokens::Type::OPERATOR: case tokens::Type::OPERATOR_TAIL1: case tokens::Type::OPERATOR_TAIL2: case tokens::Type::OPERATOR_TAIL3: - return build_operator(parser_node); + return Run(parser_node); // [used as string] // case tokens::Type::ANNOTATION_IDENTIFIER: // return build_annotation(parser_node); default: - error_handling::handle_parsing_error("Unexprected identifier node type", - parser_node); + logc.Fatal({{"Unexprected identifier node type"}}, + parser_node.get_pos()); } - error_handling::handle_general_error("Unreachable"); + ::utils::Assert(false, "Unreachable"); exit(1); // unreachable } -nodes::Identifier build_simple_name(parser::ParseTree::Node parser_node) { - return nodes::Identifier(build_node(parser_node), - nodes::Identifier::SIMPLE_NAME, - parser_node.get_value()); +nodes::Identifier +BuilderTask::operator()( + const ParserNode &parser_node, const Args &) { + Log::Context logc(executor.log(), Log::Area::kTypeCheck); + + return nodes::Identifier{ + .kind = nodes::Identifier::kSimpleName, + .value = parser_node.get_value(), + }; } -nodes::Identifier build_simple_type(parser::ParseTree::Node parser_node) { - return nodes::Identifier(build_node(parser_node), - nodes::Identifier::SIMPLE_TYPE, - parser_node.get_value()); +nodes::Identifier +BuilderTask::operator()( + const ParserNode &parser_node, const Args &) { + Log::Context logc(executor.log(), Log::Area::kTypeCheck); + + return nodes::Identifier{.kind = nodes::Identifier::kSimpleType, + .value = parser_node.get_value()}; } -nodes::Identifier build_typeclass(parser::ParseTree::Node parser_node) { - return nodes::Identifier(build_node(parser_node), - nodes::Identifier::TYPECLASS, - parser_node.get_value()); +nodes::Identifier +BuilderTask::operator()( + const ParserNode &parser_node, const Args &) { + Log::Context logc(executor.log(), Log::Area::kTypeCheck); + + return nodes::Identifier{ + .kind = nodes::Identifier::kTypeclass, + .value = parser_node.get_value(), + }; } -nodes::Identifier build_argument_name(parser::ParseTree::Node parser_node) { - return nodes::Identifier(build_node(parser_node), - nodes::Identifier::ARGUMENT_NAME, - parser_node.get_value()); +nodes::Identifier +BuilderTask::operator()( + const ParserNode &parser_node, const Args &) { + Log::Context logc(executor.log(), Log::Area::kTypeCheck); + + return nodes::Identifier{ + .kind = nodes::Identifier::kArgName, + .value = parser_node.get_value(), + }; } -nodes::Identifier build_argument_type(parser::ParseTree::Node parser_node) { - return nodes::Identifier(build_node(parser_node), - nodes::Identifier::ARGUMENT_TYPE, - parser_node.get_value()); +nodes::Identifier +BuilderTask::operator()( + const ParserNode &parser_node, const Args &) { + Log::Context logc(executor.log(), Log::Area::kTypeCheck); + + return nodes::Identifier{.kind = nodes::Identifier::kArgType, + .value = parser_node.get_value()}; } // Annotations are used as strings -std::string build_annotation(parser::ParseTree::Node parser_node) { +// TODO +nodes::Annotation +BuilderTask::operator()(const ParserNode &parser_node, + const Args &) { + Log::Context logc(executor.log(), Log::Area::kTypeCheck); + std::string identifier = parser_node.get_value(); // identifier.size() > 0 by parsing convention identifier = identifier.substr(1, identifier.size() - 1); - return identifier; + return nodes::Annotation{.value = identifier}; } -nodes::Identifier build_operator(parser::ParseTree::Node parser_node) { +nodes::Identifier +BuilderTask::operator()( + const ParserNode &parser_node, const Args &) { + Log::Context logc(executor.log(), Log::Area::kTypeCheck); + std::string identifier = parser_node.get_value(); // --- points needed for proper printing @@ -295,24 +366,38 @@ nodes::Identifier build_operator(parser::ParseTree::Node parser_node) { // } // --- - return nodes::Identifier(build_node(parser_node), nodes::Identifier::OPERATOR, - identifier); + return nodes::Identifier{.kind = nodes::Identifier::kOperator, + .value = identifier}; } -nodes::Identifier build_placeholder(parser::ParseTree::Node parser_node) { - return nodes::Identifier(build_node(parser_node), - nodes::Identifier::PLACEHOLDER, "_"); +nodes::Identifier +BuilderTask::operator()( + const ParserNode &, const Args &) { + Log::Context logc(executor.log(), Log::Area::kTypeCheck); + + return nodes::Identifier{ + .kind = nodes::Identifier::kPlaceholder, + .value = "_", + }; } // --- extra -nodes::Extra build_extra(parser::ParseTree::Node parser_node) { - return nodes::Extra(build_node(parser_node), parser_node.get_value()); +nodes::Extra +BuilderTask::operator()(const ParserNode &parser_node, + const Args &) { + Log::Context logc(executor.log(), Log::Area::kTypeCheck); + + return nodes::Extra{.content = parser_node.get_value()}; } // --- empty lines -nodes::EmptyLines build_empty_lines(parser::ParseTree::Node parser_node) { +nodes::EmptyLines +BuilderTask::operator()(const ParserNode &parser_node, + const Args &) { + Log::Context logc(executor.log(), Log::Area::kTypeCheck); + std::string empty_lines = parser_node.get_value(); size_t empty_lines_count = 0; @@ -324,11 +409,11 @@ nodes::EmptyLines build_empty_lines(parser::ParseTree::Node parser_node) { } if (empty_lines_count == 0) { - error_handling::handle_parsing_error("Empty lines node with zero new lines", - parser_node); + logc.Fatal({{"Empty lines node with zero new lines"}}, + parser_node.get_pos()); } - return nodes::EmptyLines(build_node(parser_node), empty_lines_count - 1); + return nodes::EmptyLines{.count = empty_lines_count - 1}; } } // namespace builders diff --git a/lang/builders/src/expression_builders.cpp b/lang/builders/src/expression_builders.cpp index 9bb414c..1f48b16 100644 --- a/lang/builders/src/expression_builders.cpp +++ b/lang/builders/src/expression_builders.cpp @@ -2,154 +2,129 @@ #include "basic_builders.hpp" #include "basic_nodes.hpp" -#include "error_handling.hpp" #include "expression_nodes.hpp" +#include "log.hpp" #include "tokens.hpp" #include "type_builders.hpp" #include "type_nodes.hpp" +// TODO: insert is_scoped everywere + namespace builders { -nodes::Expr BuilderTask::operator()(const ParserNode &parser_node, - const Args &) { +Node BuilderTask::operator()(const ParserNode &parser_node, + const Args &) { + Log::Context logc(executor.log(), Log::Area::kParse); + tokens::Type type = tokens::string_to_type(parser_node.get_type()); auto maybe_parenthesis = parser_node.previous_sibling(); + + // FIXME TODO bool is_scoped = (!maybe_parenthesis.is_null() && !maybe_parenthesis.is_named() && maybe_parenthesis.get_value() == "("); - std::optional expr; switch (type) { // --- flow control case tokens::Type::MATCH: - expr = Run(parser_node); - break; + return Run(parser_node, {is_scoped}); case tokens::Type::CONDITION: - return state().add_expr({build_node(parser_node), - Run(parser_node), - is_scoped}); - expr = Run(parser_node); - break; + return Run(parser_node, {is_scoped}); case tokens::Type::LOOP: - return state().add_expr( - {build_node(parser_node), Run(parser_node), is_scoped}); - expr = Run(parser_node); - break; + return Run(parser_node, {is_scoped}); // --- operators case tokens::Type::COMMA_EXPRESSION: - expr = Run(parser_node); - break; + return Run(parser_node, + {is_scoped}); case tokens::Type::OPERATOR_EXPRESSION: - expr = Run(parser_node); - break; + return Run(parser_node, + {is_scoped}); // --- containers case tokens::Type::BLOCK: - expr = Run(parser_node); - break; + return Run(parser_node, {is_scoped}); case tokens::Type::ARRAY: - expr = Run(parser_node); - break; + return Run(parser_node, {is_scoped}); // --- modifiers case tokens::Type::RETURN: - expr = Run(parser_node); - break; + return Run(parser_node, {is_scoped}); case tokens::Type::NAME_DEFINITION: - expr = Run(parser_node); - break; + return Run(parser_node, {is_scoped}); case tokens::Type::ARRAY_ACCESS: - expr = Run(parser_node); - break; + return Run(parser_node, {is_scoped}); case tokens::Type::TUPLE_ACCESS: - expr = Run(parser_node); - break; + return Run(parser_node, {is_scoped}); case tokens::Type::LOOP_CONTROL: - expr = Run(parser_node); - break; + return Run(parser_node, {is_scoped}); case tokens::Type::REFERENCE_EXPRESSION: - expr = Run(parser_node); - break; + return Run(parser_node, + {is_scoped}); case tokens::Type::SUFFIX_EXPRESSION: - expr = Run(parser_node); - break; + return Run(parser_node, + {is_scoped}); // --- other case tokens::Type::NAME_EXPRESSION: - expr = Run(parser_node); - break; + return Run(parser_node, + {is_scoped}); case tokens::Type::ARGUMENT_NAME_IDENTIFIER: case tokens::Type::SIMPLE_NAME_IDENTIFIER: case tokens::Type::PLACEHOLDER: - expr = nodes::NameExpression(build_node(parser_node), - build_identifier(parser_node)); - break; + return Build( + nodes::NameExpression{ + .name = RunOther(parser_node), + }, + parser_node.get_pos()); // TODO: is_scoped case tokens::Type::CONSTRUCTOR: - expr = Run(parser_node); - break; + return Run(parser_node); case tokens::Type::LAMBDA: - expr = Run(parser_node); - break; + return Run(parser_node); // --- literals - case tokens::Type::FLOAT_LITERAL: - expr = build_float_literal(parser_node); - break; - case tokens::Type::DOUBLE_LITERAL: - expr = build_double_literal(parser_node); - break; - case tokens::Type::INT_LITERAL: - expr = build_int_literal(parser_node); - break; - case tokens::Type::LONG_LITERAL: - expr = build_long_literal(parser_node); - break; - case tokens::Type::INDEX_LITERAL: - expr = build_index_literal(parser_node); - break; - case tokens::Type::STRING_LITERAL: - expr = build_string_literal(parser_node); - break; - case tokens::Type::UNICODE_STRING_LITERAL: - expr = build_unicode_string_literal(parser_node); - break; - case tokens::Type::CHAR_LITERAL: - expr = build_char_literal(parser_node); - break; - case tokens::Type::UNICODE_LITERAL: - expr = build_unicode_literal(parser_node); - break; - case tokens::Type::BOOL_LITERAL: - expr = build_bool_literal(parser_node); - break; - case tokens::Type::UNIT_LITERAL: - expr = build_unit_literal(parser_node); - break; - case tokens::Type::NULL_LITERAL: - expr = build_null_literal(parser_node); - break; - case tokens::Type::EXTRA: - expr = build_extra(parser_node); - break; - case tokens::Type::EMPTY_LINES: - expr = build_empty_lines(parser_node); - break; + // TODO: FIXME: + // case tokens::Type::FLOAT_LITERAL: + // return BUILD : build_float_literal(parser_node); + // case tokens::Type::DOUBLE_LITERAL: + // return BUILD : build_double_literal(parser_node); + // case tokens::Type::INT_LITERAL: + // return BUILD : build_int_literal(parser_node); + // case tokens::Type::LONG_LITERAL: + // return BUILD : build_long_literal(parser_node); + // case tokens::Type::INDEX_LITERAL: + // return BUILD : build_index_literal(parser_node); + // case tokens::Type::STRING_LITERAL: + // return BUILD : build_string_literal(parser_node); + // case tokens::Type::UNICODE_STRING_LITERAL: + // return BUILD : build_unicode_string_literal(parser_node); + // case tokens::Type::CHAR_LITERAL: + // return BUILD : build_char_literal(parser_node); + // case tokens::Type::UNICODE_LITERAL: + // return BUILD : build_unicode_literal(parser_node); + // case tokens::Type::BOOL_LITERAL: + // return BUILD : build_bool_literal(parser_node); + // case tokens::Type::UNIT_LITERAL: + // return BUILD : build_unit_literal(parser_node); + // case tokens::Type::NULL_LITERAL: + // return BUILD : build_null_literal(parser_node); + // case tokens::Type::EXTRA: + // return BUILD : build_extra(parser_node); + // case tokens::Type::EMPTY_LINES: + // return BUILD : build_empty_lines(parser_node); default: - utils::Assert(true, - std::format("Unexpected expression node type {}", - static_cast(type))); // TODO: magic_enum - // FIXME: change to fatal error ? + break; } - utils::Assert(expr.has_value(), "Expression should have value"); - - return state().add_expr( - {build_node(parser_node), expr.value(), is_scoped}); + utils::Assert(true, std::format("Unexpected expression node type {}", + static_cast(type))); // TODO: magic_enum + // FIXME: change to fatal error ? + throw std::exception(); } // --- flow control // (':=' | '=:') expression (('??' | 'if') expression)? (_do_ expression)? -nodes::Match::Case -BuilderTask::operator()(const ParserNode &parser_node, - const Args &) { +Node BuilderTask::operator()(const ParserNode &parser_node, + const Args &) { + Log::Context logc(executor.log(), Log::Area::kParse); + std::string case_type = parser_node.nth_child(0).get_value(); std::optional condition_node; @@ -169,49 +144,59 @@ BuilderTask::operator()(const ParserNode &parser_node, } } - return nodes::Match::Case( - build_node(parser_node), - case_type == ":=" ? nodes::Match::Case::PATTERN_VALUE - : nodes::Match::Case::VALUE_PATTERN, - Run(parser_node.nth_named_child(0)), - condition_node.has_value() ? Run(condition_node.value()) - : std::optional(), - expression_node.has_value() ? Run(expression_node.value()) - : std::optional()); + return Build( + nodes::Match::Case{ + .kind = case_type == ":=" ? nodes::Match::Case::PATTERN_VALUE + : nodes::Match::Case::VALUE_PATTERN, + .value = Run(parser_node.nth_named_child(0)), + .condition = condition_node.has_value() + ? Run(condition_node.value()) + : std::optional(), + .expr = expression_node.has_value() + ? Run(expression_node.value()) + : std::optional(), + }, + parser_node.get_pos()); } // expression case+ -nodes::Match -BuilderTask::operator()(const ParserNode &parser_node, - const Args &) { - std::vector cases; +Node BuilderTask::operator()(const ParserNode &parser_node, + const Args &) { + Log::Context logc(executor.log(), Log::Area::kParse); + + std::vector cases; // TODO auto current_node = parser_node.nth_named_child(1); while (!current_node.is_null()) { - cases.push_back(Run(current_node)); + cases.push_back( + Run(current_node, {.is_scoped = false})); current_node = current_node.next_named_sibling(); } - return nodes::Match(build_node(parser_node), - Run(parser_node.nth_named_child(0)), - std::move(cases)); + return Build( + nodes::Match{ + .value = Run(parser_node.nth_named_child(0)), + .cases = std::move(cases), + }, + parser_node.get_pos()); } // ('??' | 'if') expression _do_ expression (('!!' | 'elif') expression _do_ // expression)* (('!!=>', 'else') expression)? -nodes::Condition -BuilderTask::operator()(const ParserNode &parser_node, - const Args &) { +Node BuilderTask::operator()(const ParserNode &parser_node, + const Args &) { + Log::Context logc(executor.log(), Log::Area::kParse); + size_t named_child_count = parser_node.named_child_count(); - std::vector> cases; + std::vector> cases; auto current_node = parser_node.nth_named_child(0); auto next_node = current_node.next_named_sibling(); while (!current_node.is_null() && !next_node.is_null()) { cases.push_back( - {Run(current_node), Run(next_node)}); + {Run(current_node), Run(next_node)}); current_node = next_node.next_named_sibling(); if (current_node.is_null()) { break; @@ -219,97 +204,102 @@ BuilderTask::operator()(const ParserNode &parser_node, next_node = current_node.next_named_sibling(); } - return nodes::Condition( - build_node(parser_node), std::move(cases), - named_child_count % 2 == 1 - ? Run(parser_node.nth_named_child(named_child_count - 1)) - : std::optional()); + return Build( + nodes::Condition{ + .cases = std::move(cases), + .else_case = named_child_count % 2 == 1 + ? Run(parser_node.nth_named_child( + named_child_count - 1)) + : std::optional(), + }, + parser_node.get_pos()); } // ('@' | 'for') (expression | expression ':' expression)? _do_ expression -nodes::Loop BuilderTask::operator()(const ParserNode &parser_node, - const Args &) { +Node BuilderTask::operator()(const ParserNode &parser_node, + const Args &) { + Log::Context logc(executor.log(), Log::Area::kParse); + size_t named_child_count = parser_node.named_child_count(); if (named_child_count == 1) { // body - return nodes::Loop(build_node(parser_node), - Run(parser_node.nth_named_child(0))); + return Build(nodes::Loop(Run(parser_node.nth_named_child(0))), + parser_node.get_pos()); } else if (named_child_count == 2) { // condition, // body - return nodes::Loop(build_node(parser_node), - Run(parser_node.nth_named_child(0)), - Run(parser_node.nth_named_child(1))); + return Build(nodes::Loop(Run(parser_node.nth_named_child(0)), + Run(parser_node.nth_named_child(1))), + parser_node.get_pos()); } else if (named_child_count == 3) { // variable, // interval, // body - 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))); + return Build(nodes::Loop(Run(parser_node.nth_named_child(0)), + Run(parser_node.nth_named_child(1)), + Run(parser_node.nth_named_child(2))), + parser_node.get_pos()); } else { - error_handling::handle_parsing_error("Unex" - "prec" - "ted " - "name" - "d " - "expr" - "essi" - "on " - "amou" - "nt " - "in " - "loo" - "p", - parser_node); + logc.Fatal({{"Unexpected named expression amount in loop"}}, + parser_node.get_pos()); } - error_handling::handle_general_error("Unreac" - "habl" - "e"); + error_handling::handle_general_error("Unreachable"); exit(1); // unreachable } // --- operators // expression ',' expression -nodes::NameExpression -BuilderTask::operator()( +Node BuilderTask::operator()( const ParserNode &parser_node, const Args &) { - std::vector, nodes::Expr>> args; + Log::Context logc(executor.log(), Log::Area::kParse); + + std::vector, storage::Id>> args; args.emplace_back(std::nullopt, - Run(parser_node.nth_named_child(0))); + Run(parser_node.nth_named_child(0))); args.emplace_back(std::nullopt, - Run(parser_node.nth_named_child(1))); + Run(parser_node.nth_named_child(1))); - return nodes::NameExpression( - build_node(parser_node), - nodes::Identifier( - build_node(parser_node), // can't find more precise location - nodes::Identifier::SIMPLE_NAME, ","), - std::move(args), std::nullopt, false, true); + return Build( + nodes::NameExpression{ + .name = + nodes::Identifier{ + // can't find more precise location + .kind = nodes::Identifier::kSimpleName, + .value = ",", + }, + .args = std::move(args), + .prefix = {}, + .is_point_call = false, + .is_operator_call = true, + }, + parser_node.get_pos()); } // expression operator expression -nodes::NameExpression -BuilderTask::operator()( +Node BuilderTask::operator()( const ParserNode &parser_node, const Args &) { - auto name_node = parser_node.child_by_field_name("na" - "m" - "e"); + Log::Context logc(executor.log(), Log::Area::kParse); - std::vector, nodes::Expr>> args; + auto name_node = parser_node.child_by_field_name("name"); + + std::vector, storage::Id>> args; args.emplace_back(std::nullopt, - Run(name_node.previous_named_sibling())); + Run(name_node.previous_named_sibling())); - args.emplace_back(std::nullopt, - Run(name_node.next_named_sibling())); + args.emplace_back(std::nullopt, Run(name_node.next_named_sibling())); - return nodes::NameExpression(build_node(parser_node), - build_operator(name_node), std::move(args), - std::nullopt, false, true); + return Build( + nodes::NameExpression{ + .name = RunOther(name_node), + .args = std::move(args), + .prefix = {}, + .is_point_call = false, + .is_operator_call = true, + }, + parser_node.get_pos()); } // --- continers @@ -319,64 +309,84 @@ BuilderTask::operator()( // --- modifiers // ('return' | 'bring') expression -nodes::Return -BuilderTask::operator()(const ParserNode &parser_node, - const Args &) { +Node BuilderTask::operator()(const ParserNode &parser_node, + const Args &) { + Log::Context logc(executor.log(), Log::Area::kParse); + std::string modifier = parser_node.nth_child(0).get_value(); - return nodes::Return(build_node(parser_node), - modifier == "re" - "tu" - "rn" - ? nodes::Return::RETURN - : nodes::Return::BRING, - Run(parser_node.nth_named_child(0))); + return Build( + nodes::Return{ + .kind = modifier == "return" ? nodes::Return::RETURN + : nodes::Return::BRING, + .expr = Run(parser_node.nth_named_child(0)), + }, + parser_node.get_pos()); } // _var_let_ (simple_name_identifier | placeholder) -nodes::NameDefinition -BuilderTask::operator()(const ParserNode &parser_node, - const Args &) { +Node BuilderTask::operator()( + const ParserNode &parser_node, const Args &) { + Log::Context logc(executor.log(), Log::Area::kParse); + std::string modifier = parser_node.nth_child(0).get_value(); auto name_node = parser_node.nth_named_child(0); - return nodes::NameDefinition(build_node(parser_node), - (modifier == "%" || modifier == "let") - ? nodes::NameDefinition::LET - : nodes::NameDefinition::VAR, - build_identifier(name_node)); + return Build( + nodes::NameDefinition{ + .kind = (modifier == "%" || modifier == "let") + ? nodes::NameDefinition::LET + : nodes::NameDefinition::VAR, + .name = + Run(name_node), + }, + parser_node.get_pos()); } // IN PROGRESS // expression '[' expression ']' -nodes::Access BuilderTask::operator()( +Node BuilderTask::operator()( const ParserNode &parser_node, const Args &) { - return nodes::Access(build_node(parser_node), nodes::Access::ARRAY, - Run(parser_node.nth_named_child(0)), - Run(parser_node.nth_named_child(1))); + Log::Context logc(executor.log(), Log::Area::kParse); + + return Build( + nodes::Access{.kind = nodes::Access::ARRAY, + .value = Run(parser_node.nth_named_child(0)), + .index = Run(parser_node.nth_named_child(1))}, + parser_node.get_pos()); } // expression '.' number_literal -nodes::Access BuilderTask::operator()( +Node BuilderTask::operator()( const ParserNode &parser_node, const Args &) { - return nodes::Access( - build_node(parser_node), nodes::Access::TUPLE, - Run(parser_node.nth_named_child(0)), - state().add_expr( - {build_node(parser_node.nth_named_child(1)), - build_index_literal(parser_node.nth_named_child(1)), false})); + Log::Context logc(executor.log(), Log::Area::kParse); + + auto const node = Build( + nodes::Access{ + .kind = nodes::Access::TUPLE, + .value = Run(parser_node.nth_named_child(0)), + .index = Run(parser_node.nth_named_child(1)), + // TODO: FIXME: + // .index = Build(build_index_literal(parser_node.nth_named_child( + // 1)) /*, false}*/, // ?? is_scoped ?? + }, + parser_node.get_pos()); + + return node; } // 'break' | 'continue' -nodes::LoopControl -BuilderTask::operator()(const ParserNode &parser_node, - const Args &) { - return nodes::LoopControl(build_node(parser_node), - parser_node.get_value() == "br" - "ea" - "k" - ? nodes::LoopControl::BREAK - : nodes::LoopControl::CONTINUE); +Node BuilderTask::operator()(const ParserNode &parser_node, + const Args &) { + Log::Context logc(executor.log(), Log::Area::kParse); + + return Build( + nodes::LoopControl{ + .kind = parser_node.get_value() == "break" + ? nodes::LoopControl::BREAK + : nodes::LoopControl::CONTINUE, + }, + parser_node.get_pos()); } // // ModifierExpression -> .hpp @@ -391,10 +401,12 @@ void build_args_until_end(ParserNode first_parse_node, Executor &executor, while (!current_node.is_null()) { if (tokens::string_to_type(current_node.get_type()) == tokens::Type::ANNOTATION_IDENTIFIER) { - last_annotation = build_annotation(current_node); + last_annotation = + BuilderTask{executor}(current_node, {}) + .value; // TODO } else { args.emplace_back(std::move(last_annotation), - BuilderTask{executor}(current_node, {})); + BuilderTask{executor}(current_node, {})); last_annotation = std::nullopt; } current_node = current_node.next_named_sibling(); @@ -403,18 +415,17 @@ void build_args_until_end(ParserNode first_parse_node, Executor &executor, // (type '.' simple_name | expression '.' simple_name | name | '(' operator // ')') (annotation? expression)* -nodes::NameExpression -BuilderTask::operator()( +Node BuilderTask::operator()( const ParserNode &parser_node, const Args &) { + Log::Context logc(executor.log(), Log::Area::kParse); + std::vector args; std::optional prefix; bool is_point_call = false; - auto name_node = parser_node.child_by_field_name("na" - "m" - "e"); + auto name_node = parser_node.child_by_field_name("name"); std::optional prefix_node; @@ -433,23 +444,30 @@ BuilderTask::operator()( prefix_node = current_node; } else { is_point_call = true; - args.emplace_back(std::nullopt, Run(current_node)); + args.emplace_back(std::nullopt, Run(current_node)); } } build_args_until_end(name_node.next_named_sibling(), executor, args); - return nodes::NameExpression( - build_node(parser_node), build_identifier(name_node), std::move(args), - prefix_node.has_value() ? build_type(prefix_node.value(), state()) - : nodes::MaybeType(), - is_point_call, false); + return Build( + nodes::NameExpression{ + .name = RunOther(name_node), + .args = std::move(args), + .prefix = prefix_node.has_value() + ? build_type(prefix_node.value(), state()) + : nodes::MaybeType(), + .is_point_call = is_point_call, + .is_operator_call = false, + }, + parser_node.get_pos()); } // type (annotation? expression)* -nodes::Constructor -BuilderTask::operator()(const ParserNode &parser_node, - const Args &) { +Node BuilderTask::operator()(const ParserNode &parser_node, + const Args &) { + Log::Context logc(executor.log(), Log::Area::kParse); + std::vector args; build_args_until_end(parser_node @@ -459,31 +477,39 @@ BuilderTask::operator()(const ParserNode &parser_node, .next_named_sibling(), executor, args); - return nodes::Constructor( - build_node(parser_node), - build_type(parser_node.child_by_field_name("type"), state()), - std::move(args)); + return Build( + nodes::Constructor{ + .type = build_type(parser_node.child_by_field_name("type"), + state()), + .args = std::move(args), + }, + parser_node.get_pos()); } // '\\' argument_name* _do_ expression -nodes::Lambda -BuilderTask::operator()(const ParserNode &parser_node, - const Args &) { +Node BuilderTask::operator()(const ParserNode &parser_node, + const Args &) { + Log::Context logc(executor.log(), Log::Area::kParse); + std::vector args; auto current_node = parser_node.nth_child(1); // next to '\\', not null ('=>' should present) while (current_node.is_named()) { // until _do_ - args.emplace_back(build_identifier(current_node)); + args.emplace_back(RunOther(current_node)); current_node = current_node.next_sibling(); } // skip '=>' current_node = current_node.next_named_sibling(); - return nodes::Lambda(build_node(parser_node), std::move(args), - Run(current_node)); + return Build( + nodes::Lambda{ + .args = std::move(args), + .expr = Run(current_node), + }, + parser_node.get_pos()); } } // namespace builders diff --git a/lang/builders/src/statement_builders.cpp b/lang/builders/src/statement_builders.cpp index 88b8776..df1f705 100644 --- a/lang/builders/src/statement_builders.cpp +++ b/lang/builders/src/statement_builders.cpp @@ -4,7 +4,6 @@ #include "basic_nodes.hpp" #include "doc_builders.hpp" #include "doc_nodes.hpp" -#include "error_handling.hpp" #include "expression_builders.hpp" #include "statement_nodes.hpp" #include "tokens.hpp" @@ -22,6 +21,8 @@ namespace builders { nodes::Statements BuilderTask::operator()(const ParserNode &parser_node, const Args &) { + Log::Context logc(executor.log(), Log::Area::kTypeCheck); + std::vector statements; std::optional last_defined_type_name; @@ -39,6 +40,8 @@ BuilderTask::operator()(const ParserNode &parser_node, nodes::Statement BuilderTask::operator()(const ParserNode &parser_node, const Args &) { + Log::Context logc(executor.log(), Log::Area::kTypeCheck); + tokens::Type type = tokens::string_to_type(parser_node.get_type()); std::optional statement_name; @@ -46,45 +49,33 @@ BuilderTask::operator()(const ParserNode &parser_node, switch (type) { case tokens::Type::IMPORT: - statement = nodes::Statement(build_node(parser_node), - Run(parser_node)); - statement_name = *statement.value() - .get() - .value() - ->get_module_name() - ->get(); + statement = nodes::Statement{Run(parser_node)}; + statement_name = + statement.value().get().value()->module_name.value; break; case tokens::Type::TYPE_DEFINITION: - statement = nodes::Statement(build_node(parser_node), - Run(parser_node)); + statement = nodes::Statement{Run(parser_node)}; state().last_defined_type_name = - *statement.value().get().value()->get_name(); - statement_name = *statement.value() - .get() - .value() - ->get_name() - ->get(); + statement.value().get().value()->name; + statement_name = + statement.value().get().value()->name.value; break; case tokens::Type::FUNCTION_DEFINITION: - statement = nodes::Statement(build_node(parser_node), - Run(parser_node)); - statement_name = *statement.value() - .get() - .value() - ->get_full_name() - ->get(); + statement = nodes::Statement{Run(parser_node)}; + statement_name = statement.value() + .get() + .value() + ->full_name.value; break; case tokens::Type::EXTRA: - statement = - nodes::Statement(build_node(parser_node), build_extra(parser_node)); + statement = nodes::Statement{Run(parser_node)}; break; case tokens::Type::EMPTY_LINES: - statement = nodes::Statement(build_node(parser_node), - build_empty_lines(parser_node)); + statement = nodes::Statement{Run(parser_node)}; break; default: - error_handling::handle_parsing_error("Unexprected statement node type", - parser_node); + logc.Fatal({{"Unexprected statement node type"}}, + parser_node.get_pos()); } if (!statement.has_value()) { @@ -97,8 +88,8 @@ BuilderTask::operator()(const ParserNode &parser_node, .insert_combine(statement_name.value(), std::move(statement_copy)) .second != nodes::CombineResult::OK) { // TODO: more detailed errors - error_handling::handle_parsing_error( - "Can't combine statements with same name", parser_node); + logc.Fatal({{"Can't combine statements with same name"}}, + parser_node.get_pos()); } } @@ -109,6 +100,7 @@ BuilderTask::operator()(const ParserNode &parser_node, nodes::Import BuilderTask::operator()(const ParserNode &parser_node, const Args &) { + Log::Context logc(executor.log(), Log::Area::kTypeCheck); auto name_node = parser_node.child_by_field_name("name"); auto module_node = parser_node.child_by_field_name("module"); @@ -120,20 +112,21 @@ BuilderTask::operator()(const ParserNode &parser_node, auto current_node = module_node.next_named_sibling(); while (!current_node.is_null()) { - symbols.push_back(build_identifier(current_node)); + symbols.push_back(Run(current_node)); current_node = current_node.next_named_sibling(); } - return nodes::Import(build_node(parser_node), build_identifier(name_node), - build_identifier(module_node), std::move(symbols)); + return nodes::Import(Run(name_node), + Run(module_node), std::move(symbols)); } // '?' expression nodes::Constraint BuilderTask::operator()(const ParserNode &parser_node, const Args &) { - return nodes::Constraint(build_node(parser_node), - Run(parser_node.nth_named_child(0))); + Log::Context logc(executor.log(), Log::Area::kTypeCheck); + + return nodes::Constraint{.expr = Run(parser_node.nth_named_child(0))}; } parser::ParseTree::Node collect_symbol_doc_nodes( @@ -170,6 +163,8 @@ parser::ParseTree::Node collect_symbol_doc_nodes( nodes::TypeDefinition BuilderTask::operator()(const ParserNode &parser_node, const Args &) { + Log::Context logc(executor.log(), Log::Area::kTypeCheck); + std::optional description_node; std::vector annotation_nodes; @@ -179,16 +174,16 @@ BuilderTask::operator()(const ParserNode &parser_node, bool is_on_heap = !name_node.previous_sibling().is_null() && name_node.previous_sibling().get_value() == "<>"; - nodes::Identifier name = build_identifier(name_node); + nodes::Identifier name = Run(name_node); - bool is_typeclass = (name.get_type() == nodes::Identifier::TYPECLASS); + bool is_typeclass = (name.kind == nodes::Identifier::kTypeclass); // if (is_typeclass && !annotation_nodes.empty()) { - error_handling::handle_parsing_error( - "Typeclass definition can't have annotation documentation", - parser_node); + logc.Fatal( + {{"Typeclass definition can't have annotation documentation"}}, + parser_node.get_pos()); } // @@ -202,10 +197,10 @@ BuilderTask::operator()(const ParserNode &parser_node, while (!current_node.is_null()) { switch (tokens::string_to_type(current_node.get_type())) { case tokens::Type::TYPECLASS_IDENTIFIER: - typeclasses.push_back(build_identifier(current_node)); + typeclasses.push_back(Run(current_node)); break; case tokens::Type::ARGUMENT_TYPE_IDENTIFIER: - args.push_back(build_identifier(current_node)); + args.push_back(Run(current_node)); break; case tokens::Type::VARIANT_TYPE: case tokens::Type::TUPLE_TYPE: @@ -213,33 +208,34 @@ BuilderTask::operator()(const ParserNode &parser_node, case tokens::Type::MODIFIED_TYPE: case tokens::Type::SIMPLE_TYPE: if (type_node.has_value()) { - error_handling::handle_parsing_error( - "More then one type node in type definition", parser_node); + logc.Fatal({{"More then one type node in type definition"}}, + parser_node.get_pos()); } type_node = current_node; break; default: - error_handling::handle_parsing_error( - "Unexprected node type in type definition", parser_node); + logc.Fatal({{"Unexprected node type in type definition"}}, + parser_node.get_pos()); } current_node = current_node.next_named_sibling(); } if (!type_node.has_value() && !annotation_nodes.empty()) { - error_handling::handle_parsing_error( - "Type declaration can't contain annotation documentation", parser_node); + logc.Fatal( + {{"Type declaration can't contain annotation documentation"}}, + parser_node.get_pos()); } if (is_typeclass) { if (!args.empty()) { - error_handling::handle_parsing_error("Typeclass can't have arguments", - parser_node); + logc.Fatal({{"Typeclass can't have arguments"}}, + parser_node.get_pos()); } if (type_node.has_value()) { - error_handling::handle_parsing_error( - "Typeclass can't be type (contain constructors / fields)", - type_node.value()); + logc.Fatal( + {{"Typeclass can't be type (contain constructors / fields)"}}, + type_node.value().get_pos()); } } @@ -255,11 +251,15 @@ BuilderTask::operator()(const ParserNode &parser_node, annotations, annotations.begin())); } - return nodes::TypeDefinition( - build_node(parser_node), - build_symbol_docs(description_node, annotation_nodes, annotations), - is_on_heap, std::move(name), std::move(typeclasses), std::move(args), - type); + return nodes::TypeDefinition{ + .docs = + build_symbol_docs(description_node, annotation_nodes, annotations), + .is_on_heap = is_on_heap, + .name = std::move(name), + .typeclasses = std::move(typeclasses), + .args = std::move(args), + .type = type, + }; } // definition_info? annotation_info* (constraint ';')* '.'? (simple_name @@ -268,6 +268,8 @@ BuilderTask::operator()(const ParserNode &parser_node, // (((block | array) | '=' expression ';') | ';') nodes::FunctionDefinition BuilderTask::operator()( const ParserNode &parser_node, const Args &) { + Log::Context logc(executor.log(), Log::Area::kTypeCheck); + // const std::optional &last_defined_type_name, // TODO std::optional description_node; @@ -296,8 +298,8 @@ nodes::FunctionDefinition BuilderTask::operator()( is_method = true; if (!state().last_defined_type_name.has_value()) { - error_handling::handle_parsing_error( - "Can't define method without associated type", parser_node); + logc.Fatal({{"Can't define method without associated type"}}, + parser_node.get_pos()); } name_prefix = state().last_defined_type_name.value(); @@ -307,7 +309,7 @@ nodes::FunctionDefinition BuilderTask::operator()( current_node = name_node.next_sibling(); if (!current_node.is_null() && !current_node.is_named()) { - return_modifier = build_modifier(current_node); + return_modifier = Run(current_node); // only optional, result allowed if (!nodes::utils::is_suffix_modifier(return_modifier)) { @@ -333,7 +335,7 @@ nodes::FunctionDefinition BuilderTask::operator()( // update last before modifier auto maybe_reference_node = current_node.previous_sibling(); if (!maybe_reference_node.is_null() && !maybe_reference_node.is_named()) { - last_before_modifier = build_modifier(maybe_reference_node); + last_before_modifier = Run(maybe_reference_node); // only out, in, ref allowed if (nodes::utils::is_suffix_modifier(last_before_modifier)) { @@ -343,13 +345,13 @@ nodes::FunctionDefinition BuilderTask::operator()( switch (tokens::string_to_type(current_node.get_type())) { case tokens::Type::ANNOTATION_IDENTIFIER: - last_annotation = build_annotation(current_node); + last_annotation = Run(current_node).value; // TODO break; case tokens::Type::ARGUMENT_NAME_IDENTIFIER: // update last after modifier maybe_reference_node = current_node.next_sibling(); if (!maybe_reference_node.is_null() && !maybe_reference_node.is_named()) { - last_after_modifier = build_modifier(maybe_reference_node); + last_after_modifier = Run(maybe_reference_node); // only optional, result allowed if (!nodes::utils::is_suffix_modifier(last_after_modifier)) { @@ -363,8 +365,8 @@ nodes::FunctionDefinition BuilderTask::operator()( } args.push_back(nodes::FunctionDefinition::Argument( - last_annotation, build_identifier(current_node), last_before_modifier, - last_after_modifier)); + last_annotation, Run(current_node), + last_before_modifier, last_after_modifier)); last_annotation = std::nullopt; break; @@ -381,12 +383,12 @@ nodes::FunctionDefinition BuilderTask::operator()( if (!args[current_type_id].add_type( last_annotation, build_type(current_node, state()), last_before_modifier)) { - error_handling::handle_parsing_error( - "It is impossible to use argument modifiers (annotations, " - "references, " - "optional markers, result markers) when types explicitely " - "defined. Use type annotations instead.", - current_node); + logc.Fatal( + {{"It is impossible to use argument modifiers (annotations, " + "references, " + "optional markers, result markers) when types explicitely " + "defined. Use type annotations instead."}}, + current_node.get_pos()); } } @@ -396,9 +398,9 @@ nodes::FunctionDefinition BuilderTask::operator()( break; default: if (expression_node.has_value()) { - error_handling::handle_parsing_error( - "More then one expression found in function definition", - parser_node); + logc.Fatal( + {{"More then one expression found in function definition"}}, + parser_node.get_pos()); } expression_node = current_node; break; @@ -407,15 +409,16 @@ nodes::FunctionDefinition BuilderTask::operator()( } if (current_type_id > 0 && current_type_id < args.size()) { - error_handling::handle_parsing_error( - "Less types then arguments in function definition", parser_node); + logc.Fatal( + {{"Less types then arguments in function definition"}}, + parser_node.get_pos()); } if (current_type_id == 0 && !expression_node.has_value()) { - error_handling::handle_parsing_error( - "Can't declare function without types (types or function body should " - "be added)", - parser_node); + logc.Fatal( + {{"Can't declare function without types (types or function body should " + "be added)"}}, + parser_node.get_pos()); } // automatic annotations @@ -424,13 +427,13 @@ nodes::FunctionDefinition BuilderTask::operator()( if (are_annotations_same_to_names) { for (size_t i = 0; i < args.size(); ++i) { - std::string new_annotation = *args[i].get_name().value()->get(); + std::string new_annotation = args[i].get_name().value()->value; if (!args[i].add_annotation( new_annotation.substr(1, new_annotation.size() - 1))) { - error_handling::handle_parsing_error( - "no annotations provided ( => all annotations same to names), but " - "can't add name annotation", - current_node); + logc.Fatal({{"no annotations provided ( => all annotations " + "same to names), but " + "can't add name annotation"}}, + current_node.get_pos()); } } } @@ -439,21 +442,20 @@ nodes::FunctionDefinition BuilderTask::operator()( for (auto &arg : args) { if (arg.get_annotation().has_value()) { if (!annotations_set.insert(*arg.get_annotation().value()).second) { - error_handling::handle_parsing_error( - "Two or more same annotations found in function definition", - parser_node); + logc.Fatal( + {{"Two or more same annotations found in function definition"}}, + parser_node.get_pos()); } } } return nodes::FunctionDefinition( - build_node(parser_node), build_symbol_docs(description_node, annotation_nodes, annotations_set), std::move(constraints), return_modifier, is_method, name_prefix, - build_identifier(name_node), std::move(args), + Run(name_node), std::move(args), are_annotations_same_to_names, - expression_node.has_value() ? Run(expression_node.value()) - : std::optional()); + expression_node.has_value() ? Run(expression_node.value()) + : std::optional()); } } // namespace builders diff --git a/lang/nodes/include/basic_nodes.hpp b/lang/nodes/include/basic_nodes.hpp index ee0b86f..85b513d 100644 --- a/lang/nodes/include/basic_nodes.hpp +++ b/lang/nodes/include/basic_nodes.hpp @@ -151,37 +151,37 @@ inline bool can_cast_modifier(Modifier from, Modifier to) { } // namespace utils -class Node { -public: - Node() : undefined_(true) {} +// class Node { +// public: +// Node() : undefined_(true) {} - Node(std::pair start_position, - std::pair end_position) - : undefined_(false), start_position_(start_position), - end_position_(end_position) {} +// Node(std::pair start_position, +// std::pair end_position) +// : undefined_(false), start_position_(start_position), +// end_position_(end_position) {} - std::pair get_start_position() const { - if (undefined_) { - error_handling::handle_general_error( - "Get start position from undefined node"); - } - return start_position_; - } +// std::pair get_start_position() const { +// if (undefined_) { +// error_handling::handle_general_error( +// "Get start position from undefined node"); +// } +// return start_position_; +// } - std::pair get_end_position() const { - if (undefined_) { - error_handling::handle_general_error( - "Get end position from undefined node"); - } - return end_position_; - } +// std::pair get_end_position() const { +// if (undefined_) { +// error_handling::handle_general_error( +// "Get end position from undefined node"); +// } +// return end_position_; +// } -protected: - bool undefined_ = false; +// protected: +// bool undefined_ = false; - std::pair start_position_ = {0, 0}; - std::pair end_position_ = {0, 0}; -}; +// std::pair start_position_ = {0, 0}; +// std::pair end_position_ = {0, 0}; +// }; struct unit {}; struct null {}; @@ -194,162 +194,121 @@ struct unicode { std::string ch; }; -class Literal : public Node { +struct Literal { public: using Type = std::variant; - template - Literal(Node node, T &&value) : Node(node), value_(std::forward(value)) {} - template std::optional get() { - if (std::holds_alternative(value_)) { - return &std::get(value_); + if (std::holds_alternative(value)) { + return &std::get(value); } return std::nullopt; } template std::optional get() const { - if (std::holds_alternative(value_)) { - return &std::get(value_); + if (std::holds_alternative(value)) { + return &std::get(value); } return std::nullopt; } - Type &get_any() { return value_; } + // - const Type &get_any() const { return value_; } - -private: - Type value_; + Type value; }; -class Identifier : public Node { -public: - static constexpr char NAME_DELIMITER = '.'; +// TODO: merge with identifier ?? +struct Annotation { + auto operator<=>(const Annotation &other) const = default; - enum IdentifierType { - SIMPLE_NAME, - SIMPLE_TYPE, - TYPECLASS, - ARGUMENT_NAME, - ARGUMENT_TYPE, + std::string value; +}; + +struct Identifier { +public: + static constexpr char kNameDelimiter = '.'; + + enum Kind { + kSimpleName, + kSimpleType, + kTypeclass, + kArgName, + kArgType, // ANNOTATION, used as std::string - OPERATOR, - PLACEHOLDER, + kOperator, + kPlaceholder, // - GENERIC_TYPE, + kGenericType, }; - Identifier(Node node, IdentifierType type, std::string &&value) - : Node(node), type_(type), value_(std::move(value)) {} + // - Identifier(Node node, IdentifierType type, const std::string &value) - : Node(node), type_(type), value_(value) {} - - IdentifierType get_type() const { return type_; } + auto operator<=>(const Identifier &other) const = default; // - std::string *get() { return &value_; } + Kind kind; + std::string value; - const std::string *get() const { return &value_; } + // TODO - // + // void append_before(const std::string &name) { + // value_ = name + NAME_DELIMITER + value_; + // } - void append_before(const std::string &name) { - value_ = name + NAME_DELIMITER + value_; - } + // void append_before( + // const Identifier &identifier, + // std::source_location location = std::source_location::current()) { + // error_handling::expect(identifier.type_ == type_, + // "different Identifier types on append_before", + // location); + // value_ = *identifier.get() + NAME_DELIMITER + value_; + // } - void append_before( - const Identifier &identifier, - std::source_location location = std::source_location::current()) { - error_handling::expect(identifier.type_ == type_, - "different Identifier types on append_before", - location); - value_ = *identifier.get() + NAME_DELIMITER + value_; - } + // void append_after(const std::string &name) { + // value_ += NAME_DELIMITER + name; + // } - void append_after(const std::string &name) { - value_ += NAME_DELIMITER + name; - } + // void append_after( + // const Identifier &identifier, + // std::source_location location = std::source_location::current()) { + // error_handling::expect(identifier.type_ == type_, + // "different Identifier types on append_after", + // location); + // value_ += NAME_DELIMITER + *identifier.get(); + // } - void append_after( - const Identifier &identifier, - std::source_location location = std::source_location::current()) { - error_handling::expect(identifier.type_ == type_, - "different Identifier types on append_after", - location); - value_ += NAME_DELIMITER + *identifier.get(); - } + // std::vector get_fragments() const { + // std::vector fragments; + // for (auto &&fragment_name : + // std::ranges::views::split(value_, NAME_DELIMITER)) { + // fragments.emplace_back( + // *this, type_, + // std::string(fragment_name.begin(), fragment_name.end())); + // } + // return fragments; + // } - std::vector get_fragments() const { - std::vector fragments; - for (auto &&fragment_name : - std::ranges::views::split(value_, NAME_DELIMITER)) { - fragments.emplace_back( - *this, type_, - std::string(fragment_name.begin(), fragment_name.end())); - } - return fragments; - } - - std::pair split_first() { - const auto pos = value_.find(NAME_DELIMITER); - if (pos == std::string::npos) { - return {Identifier(*this, type_, ""), *this}; - } - return { - Identifier(*this, type_, value_.substr(0, pos)), - Identifier(*this, type_, value_.substr(pos + 1))}; // '.' is leaved out - } - - // - - bool operator==(const Identifier &other_identifier) const { - return type_ == other_identifier.type_ && value_ == other_identifier.value_; - } - - bool operator!=(const Identifier &other_identifier) const { - return !(*this == other_identifier); - } - - bool operator<(const Identifier &other_identifier) const { - return type_ < other_identifier.type_ || (type_ == other_identifier.type_ && - value_ < other_identifier.value_); - } - -private: - IdentifierType type_; - std::string value_; + // std::pair split_first() { + // const auto pos = value_.find(NAME_DELIMITER); + // if (pos == std::string::npos) { + // return {Identifier(*this, type_, ""), *this}; + // } + // return { + // Identifier(*this, type_, value_.substr(0, pos)), + // Identifier(*this, type_, value_.substr(pos + 1))}; // '.' is leaved + // out + // } }; -class Extra : public Node { -public: - Extra(Node node, std::string &&content) - : Node(node), content_(std::move(content)) {} - - Extra(Node node, const std::string &content) - : Node(node), content_(content) {} - - std::string *content() { return &content_; } - - const std::string *content() const { return &content_; } - -private: - std::string content_; +struct Extra { + std::string content; }; -class EmptyLines : public Node { -public: - EmptyLines(Node node, size_t line_count) - : Node(node), line_count_(line_count) {} - - size_t line_count() const { return line_count_; } - -private: - size_t line_count_; +struct EmptyLines { + size_t count; }; } // namespace nodes diff --git a/lang/nodes/include/expression_nodes.hpp b/lang/nodes/include/expression_nodes.hpp index 24e5bc5..d1640a6 100644 --- a/lang/nodes/include/expression_nodes.hpp +++ b/lang/nodes/include/expression_nodes.hpp @@ -1,6 +1,7 @@ #pragma once #include "basic_nodes.hpp" +#include "storage.hpp" #include "type_nodes.hpp" #include @@ -9,504 +10,190 @@ namespace nodes { -class TypedNode : public Node { -public: - TypedNode(Node node) : Node(node) {} - - void set_expression_type(Type expression_type) { - expression_type_ = expression_type; - } - - std::optional get_expression_type() const { return expression_type_; } - -protected: - std::optional expression_type_; -}; +using NodeId = storage::Id; class ExprData; -class ExprStorage; -class Expr { - friend ExprStorage; - -public: - Expr() = delete; - - ExprData *get(); - - const ExprData *get() const; - -private: - Expr(ExprStorage &expression_storage, size_t id) - : expression_storage_(&expression_storage), id_(id) {} - -private: - ExprStorage *expression_storage_; - size_t id_; +// TODO: add to all nodes +struct GeneralInfo { + bool is_scoped; }; -namespace utils { +// namespace utils { -inline std::optional -proxy_to_expr_optional(std::optional &proxy) { - if (proxy.has_value()) { - return proxy.value().get(); - } - return std::nullopt; -} +// inline std::optional +// proxy_to_expr_optional(std::optional &proxy) { +// if (proxy.has_value()) { +// return proxy.value().get(); +// } +// return std::nullopt; +// } -inline std::optional -proxy_to_expr_optional(const std::optional &proxy) { - if (proxy.has_value()) { - return proxy.value().get(); - } - return std::nullopt; -} +// inline std::optional +// proxy_to_expr_optional(const std::optional &proxy) { +// if (proxy.has_value()) { +// return proxy.value().get(); +// } +// return std::nullopt; +// } -} // namespace utils +// } // namespace utils // --- flow control -class Match : public TypedNode { -public: - class Case : public TypedNode { - public: - enum CaseType { +struct Match { + struct Case { + enum Kind { PATTERN_VALUE, VALUE_PATTERN, }; - Case(Node node, CaseType case_type, Expr value, - std::optional condition = std::nullopt, - std::optional expression = std::nullopt) - : TypedNode(node), case_type_(case_type), value_(value), - condition_(condition), expression_(expression) {} + // - CaseType case_type() const { return case_type_; } - - ExprData *get_value() { return value_.get(); } - - const ExprData *get_value() const { return value_.get(); } - - std::optional get_condition() { - return utils::proxy_to_expr_optional(condition_); - } - - std::optional get_condition() const { - return utils::proxy_to_expr_optional(condition_); - } - - std::optional get_expression() { - return utils::proxy_to_expr_optional(expression_); - } - - std::optional get_expression() const { - return utils::proxy_to_expr_optional(expression_); - } - - private: - CaseType case_type_; - Expr value_; - std::optional condition_; - std::optional expression_; + Kind kind; + NodeId value; + std::optional condition; + std::optional expr; }; - Match(Node node, Expr value, std::vector &&cases) - : TypedNode(node), value_(value), cases_(std::move(cases)) {} + // - Match(Node node, Expr value, const std::vector &cases) - : TypedNode(node), value_(value), cases_(cases) {} - - ExprData *get_value() { return value_.get(); } - - const ExprData *get_value() const { return value_.get(); } - - size_t cases_size() const { return cases_.size(); } - - Case *get_case(size_t id) { return &cases_.at(id); } - - const Case *get_case(size_t id) const { return &cases_.at(id); } - -private: - Expr value_; - std::vector cases_; + NodeId value; + std::vector cases; }; -class Condition : public Node { -public: - Condition(Node node, std::vector> &&cases, - std::optional else_case = std::nullopt) - : Node(node), cases_(std::move(cases)), else_case_(else_case) {} - - Condition(Node node, const std::vector> &cases, - std::optional else_case = std::nullopt) - : Node(node), cases_(cases), else_case_(else_case) {} - - size_t cases_size() const { return cases_.size(); } - - std::pair get_case(size_t id) { - return {cases_.at(id).first.get(), cases_[id].second.get()}; - } - - std::pair get_case(size_t id) const { - return {cases_.at(id).first.get(), cases_[id].second.get()}; - } - - std::optional get_else_case() { - return utils::proxy_to_expr_optional(else_case_); - } - - std::optional get_else_case() const { - return utils::proxy_to_expr_optional(else_case_); - } - -private: - std::vector> cases_; - std::optional else_case_; +struct Condition { + std::vector> cases; + std::optional else_case; }; -class Loop : public TypedNode { +// TODO: prittier constructors +struct Loop { public: - enum LoopType { + enum Kind { LOOP, WHILE, FOR, }; + // + // LOOP - Loop(Node node, Expr expression) - : TypedNode(node), loop_type_(LOOP), expression_(expression) {} + Loop(NodeId expr) : kind(LOOP), expr(expr) {} // WHILE - Loop(Node node, Expr condition, Expr expression) - : TypedNode(node), loop_type_(WHILE), expression_(expression), - condition_(condition) {} + Loop(NodeId condition, NodeId expr) + : kind(WHILE), expr(expr), condition(condition) {} // FOR - Loop(Node node, Expr variable, Expr interval, Expr expression) - : TypedNode(node), loop_type_(FOR), expression_(expression), - variable_(variable), interval_(interval) {} + Loop(NodeId variable, NodeId interval, NodeId expr) + : kind(FOR), expr(expr), variable(variable), interval(interval) {} - LoopType get_type() const { return loop_type_; } + // - ExprData *get_expression() { return expression_.get(); } + Kind kind; + NodeId expr; - const ExprData *get_expression() const { return expression_.get(); } - - std::optional get_condition() { - return utils::proxy_to_expr_optional(condition_); - } - - std::optional get_condition() const { - return utils::proxy_to_expr_optional(condition_); - } - - std::optional get_variable() { - return utils::proxy_to_expr_optional(variable_); - } - - std::optional get_variable() const { - return utils::proxy_to_expr_optional(variable_); - } - - std::optional get_interval() { - return utils::proxy_to_expr_optional(interval_); - } - - std::optional get_interval() const { - return utils::proxy_to_expr_optional(interval_); - } - -private: - LoopType loop_type_; - - Expr expression_; - - std::optional condition_; - std::optional variable_; - std::optional interval_; + std::optional condition; + std::optional variable; + std::optional interval; }; // --- containers -class Container : public TypedNode { -public: - enum ContainerType { +struct Container { + enum Kind { BLOCK, ARRAY, }; - Container(Node node, ContainerType type, std::vector &&expressions) - : TypedNode(node), container_type_(type), - expressions_(std::move(expressions)) {} + // - Container(Node node, ContainerType type, const std::vector &expressions) - : TypedNode(node), container_type_(type), expressions_(expressions) {} - - ContainerType get_type() const { return container_type_; } - - size_t expressions_size() const { return expressions_.size(); } - - ExprData *get_expression(size_t id) { return expressions_.at(id).get(); } - - const ExprData *get_expression(size_t id) const { - return expressions_.at(id).get(); - } - -private: - ContainerType container_type_; - - std::vector expressions_; + Kind kind; + std::vector exprs; }; // --- modifiers -class Return : public Node { -public: - enum ReturnType { +struct Return { + enum Kind { RETURN, BRING, }; - Return(Node node, ReturnType type, Expr expression) - : Node(node), return_type_(type), expression_(expression) {} + // - ReturnType get_type() const { return return_type_; } - - ExprData *get_expression() { return expression_.get(); } - - const ExprData *get_expression() const { return expression_.get(); } - -private: - ReturnType return_type_; - - Expr expression_; + Kind kind; + NodeId expr; }; -class NameDefinition : public TypedNode { -public: - enum Modifier { +struct NameDefinition { + enum Kind { LET, // % VAR, // $ }; - NameDefinition(Node node, Modifier modifier, Identifier &&name) - : TypedNode(node), modifier_(modifier), name_(std::move(name)) {} + // - NameDefinition(Node node, Modifier modifier, const Identifier &name) - : TypedNode(node), modifier_(modifier), name_(name) {} - - Modifier get_modifier() const { return modifier_; } - - Identifier *get_name() { return &name_; } - - const Identifier *get_name() const { return &name_; } - -private: - Modifier modifier_; - - Identifier name_; + Kind kind; + Identifier name; }; -class Access : public TypedNode { -public: - enum AccessType { +struct Access { + enum Kind { ARRAY, TUPLE, // only number literal index allowed }; - Access(Node node, AccessType type, Expr value, Expr index) - : TypedNode(node), access_type_(type), value_(value), index_(index) {} + // - AccessType get_type() const { return access_type_; } + Kind kind; - ExprData *get_value() { return value_.get(); } - - const ExprData *get_value() const { return value_.get(); } - - ExprData *get_index() { return index_.get(); } - - const ExprData *get_index() const { return index_.get(); } - -private: - AccessType access_type_; - - Expr value_; - Expr index_; + NodeId value; + NodeId index; }; -class LoopControl : public TypedNode { -public: - enum LoopControlType { +struct LoopControl { + enum Kind { BREAK, CONTINUE, }; - LoopControl(Node node, LoopControlType type) - : TypedNode(node), loop_control_type_(type) {} + // - LoopControlType get_type() const { return loop_control_type_; } - -private: - LoopControlType loop_control_type_; + Kind kind; }; -class ModifierExpression : public TypedNode { -public: - ModifierExpression(Node node, Modifier modifier, Expr expression) - : TypedNode(node), modifier_(modifier), expression_(expression) {} - - Modifier get_modifier() const { return modifier_; } - - ExprData *get_expression() { return expression_.get(); } - - const ExprData *get_expression() const { return expression_.get(); } - -private: - Modifier modifier_; - - Expr expression_; +struct ModifierExpression { + Modifier modifier; + NodeId expr; }; // --- other -using AnnotatedArgument = std::pair, Expr>; +using AnnotatedArgument = std::pair, NodeId>; -class NameExpression : public TypedNode { -public: - NameExpression(Node node, Identifier &&name) - : TypedNode(node), name_(std::move(name)) {} - - NameExpression(Node node, const Identifier &name) - : TypedNode(node), name_(name) {} - - NameExpression(Node node, Identifier &&name, - std::vector &&args, - std::optional &&prefix, bool is_point_call = false, - bool is_operator_call = false) - : TypedNode(node), name_(std::move(name)), args_(std::move(args)), - prefix_(std::move(prefix)), is_point_call_(is_point_call), - is_operator_call_(is_operator_call) {} - - Identifier *get_name() { return &name_; } - - const Identifier *get_name() const { return &name_; } - - std::optional get_prefix() { - if (prefix_.has_value()) { - return prefix_.value().get(); - } - return std::nullopt; - } - - std::optional get_prefix() const { - if (prefix_.has_value()) { - return prefix_.value().get(); - } - return std::nullopt; - } - - size_t args_size() const { return args_.size(); } - - ExprData *get_argument_value(size_t id) { return args_.at(id).second.get(); } - - const ExprData *get_argument_value(size_t id) const { - return args_.at(id).second.get(); - } - - std::optional get_argument_annotation(size_t id) { - if (args_.at(id).first.has_value()) { - return &args_[id].first.value(); - } - return std::nullopt; - } - - std::optional get_argument_annotation(size_t id) const { - if (args_.at(id).first.has_value()) { - return &args_[id].first.value(); - } - return std::nullopt; - } - - bool is_point_call() const { return is_point_call_; } - - bool is_operator_call() const { return is_operator_call_; } - -private: - Identifier name_; +struct NameExpression { + Identifier name; // universal function call syntax - std::vector args_; - std::optional prefix_; + std::vector args = {}; + std::optional prefix = {}; // for static methods - bool is_point_call_ = false; // x.f ... or f x ... - bool is_operator_call_ = false; // ... operator ... + bool is_point_call = false; // x.f ... or f x ... + bool is_operator_call = false; // ... operator ... }; -class Constructor : public TypedNode { -public: - Constructor(Node node, Type type, std::vector &&args) - : TypedNode(node), constructor_type_(type), args_(std::move(args)) {} - - Constructor(Node node, Type type, const std::vector &args) - : TypedNode(node), constructor_type_(type), args_(args) {} - - TypeData *get_type() { return constructor_type_.get(); } - - const TypeData *get_type() const { return constructor_type_.get(); } - - Type get_type_proxy() const { return constructor_type_; } - - size_t args_size() const { return args_.size(); } - - ExprData *get_argument_value(size_t id) { return args_.at(id).second.get(); } - - const ExprData *get_argument_value(size_t id) const { - return args_.at(id).second.get(); - } - - std::optional get_argument_annotation(size_t id) { - if (args_.at(id).first.has_value()) { - return &args_[id].first.value(); - } - return std::nullopt; - } - - std::optional get_argument_annotation(size_t id) const { - if (args_.at(id).first.has_value()) { - return &args_[id].first.value(); - } - return std::nullopt; - } - -private: - Type constructor_type_; - std::vector, Expr>> args_; +struct Constructor { + Type type; + std::vector args; }; -class Lambda : public TypedNode { -public: - Lambda(Node node, std::vector &&args, Expr expression) - : TypedNode(node), args_(std::move(args)), expression_(expression) {} - - Lambda(Node node, const std::vector &args, Expr expression) - : TypedNode(node), args_(args), expression_(expression) {} - - size_t args_size() const { return args_.size(); } - - Identifier *get_argument(size_t id) { return &args_.at(id); } - - const Identifier *get_argument(size_t id) const { return &args_.at(id); } - - ExprData *get_expression() { return expression_.get(); } - - const ExprData *get_expression() const { return expression_.get(); } - -private: - std::vector args_; - Expr expression_; +struct Lambda { + std::vector args; + NodeId expr; }; -class ExprData : public Node { +class ExprData { public: using Type = std::variant< // --- flow control @@ -542,9 +229,8 @@ public: public: template - ExprData(Node node, T &&expression, bool is_scoped) - : Node(node), expression_(std::forward(expression)), - is_scoped_(is_scoped) {} + ExprData(T &&expression, bool is_scoped) + : expression_(std::forward(expression)), is_scoped_(is_scoped) {} template std::optional get() { if (std::holds_alternative(expression_)) { @@ -572,22 +258,22 @@ private: bool is_scoped_ = false; }; -class ExprStorage { - friend Expr; +// class ExprStorage { +// friend Expr; -public: - Expr add_expr(ExprData expression) { - storage_.push_back(std::move(expression)); - return Expr(*this, storage_.size() - 1); - } +// public: +// Expr add_expr(ExprData expression) { +// storage_.push_back(std::move(expression)); +// return Expr(*this, storage_.size() - 1); +// } -private: - ExprData *get_expr(size_t id) { return &storage_.at(id); } +// private: +// ExprData *get_expr(size_t id) { return &storage_.at(id); } - const ExprData *get_expr(size_t id) const { return &storage_.at(id); } +// const ExprData *get_expr(size_t id) const { return &storage_.at(id); } -private: - std::vector storage_; -}; +// private: +// std::vector storage_; +// }; } // namespace nodes diff --git a/lang/nodes/include/nodes_storage.hpp b/lang/nodes/include/nodes_storage.hpp index b31d26f..135416a 100644 --- a/lang/nodes/include/nodes_storage.hpp +++ b/lang/nodes/include/nodes_storage.hpp @@ -1,15 +1,38 @@ #pragma once +#include "expression_nodes.hpp" #include "storage.hpp" namespace nodes { -// FIXME -struct NodeData { - std::variant value; -}; // TODO: union with nodes +template class Node_; + +struct NodeData { +public: + template NodeData(T value) : value(std::move(value)) {} + + template std::optional get() { + if (std::holds_alternative(value)) { + return &std::get(value); + } + return std::nullopt; + } + + template std::optional get() const { + if (std::holds_alternative(value)) { + return &std::get(value); + } + return std::nullopt; + } + + template bool Holds() const { + return std::holds_alternative(value); + } + +public: + nodes::ExprData::Type value; +}; -// TODO: replace NodeData with real node class NodeStorage : public core::Storage { using Id = storage::Id; @@ -36,7 +59,7 @@ protected: core::DependentStorage &data_; }; -// TODO: replace all nodes +// FIXME: rename // Mixins should be NodePart<...> or their children template class Node_ : public Mixins... { using Id = storage::Id; @@ -45,9 +68,13 @@ public: Node_(Id id, NodeStorage &data, Mixins &&...mixins) : Mixins(std::move(mixins))..., id_(id), data_(data) {} + operator Id() const { return id(); } + // - template bool &Has() { return NodePart::data_.Has(id_); } + template bool &Has() const { + return NodePart::data_.Has(id_); + } // @@ -55,6 +82,12 @@ public: template T &get() { return std::get(data_[id_].value); } + Id id() const { return id_; } + + template bool Holds() const { + return operator*().template Holds(); + } + // const NodeData &operator*() const { return data_[id_]; } diff --git a/lang/nodes/include/statement_nodes.hpp b/lang/nodes/include/statement_nodes.hpp index e26c992..d8a3e1e 100644 --- a/lang/nodes/include/statement_nodes.hpp +++ b/lang/nodes/include/statement_nodes.hpp @@ -27,54 +27,17 @@ enum class CombineResult { }; // IN PROGRESS: add another constructors ?? -class Import : public Node { -public: - Import(Node node, const Identifier &import_name, - const Identifier &module_name, std::vector &&symbols = {}) - : Node(node), import_name_(import_name), module_name_(module_name), - symbols_(std::move(symbols)) {} - - // - - Identifier *get_import_name() { return &import_name_; } - - const Identifier *get_import_name() const { return &import_name_; } - - // - - Identifier *get_module_name() { return &module_name_; } - - const Identifier *get_module_name() const { return &module_name_; } - - // - - size_t symbols_size() const { return symbols_.size(); } - - Identifier *get_symbol(size_t id) { return &symbols_.at(id); } - - const Identifier *get_symbol(size_t id) const { return &symbols_.at(id); } - -private: - Identifier import_name_; - Identifier module_name_; - std::vector symbols_; +struct Import { + Identifier import_name; + Identifier module_name; + std::vector symbols; }; -class Constraint : public Node { -public: - Constraint(Node node, Expr expression) - : Node(node), expression_(expression) {} - - ExprData *get_expression() { return expression_.get(); } - - const ExprData *get_expression() const { return expression_.get(); } - -private: - Expr expression_; +struct Constraint { + NodeId expr; }; -class FunctionDefinition : public Node { -public: +struct FunctionDefinition { class Argument { public: Argument(const std::optional &annotation, Identifier &&name, @@ -242,151 +205,43 @@ public: Modifier::NONE; // optional, result, none // sync with type }; - FunctionDefinition(Node node, SymbolDocs &&docs, - std::vector &&constraints, + FunctionDefinition(SymbolDocs &&docs, std::vector &&constraints, Modifier return_modifier, bool is_method, const std::optional &name_prefix, const Identifier &name, std::vector &&args, bool are_annotations_same_to_names, - std::optional expression) - : Node(node), docs_(std::move(docs)), - constraints_(std::move(constraints)), return_modifier_(return_modifier), - is_method_(is_method), name_(name), full_name_(name), - args_(std::move(args)), - are_annotations_same_to_names_(are_annotations_same_to_names), - expression_(expression) { + std::optional expr) + : docs(std::move(docs)), constraints(std::move(constraints)), + return_modifier(return_modifier), is_method(is_method), name(name), + full_name(name), args(std::move(args)), + are_annotations_same_to_names(are_annotations_same_to_names), + expr(expr) { if (name_prefix.has_value()) { - full_name_.append_before(*name_prefix.value().get()); + full_name.append_before(name_prefix.value().value); } } // - SymbolDocs *get_docs() { return &docs_; } - - const SymbolDocs *get_docs() const { return &docs_; } - - // - - size_t constraints_size() const { return constraints_.size(); } - - Constraint *get_constraint(size_t id) { return &constraints_.at(id); } - - const Constraint *get_constraint(size_t id) const { - return &constraints_.at(id); - } - - // - - Modifier get_return_modifier() const { return return_modifier_; } - - bool is_method() const { return is_method_; } - - // - - Identifier *get_name() { return &name_; } - - const Identifier *get_name() const { return &name_; } - - // - - Identifier *get_full_name() { return &full_name_; } - - const Identifier *get_full_name() const { return &full_name_; } - - // - - size_t args_size() const { return args_.size(); } - - Argument *get_argument(size_t id) { return &args_.at(id); } - - const Argument *get_argument(size_t id) const { return &args_.at(id); } - - // - - std::optional get_expression() { - if (expression_.has_value()) { - return expression_.value().get(); - } - return std::nullopt; - } - - std::optional get_expression() const { - if (expression_.has_value()) { - return expression_.value().get(); - } - return std::nullopt; - } - - // - - bool are_annotations_same_to_names() const { - return are_annotations_same_to_names_; - } - - // - bool is_same_to(const FunctionDefinition &other) const; CombineResult combine(FunctionDefinition &&other); -private: - SymbolDocs docs_; - std::vector constraints_; - Modifier return_modifier_; - bool is_method_; - Identifier name_; - Identifier full_name_; - std::vector args_; - bool are_annotations_same_to_names_; // needed for easier prinitng process - std::optional expression_; + // + + SymbolDocs docs; + std::vector constraints; + Modifier return_modifier; + bool is_method; + Identifier name; + Identifier full_name; + std::vector args; + bool are_annotations_same_to_names; // needed for easier prinitng process + std::optional expr; }; // refactor ?? -class TypeDefinition : public Node { -public: - TypeDefinition(Node node, SymbolDocs &&docs, bool is_on_heap, - const Identifier &name, std::vector &&typeclasses, - std::vector &&args, std::optional type) - : Node(node), docs_(std::move(docs)), is_on_heap_(is_on_heap), - name_(name), typeclasses_(typeclasses), args_(std::move(args)), - type_(std::move(type)) {} - - // - - SymbolDocs *get_docs() { return &docs_; } - - const SymbolDocs *get_docs() const { return &docs_; } - - // - - bool is_on_heap() const { return is_on_heap_; } - - // - - Identifier *get_name() { return &name_; } - - const Identifier *get_name() const { return &name_; } - - // - - size_t args_size() const { return args_.size(); } - - Identifier *get_argument(size_t id) { return &args_.at(id); } - - const Identifier *get_argument(size_t id) const { return &args_.at(id); } - - // - - std::optional get_type() const { - if (type_.has_value()) { - return type_.value(); - } - return std::nullopt; - } - - // - - bool is_typeclass() { return name_.get_type() == Identifier::TYPECLASS; } +struct TypeDefinition { + bool is_typeclass() { return name.kind == Identifier::kTypeclass; } // @@ -394,53 +249,44 @@ public: CombineResult combine(TypeDefinition &&other); -private: - SymbolDocs docs_; - bool is_on_heap_; - Identifier name_; - std::vector typeclasses_; - std::vector args_; - std::optional type_; + // + + SymbolDocs docs; + bool is_on_heap; + Identifier name; + std::vector typeclasses; + std::vector args; + std::optional type; }; -class Statement : public Node { +struct Statement { public: using Type = std::variant; - // Statement(const Statement &) = default; - // Statement(Statement &&) = default; - // Statement &operator=(const Statement &) = default; - // Statement &operator=(Statement &&) = default; - - template - Statement(Node node, T &&statement) - : Node(node), expr_(std::forward(statement)) {} + // template std::optional get() { - if (std::holds_alternative(expr_)) { - return &std::get(expr_); + if (std::holds_alternative(expr)) { + return &std::get(expr); } return std::nullopt; } template std::optional get() const { - if (std::holds_alternative(expr_)) { - return &std::get(expr_); + if (std::holds_alternative(expr)) { + return &std::get(expr); } return std::nullopt; } - Type &get_any() { return expr_; } - - const Type &get_any() const { return expr_; } - bool is_same_to(const Statement &other) const; CombineResult combine(Statement &&other); -private: - Type expr_; + // + + Type expr; }; } // namespace nodes diff --git a/lang/nodes/include/type_nodes.hpp b/lang/nodes/include/type_nodes.hpp index 72451f3..88d9f2e 100644 --- a/lang/nodes/include/type_nodes.hpp +++ b/lang/nodes/include/type_nodes.hpp @@ -167,7 +167,7 @@ public: // - bool is_generic() { return name_.get_type() == Identifier::GENERIC_TYPE; } + bool is_generic() { return name_.kind == Identifier::kGenericType; } // @@ -192,7 +192,7 @@ public: bool operator<(const TypeData &other) const { if (name_ != other.name_) { - return *name_.get() < *other.name_.get(); + return name_.value < other.name_.value; } if (modifier_ != other.modifier_) { @@ -220,7 +220,7 @@ public: // is parameters count check necessary ?? builtin::Type to_builtin() const { - auto builtin_type = builtin::types::to_type(*name_.get()); + auto builtin_type = builtin::types::to_type(name_.value); auto builtin_type_parameters_count = builtin::types::get_parameters_count(builtin_type); @@ -249,12 +249,12 @@ class TypeStorage { public: Type primitive(builtin::Type type); - Type add_array_of(Type type, Node node = Node()); + Type add_array_of(Type type); - Type add_error_of(Type type, Node node = Node()); + Type add_error_of(Type type); nodes::Type add_container_of(std::vector &¶meters, - builtin::Type container, Node node = Node()); + builtin::Type container); nodes::Type add_modification_of(Type type, Modifier modifier); diff --git a/lang/nodes/src/expression_nodes.cpp b/lang/nodes/src/expression_nodes.cpp index 29a4cee..0359ff3 100644 --- a/lang/nodes/src/expression_nodes.cpp +++ b/lang/nodes/src/expression_nodes.cpp @@ -1,9 +1,3 @@ #include "expression_nodes.hpp" -namespace nodes { - -ExprData *Expr::get() { return expression_storage_->get_expr(id_); } - -const ExprData *Expr::get() const { return expression_storage_->get_expr(id_); } - -}; // namespace nodes +namespace nodes {}; // namespace nodes diff --git a/lang/nodes/src/statement_nodes.cpp b/lang/nodes/src/statement_nodes.cpp index 048d7de..9adcff6 100644 --- a/lang/nodes/src/statement_nodes.cpp +++ b/lang/nodes/src/statement_nodes.cpp @@ -1,5 +1,6 @@ #include "statement_nodes.hpp" +// #include "error_handling.hpp" #include "error_handling.hpp" #include "utils.hpp" #include @@ -7,7 +8,7 @@ namespace nodes { bool FunctionDefinition::is_same_to(const FunctionDefinition &other) const { - if (name_ != other.name_) { + if (name != other.name) { return false; } return true; @@ -21,96 +22,95 @@ bool FunctionDefinition::is_same_to(const FunctionDefinition &other) const { // name 'arg1 'arg2 -> 'arg3 = ... // function definition (without types) CombineResult FunctionDefinition::combine(FunctionDefinition &&other) { // names should be the same - if (name_ != other.name_) { + if (name != other.name) { return CombineResult::DIFFERENT_NAME_ERROR; } // modifiers should be the same - if (return_modifier_ != other.return_modifier_) { + if (return_modifier != other.return_modifier) { return CombineResult::DIFFERNENT_MODIFIER_ERROR; } - if (is_method_ != other.is_method_) { + if (is_method != other.is_method) { return CombineResult::DIFFERNENT_MODIFIER_ERROR; // other error type ?? } - if (are_annotations_same_to_names_ != other.are_annotations_same_to_names_) { + if (are_annotations_same_to_names != other.are_annotations_same_to_names) { return CombineResult::ARGUMENTS_ERROR; } // only one definition should have constraints - if (!constraints_.empty() && !other.constraints_.empty()) { + if (!constraints.empty() && !other.constraints.empty()) { return CombineResult::MORE_THEN_ONE_CONSTRAINTS_ERROR; } // only one definition should have expression (body) - if (expression_.has_value() && other.expression_.has_value()) { + if (expr.has_value() && other.expr.has_value()) { return CombineResult::MORE_THEN_ONE_DEFINITION_BODY_ERROR; } // only one definition should have documentation - if (docs_.get_description().has_value() && - other.docs_.get_description().has_value()) { + if (docs.get_description().has_value() && + other.docs.get_description().has_value()) { return CombineResult::MORE_THEN_ONE_DOCS_ERROR; } - if (docs_.annotations_info_size() > 0 && - other.docs_.annotations_info_size() > 0) { + if (docs.annotations_info_size() > 0 && + other.docs.annotations_info_size() > 0) { return CombineResult::MORE_THEN_ONE_DOCS_ERROR; } // check, that function definitions have same named args - for (size_t i = 0; i < std::max(args_.size(), other.args_.size()); ++i) { - if (i < args_.size() && i < other.args_.size()) { + for (size_t i = 0; i < std::max(args.size(), other.args.size()); ++i) { + if (i < args.size() && i < other.args.size()) { // annotations should be the same - if ((!args_[i].get_annotation().has_value() && - !other.args_[i].get_annotation().has_value()) || - (args_[i].get_annotation().has_value() && - other.args_[i].get_annotation().has_value() && - *args_[i].get_annotation().value() != - *other.args_[i].get_annotation().value())) { + if ((!args[i].get_annotation().has_value() && + !other.args[i].get_annotation().has_value()) || + (args[i].get_annotation().has_value() && + other.args[i].get_annotation().has_value() && + *args[i].get_annotation().value() != + *other.args[i].get_annotation().value())) { return CombineResult::ARGUMENTS_ERROR; } // argument names should be the same - if ((!args_[i].get_name().has_value() && - !other.args_[i].get_name().has_value()) || - (args_[i].get_name().has_value() && - other.args_[i].get_name().has_value() && - args_[i].get_name().value() != other.args_[i].get_name().value())) { + if ((!args[i].get_name().has_value() && + !other.args[i].get_name().has_value()) || + (args[i].get_name().has_value() && + other.args[i].get_name().has_value() && + args[i].get_name().value() != other.args[i].get_name().value())) { return CombineResult::ARGUMENTS_ERROR; } // types should be the same (if present in both definitions) - if (args_[i].get_type().has_value() && - other.args_[i].get_type().has_value() && - *args_[i].get_type().value() != *other.args_[i].get_type().value()) { + if (args[i].get_type().has_value() && + other.args[i].get_type().has_value() && + *args[i].get_type().value() != *other.args[i].get_type().value()) { return CombineResult::ARGUMENTS_ERROR; } // argument modifiers should be the same - if (args_[i].get_before_modifier() != - other.args_[i].get_before_modifier() || - args_[i].get_after_modifier() != - other.args_[i].get_after_modifier()) { + if (args[i].get_before_modifier() != + other.args[i].get_before_modifier() || + args[i].get_after_modifier() != other.args[i].get_after_modifier()) { return CombineResult::ARGUMENTS_ERROR; } - } else if (i < args_.size()) { + } else if (i < args.size()) { // annotations should be the same - if (args_[i].get_annotation().has_value()) { + if (args[i].get_annotation().has_value()) { return CombineResult::ARGUMENTS_ERROR; } // names should be the same - if (args_[i].get_name().has_value()) { + if (args[i].get_name().has_value()) { return CombineResult::ARGUMENTS_ERROR; } } else { // i < other_function_definition.size() // annotations should be the same - if (other.args_[i].get_annotation().has_value()) { + if (other.args[i].get_annotation().has_value()) { return CombineResult::ARGUMENTS_ERROR; } // names should be the same - if (other.args_[i].get_name().has_value()) { + if (other.args[i].get_name().has_value()) { return CombineResult::ARGUMENTS_ERROR; } } @@ -118,28 +118,28 @@ CombineResult FunctionDefinition::combine(FunctionDefinition &&other) { // combine docs // all docs should be in one definition - if (other.docs_.get_description().has_value() || - other.docs_.annotations_info_size() > 0) { - if (docs_.annotations_info_size() > 0 || - docs_.get_description().has_value()) { + if (other.docs.get_description().has_value() || + other.docs.annotations_info_size() > 0) { + if (docs.annotations_info_size() > 0 || + docs.get_description().has_value()) { return CombineResult::MORE_THEN_ONE_DOCS_ERROR; } - docs_ = std::move(other.docs_); + docs = std::move(other.docs); } - if (!other.constraints_.empty()) { - constraints_ = std::move(other.constraints_); + if (!other.constraints.empty()) { + constraints = std::move(other.constraints); } - if (other.expression_.has_value()) { - expression_ = other.expression_; + if (other.expr.has_value()) { + expr = other.expr; } - for (size_t i = 0; i < other.args_.size(); ++i) { - if (i < args_.size()) { - if (other.args_[i].get_type().has_value()) { - if (args_[i].update_type_from(other.args_[i])) { + for (size_t i = 0; i < other.args.size(); ++i) { + if (i < args.size()) { + if (other.args[i].get_type().has_value()) { + if (args[i].update_type_from(other.args[i])) { error_handling::handle_internal_error( "Function arguments are not properly checked before merging " "during combination", @@ -147,7 +147,7 @@ CombineResult FunctionDefinition::combine(FunctionDefinition &&other) { } } } else { - args_.push_back(std::move(other.args_[i])); + args.push_back(std::move(other.args[i])); } } @@ -155,7 +155,7 @@ CombineResult FunctionDefinition::combine(FunctionDefinition &&other) { } bool TypeDefinition::is_same_to(const TypeDefinition &other) const { - if (name_ != other.name_) { + if (name != other.name) { return false; } return true; @@ -167,83 +167,83 @@ bool TypeDefinition::is_same_to(const TypeDefinition &other) const { // Type[...] 'A 'B 'C = ... // define type CombineResult TypeDefinition::combine(TypeDefinition &&other) { // name should be same - if (name_ != other.name_) { + if (name != other.name) { return CombineResult::DIFFERENT_NAME_ERROR; } // modifier should be the same - if (is_on_heap_ != other.is_on_heap_) { + if (is_on_heap != other.is_on_heap) { return CombineResult::DIFFERNENT_MODIFIER_ERROR; } // typeclasses should be the same - if (typeclasses_.size() != other.typeclasses_.size()) { + if (typeclasses.size() != other.typeclasses.size()) { return CombineResult::ARGUMENTS_ERROR; } - for (size_t i = 0; i < typeclasses_.size(); ++i) { - if (typeclasses_[i] != other.typeclasses_[i]) { + for (size_t i = 0; i < typeclasses.size(); ++i) { + if (typeclasses[i] != other.typeclasses[i]) { return CombineResult::ARGUMENTS_ERROR; } } // args should be the same - if (args_.size() != other.args_.size()) { + if (args.size() != other.args.size()) { return CombineResult::ARGUMENTS_ERROR; } - for (size_t i = 0; i < args_.size(); ++i) { - if (args_[i] != other.args_[i]) { + for (size_t i = 0; i < args.size(); ++i) { + if (args[i] != other.args[i]) { return CombineResult::ARGUMENTS_ERROR; } } // only one definition should have documentation - if (docs_.get_description().has_value() && - other.docs_.get_description().has_value()) { + if (docs.get_description().has_value() && + other.docs.get_description().has_value()) { return CombineResult::MORE_THEN_ONE_DOCS_ERROR; } - if (docs_.annotations_info_size() > 0 && - other.docs_.annotations_info_size() > 0) { + if (docs.annotations_info_size() > 0 && + other.docs.annotations_info_size() > 0) { return CombineResult::MORE_THEN_ONE_DOCS_ERROR; } // only one type should define type / body - if (type_.has_value() && other.type_.has_value()) { + if (type.has_value() && other.type.has_value()) { return CombineResult::MORE_THEN_ONE_DEFINITION_BODY_ERROR; } // combine docs // all docs should be in one definition - if (other.docs_.get_description().has_value() || - other.docs_.annotations_info_size() > 0) { - if (docs_.annotations_info_size() > 0 || - docs_.get_description().has_value()) { + if (other.docs.get_description().has_value() || + other.docs.annotations_info_size() > 0) { + if (docs.annotations_info_size() > 0 || + docs.get_description().has_value()) { return CombineResult::MORE_THEN_ONE_DOCS_ERROR; } - docs_ = std::move(other.docs_); + docs = std::move(other.docs); } - if (other.type_.has_value()) { - type_ = std::move(other.type_); + if (other.type.has_value()) { + type = std::move(other.type); } return CombineResult::OK; } bool Statement::is_same_to(const Statement &other) const { - if (expr_.index() != other.expr_.index()) { + if (expr.index() != other.expr.index()) { return false; } - switch (expr_.index()) { + switch (expr.index()) { case 0: // Import return false; case 1: // TypeDefinition - return std::get(expr_).is_same_to( - std::move(std::get(other.expr_))); + return std::get(expr).is_same_to( + std::move(std::get(other.expr))); case 2: // FunctionDefinition - return std::get(expr_).is_same_to( - std::move(std::get(other.expr_))); + return std::get(expr).is_same_to( + std::move(std::get(other.expr))); case 3: // Extra return false; case 4: // EmptyLines @@ -259,19 +259,19 @@ bool Statement::is_same_to(const Statement &other) const { } CombineResult Statement::combine(Statement &&other) { - if (expr_.index() != other.expr_.index()) { + if (expr.index() != other.expr.index()) { return CombineResult::DIFFERENT_STATEMENT_TYPES; } - switch (expr_.index()) { + switch (expr.index()) { case 0: // Import return CombineResult::STATEMENTS_CANT_BE_COMBINED_ERROR; case 1: // TypeDefinition - return std::get(expr_).combine( - std::move(std::get(other.expr_))); + return std::get(expr).combine( + std::move(std::get(other.expr))); case 2: // FunctionDefinition - return std::get(expr_).combine( - std::move(std::get(other.expr_))); + return std::get(expr).combine( + std::move(std::get(other.expr))); case 3: // Extra return CombineResult::STATEMENTS_CANT_BE_COMBINED_ERROR; case 4: // EmptyLines diff --git a/lang/nodes/src/type_nodes.cpp b/lang/nodes/src/type_nodes.cpp index 4e7548d..5a2dba8 100644 --- a/lang/nodes/src/type_nodes.cpp +++ b/lang/nodes/src/type_nodes.cpp @@ -1,5 +1,7 @@ #include "type_nodes.hpp" +// TODO: replace error system + namespace nodes { TypeData *Type::get() { return type_storage_->get_type(id_); } @@ -18,12 +20,14 @@ Type TypeStorage::primitive(builtin::Type type) { return Type(*this, iter->second); } else { primitive_type_ids_[type] = storage_.size(); - return add_type(TypeData(Identifier(Node(), Identifier::SIMPLE_TYPE, - builtin::types::to_string(type)))); + return add_type(TypeData(Identifier{ + .kind = Identifier::kSimpleType, + .value = builtin::types::to_string(type), + })); } } -Type TypeStorage::add_array_of(Type type, Node node) { +Type TypeStorage::add_array_of(Type type) { if (type.type_storage_ != this) { error_handling::handle_general_error( "TypeStorage: Can't add array of type from another type " @@ -33,12 +37,15 @@ Type TypeStorage::add_array_of(Type type, Node node) { std::vector parameters; parameters.push_back(type); - return add_type(TypeData(Identifier(node, Identifier::SIMPLE_TYPE, - builtin::types::ARRAY_IDENTIFIER), - std::move(parameters))); + return add_type(TypeData( + Identifier{ + .kind = Identifier::kSimpleType, + .value = builtin::types::ARRAY_IDENTIFIER, + }, + std::move(parameters))); } -Type TypeStorage::add_error_of(Type type, Node node) { +Type TypeStorage::add_error_of(Type type) { if (type.type_storage_ != this) { error_handling::handle_general_error( "TypeStorage: Can't add error of type from another type " @@ -48,13 +55,16 @@ Type TypeStorage::add_error_of(Type type, Node node) { std::vector parameters; parameters.push_back(type); - return add_type(TypeData(Identifier(node, Identifier::SIMPLE_TYPE, - builtin::types::ERROR_IDENTIFIER), - std::move(parameters))); + return add_type(TypeData( + Identifier{ + .kind = Identifier::kSimpleType, + .value = builtin::types::ERROR_IDENTIFIER, + }, + std::move(parameters))); } nodes::Type TypeStorage::add_container_of(std::vector &¶meters, - builtin::Type container, Node node) { + builtin::Type container) { for (auto ¶meter : parameters) { if (parameter.type_storage_ != this) { error_handling::handle_general_error( @@ -64,10 +74,12 @@ nodes::Type TypeStorage::add_container_of(std::vector &¶meters, } } - return add_type( - nodes::TypeData(nodes::Identifier(node, nodes::Identifier::SIMPLE_TYPE, - builtin::types::to_string(container)), - std::move(parameters))); + return add_type(nodes::TypeData( + nodes::Identifier{ + .kind = nodes::Identifier::kSimpleType, + .value = builtin::types::to_string(container), + }, + std::move(parameters))); } nodes::Type TypeStorage::add_modification_of(Type type, Modifier modifier) { @@ -95,7 +107,7 @@ bool TypeStorage::resolve_all_generic_types() { for (auto &type : storage_) { if (type.is_generic()) { - auto iter = resolved_generic_names_.find(*type.get_name()->get()); + auto iter = resolved_generic_names_.find(type.get_name()->value); // because of undefined order some types can became resolved earlir // wirking correctly because each generic type has <= 1 successor, no @@ -280,9 +292,10 @@ bool TypeStorage::resolve( // Identifier TypeStorage::generate_generic_type_identifier() { - Identifier identifier = - Identifier(Node(), Identifier::GENERIC_TYPE, - "G_" + std::to_string(last_generic_type_id_)); + Identifier identifier = Identifier{ + .kind = Identifier::kGenericType, + .value = "G_" + std::to_string(last_generic_type_id_), + }; ++last_generic_type_id_; return identifier; } diff --git a/lang/printers/src/expression_printers.cpp b/lang/printers/src/expression_printers.cpp index c5c47ae..91bebb4 100644 --- a/lang/printers/src/expression_printers.cpp +++ b/lang/printers/src/expression_printers.cpp @@ -33,7 +33,7 @@ void print(const nodes::ExprData &expression, printers::Printer &printer) { void print(const nodes::Match::Case &expression, Printer &printer) { - switch (expression.case_type()) { + switch (expression.kind()) { case nodes::Match::Case::PATTERN_VALUE: printer.print(":="); break; @@ -316,7 +316,7 @@ void print(const nodes::NameExpression &expression, bool operator_called_as_function = (!expression.is_operator_call() && - expression.get_name()->get_type() == nodes::Identifier::OPERATOR); + expression.get_name()->get_type() == nodes::Identifier::kOperator); if (operator_called_as_function) { printer.print("( "); diff --git a/lang/type_check/include/type_check_utils.hpp b/lang/type_check/include/type_check_utils.hpp index 93fcd75..59a653f 100644 --- a/lang/type_check/include/type_check_utils.hpp +++ b/lang/type_check/include/type_check_utils.hpp @@ -18,15 +18,15 @@ class State { public: struct VariableInfo { nodes::Type type; - nodes::NameDefinition::Modifier modifier; + nodes::NameDefinition::Kind modifier; }; public: State(Log &log) : log_(log) {} bool insert_variable(const std::string &name, nodes::Type type, - nodes::NameDefinition::Modifier modifier) { - Log::Context logc(log_, utils::Log::Area::kTypeCheck); + nodes::NameDefinition::Kind modifier) { + Log::Context logc(log_, Log::Area::kTypeCheck); if (contexts_.empty()) { logc.Fatal( @@ -50,7 +50,7 @@ public: } bool bring_type(nodes::Type type) { - Log::Context logc(log_, utils::Log::Area::kTypeCheck); + Log::Context logc(log_, Log::Area::kTypeCheck); if (contexts_.empty()) { logc.Fatal( @@ -66,7 +66,7 @@ public: } bool return_type(nodes::Type type) { - Log::Context logc(log_, utils::Log::Area::kTypeCheck); + Log::Context logc(log_, Log::Area::kTypeCheck); if (contexts_.empty()) { logc.Fatal( @@ -83,7 +83,7 @@ public: private: void enter_context(const nodes::Node &node) { - Log::Context logc(log_, utils::Log::Area::kTypeCheck); + Log::Context logc(log_, Log::Area::kTypeCheck); contexts_.emplace_back(node); } @@ -92,7 +92,7 @@ private: // returns brought type, return type is merged with next context or with // brought type in last context nodes::MaybeType exit_context() { - Log::Context logc(log_, utils::Log::Area::kTypeCheck); + Log::Context logc(log_, Log::Area::kTypeCheck); if (contexts_.empty()) { logc.Fatal( diff --git a/lang/type_check/src/expression_type_check.cpp b/lang/type_check/src/expression_type_check.cpp index ab09a16..bb6a2dd 100644 --- a/lang/type_check/src/expression_type_check.cpp +++ b/lang/type_check/src/expression_type_check.cpp @@ -849,7 +849,7 @@ Result CheckTask::operator()(const nodes::Lambda &expr, if (!state().insert_variable( *expr.get_argument(i)->get(), expected_type.get()->get_parameter_proxy(i), - nodes::NameDefinition::Modifier::LET)) { + nodes::NameDefinition::Kind::LET)) { // TODO: which modifier ?? type_check_error("Variable is already defined in this context", expr, executor); diff --git a/lang/type_check/src/type_check_utils.cpp b/lang/type_check/src/type_check_utils.cpp index e3a480e..c516272 100644 --- a/lang/type_check/src/type_check_utils.cpp +++ b/lang/type_check/src/type_check_utils.cpp @@ -11,7 +11,7 @@ nodes::Type check_same_to_pass_type_in_args(nodes::Type type, const Args &args, Executor &executor, const std::string &message, bool handle_errors) { - Log::Context logc(executor.log(), utils::Log::Area::kTypeCheck); + Log::Context logc(executor.log(), Log::Area::kTypeCheck); if (not args.get_passed().has_value()) { return type; @@ -27,7 +27,7 @@ nodes::Type check_same_to_pass_type_in_args(nodes::Type type, const Args &args, bool check_no_pass_type_in_args(const Args &args, const nodes::Node &node, Executor &executor, const std::string &message, bool handle_errors) { - Log::Context logc(executor.log(), utils::Log::Area::kTypeCheck); + Log::Context logc(executor.log(), Log::Area::kTypeCheck); if (args.get_passed().has_value()) { type_check_error(message, node, executor, handle_errors); @@ -40,7 +40,7 @@ bool check_no_pass_type_in_args(const Args &args, const nodes::Node &node, Result type_same_to_expected(nodes::Type type, const Args &args, const nodes::Node & /*node*/, Executor &executor, const std::string &message, bool handle_errors) { - Log::Context logc(executor.log(), utils::Log::Area::kTypeCheck); + Log::Context logc(executor.log(), Log::Area::kTypeCheck); const auto &expected = args.get_expected(); @@ -63,7 +63,7 @@ Result type_same_to_expected(nodes::Type type, const Args &args, Result type_check_from_args(nodes::Type /*type*/, const Args & /*args*/, const nodes::Node & /*node*/, Executor &executor, bool /*handle_errors*/) { - Log::Context logc(executor.log(), utils::Log::Area::kTypeCheck); + Log::Context logc(executor.log(), Log::Area::kTypeCheck); /* TODO FIXME */ logc.Fatal({{"Not implemented yet"}}); @@ -76,7 +76,7 @@ find_statement(const std::string &name, const nodes::Node & /*node*/, Executor &executor, const std::string &message_not_found, const std::string &message_different_statement, bool handle_errors) { - Log::Context logc(executor.log(), utils::Log::Area::kTypeCheck); + Log::Context logc(executor.log(), Log::Area::kTypeCheck); const auto maybe_any_statement = executor.state().find(name); if (not maybe_any_statement.has_value()) { @@ -100,7 +100,7 @@ find_statement(const std::string &name, const nodes::Node & /*node*/, std::optional find_type_definition(const std::string &name, const nodes::Node &node, Executor &executor, bool handle_errors) { - Log::Context logc(executor.log(), utils::Log::Area::kTypeCheck); + Log::Context logc(executor.log(), Log::Area::kTypeCheck); return find_statement( name, node, executor, "No type definition found in name tree", @@ -110,7 +110,7 @@ find_type_definition(const std::string &name, const nodes::Node &node, std::optional find_name_definition(const std::string &name, const nodes::Node &node, Executor &executor, bool handle_errors) { - Log::Context logc(executor.log(), utils::Log::Area::kTypeCheck); + Log::Context logc(executor.log(), Log::Area::kTypeCheck); return find_statement( name, node, executor, "No name definition found in name tree", @@ -121,7 +121,7 @@ std::optional unfold_user_defined_type(nodes::Type type, const nodes::Node &node, Executor &executor, bool handle_errors) { - Log::Context logc(executor.log(), utils::Log::Area::kTypeCheck); + Log::Context logc(executor.log(), Log::Area::kTypeCheck); const auto maybe_type_definition = find_type_definition( *type.get()->get_name()->get(), node, executor, handle_errors); @@ -151,7 +151,7 @@ std::optional get_field_type_by_name(nodes::Type type, const nodes::Node &node, Executor &executor, bool handle_errors) { - Log::Context logc(executor.log(), utils::Log::Area::kTypeCheck); + Log::Context logc(executor.log(), Log::Area::kTypeCheck); switch (type.get()->to_builtin()) { case builtin::Type::TUPLE: { // access field @@ -194,7 +194,7 @@ std::optional get_field_type_by_name(nodes::Type type, // FIXME: replace with direct log calls void type_check_error(const std::string &message, const nodes::Node &, Executor &executor, bool handle_error) { - Log::Context logc(executor.log(), utils::Log::Area::kTypeCheck); + Log::Context logc(executor.log(), Log::Area::kTypeCheck); if (!handle_error) { return; diff --git a/lang/utils/include/tree_sitter_wrapper.hpp b/lang/utils/include/tree_sitter_wrapper.hpp index 717495a..5a3801c 100644 --- a/lang/utils/include/tree_sitter_wrapper.hpp +++ b/lang/utils/include/tree_sitter_wrapper.hpp @@ -2,6 +2,7 @@ #include +#include "log.hpp" #include "utils.hpp" #include "tree_sitter/api.h" @@ -18,56 +19,46 @@ public: : node_(node), source_(source) {} std::string get_type() const { - if (is_null()) { - error_handling::handle_general_error( - "Null parsing node method called (get_type)"); - } + utils::Assert(not is_null(), + "Null parsing node method called (get_type)"); return ts_node_type(node_); } - std::pair get_start_point() const { - if (is_null()) { - error_handling::handle_general_error( - "Null parsing node method called (get_start_point)"); - } + utils::Pos::Point get_start_point() const { + utils::Assert(not is_null(), + "Null parsing node method called (get_start_point)"); TSPoint point = ts_node_start_point(node_); return {point.row, point.column}; } - std::pair get_end_point() const { - if (is_null()) { - error_handling::handle_general_error( - "Null parsing node method called (get_end_point)"); - } + utils::Pos::Point get_end_point() const { + utils::Assert(not is_null(), + "Null parsing node method called (get_end_point)"); TSPoint point = ts_node_end_point(node_); return {point.row, point.column}; } + utils::Pos get_pos() const { return {get_start_point(), get_end_point()}; } + std::string get_as_sexpression() const { - if (is_null()) { - error_handling::handle_general_error( - "Null parsing node method called (get_as_sexpression)"); - } + utils::Assert(not is_null(), + "Null parsing node method called (get_as_sexpression)"); return ts_node_string(node_); } std::string get_value() const { // from source - if (is_null()) { - error_handling::handle_general_error( - "Null parsing node method called (get_value)"); - } + utils::Assert(not is_null(), + "Null parsing node method called (get_value)"); size_t start = ts_node_start_byte(node_); size_t end = ts_node_end_byte(node_); return source_->substr(start, end - start); } size_t get_value_length() const { // from source - if (is_null()) { - error_handling::handle_general_error( - "Null parsing node method called (get_value_length)"); - } + utils::Assert(not is_null(), + "Null parsing node method called (get_value_length)"); size_t start = ts_node_start_byte(node_); size_t end = ts_node_end_byte(node_); return end - start; @@ -76,106 +67,80 @@ public: bool is_null() const { return ts_node_is_null(node_); } bool is_named() const { - if (is_null()) { - error_handling::handle_general_error( - "Null parsing node method called (is_named)"); - } + utils::Assert(not is_null(), + "Null parsing node method called (is_named)"); return ts_node_is_named(node_); } bool is_missing() const { - if (is_null()) { - error_handling::handle_general_error( - "Null parsing node method called (is_missing)"); - } + utils::Assert(not is_null(), + "Null parsing node method called (is_missing)"); return ts_node_is_missing(node_); } bool is_extra() const { // comments, etc. - if (is_null()) { - error_handling::handle_general_error( - "Null parsing node method called (is_extra)"); - } + utils::Assert(not is_null(), + "Null parsing node method called (is_extra)"); return ts_node_is_extra(node_); } bool has_error() const { - if (is_null()) { - error_handling::handle_general_error( - "Null parsing node method called (has_error)"); - } + utils::Assert(not is_null(), + "Null parsing node method called (has_error)"); return ts_node_has_error(node_); } Node nth_child(size_t n) const { - if (is_null()) { - error_handling::handle_general_error( - "Null parsing node method called (nth_child)"); - } + utils::Assert(not is_null(), + "Null parsing node method called (nth_child)"); return Node(ts_node_child(node_, n), source_); } size_t child_count() const { - if (is_null()) { - error_handling::handle_general_error( - "Null parsing node method called (child_count)"); - } + utils::Assert(not is_null(), + "Null parsing node method called (child_count)"); return ts_node_child_count(node_); } Node nth_named_child(size_t n) const { - if (is_null()) { - error_handling::handle_general_error( - "Null parsing node method called (nth_named_child)"); - } + utils::Assert(not is_null(), + "Null parsing node method called (nth_named_child)"); return Node(ts_node_named_child(node_, n), source_); } size_t named_child_count() const { - if (is_null()) { - error_handling::handle_general_error( - "Null parsing node method called (named_child_count)"); - } + utils::Assert(not is_null(), + "Null parsing node method called (named_child_count)"); return ts_node_named_child_count(node_); } Node child_by_field_name(const std::string &name) const { - if (is_null()) { - error_handling::handle_general_error( - "Null parsing node method called (child_by_field_name)"); - } + utils::Assert(not is_null(), + "Null parsing node method called (child_by_field_name)"); return Node(ts_node_child_by_field_name(node_, name.c_str(), name.size()), source_); } Node previous_sibling() const { - if (is_null()) { - error_handling::handle_general_error( - "Null parsing node method called (previous_sibling)"); - } + utils::Assert(not is_null(), + "Null parsing node method called (previous_sibling)"); return Node(ts_node_prev_sibling(node_), source_); } Node previous_named_sibling() const { - if (is_null()) { - error_handling::handle_general_error( - "Null parsing node method called (previous_named_sibling)"); - } + utils::Assert(not is_null(), + "Null parsing node method called (previous_named_sibling)"); return Node(ts_node_prev_named_sibling(node_), source_); } Node next_sibling() const { - if (is_null()) { - error_handling::handle_general_error( - "Null parsing node method called (next_sibling)"); - } + utils::Assert(not is_null(), + "Null parsing node method called (next_sibling)"); return Node(ts_node_next_sibling(node_), source_); } Node next_named_sibling() const { - if (is_null()) { - error_handling::handle_general_error( - "Null parsing node method called (next_named_sibling)"); - } + utils::Assert(not is_null(), + "Null parsing node method called (next_named_sibling)"); return Node(ts_node_next_named_sibling(node_), source_); } diff --git a/lang/utils/include/utils.hpp b/lang/utils/include/utils.hpp index 8e556df..f5deef7 100644 --- a/lang/utils/include/utils.hpp +++ b/lang/utils/include/utils.hpp @@ -63,6 +63,18 @@ namespace utils { #else // GCC, Clang __builtin_unreachable(); #endif + + // --- + + // // TODO + // template + // inline std::optional carry(std::optional value, std::function + // const& f) { + // if (value.has_value()) { + // return f(std::move(value)); + // } + // return std::nullopt; + // } } } // namespace utils