diff --git a/lang/app/sources_manager.hpp b/lang/app/sources_manager.hpp index a9b8574..fb6c6bd 100644 --- a/lang/app/sources_manager.hpp +++ b/lang/app/sources_manager.hpp @@ -51,7 +51,13 @@ public: void Print(std::ostream &out) { printers::Printer printer(out, 2, 80, true); - printers::print(statements_, printer); + + // TODO: FIXME: share executor + printers::Executor executor( + utils::BuildPrintLog(std::cout), + printers::Exprs{executor_.state()}, + std::move(printer)); + printers::PrintTask{executor}(statements_, {}); } size_t statements_size() const { return statements_.size(); } diff --git a/lang/builders/include/builders_utils.hpp b/lang/builders/include/builders_utils.hpp index 50bd1c6..97f5d8a 100644 --- a/lang/builders/include/builders_utils.hpp +++ b/lang/builders/include/builders_utils.hpp @@ -40,7 +40,7 @@ template struct BuilderTask { template struct BuilderTaskUtils : public Task { using Task::Task; - Node Ext(storage::Id id) const { + Node Ext(storage::Id id) { return Node(id, this->template state(), this->template state()); } @@ -58,7 +58,15 @@ template struct BuilderTaskUtils : public Task { 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); + return Ext(id); + } + + // TODO: rename + template + Ret RunOther(const parser::ParseTree::Node &node, const Args &args = {}) { + BuilderTask task(this->executor); + return task(node, args); } }; @@ -85,11 +93,15 @@ struct ExprBuilderTaskBase : public BuilderTaskUtils { BuilderTask task(this->executor); return task(node, args); } +}; + +template +struct TypeBuilderTaskBase : public BuilderTaskUtils { + using BuilderTaskUtils::BuilderTaskUtils; - // TODO: rename template - Ret RunOther(const parser::ParseTree::Node &node, const Args &args = {}) { + typename Ret = nodes::Type> + Ret Run(const parser::ParseTree::Node &node, const Args &args = {}) { BuilderTask task(this->executor); return task(node, args); } diff --git a/lang/builders/include/doc_builders.hpp b/lang/builders/include/doc_builders.hpp index a69f82b..af1e050 100644 --- a/lang/builders/include/doc_builders.hpp +++ b/lang/builders/include/doc_builders.hpp @@ -1,5 +1,6 @@ #pragma once +#include "builders_utils.hpp" #include "doc_nodes.hpp" #include "tree_sitter_wrapper.hpp" @@ -8,9 +9,10 @@ namespace builders { -nodes::SymbolDocs build_symbol_docs( - std::optional description_parser_node, - const std::vector &annotation_parser_nodes = {}, - const std::unordered_set &annotations = {}); +nodes::SymbolDocs +build_symbol_docs(std::optional description_parser_node, + const std::vector &annotation_parser_nodes, + const std::unordered_set &annotations, + Executor &executor); } // namespace builders diff --git a/lang/builders/include/expression_builders.hpp b/lang/builders/include/expression_builders.hpp index f2c6cfc..8bfe8ed 100644 --- a/lang/builders/include/expression_builders.hpp +++ b/lang/builders/include/expression_builders.hpp @@ -23,6 +23,13 @@ namespace builders { // --- flow control +template <> +struct BuilderTask : public ExprBuilderTaskBase { + using ExprBuilderTaskBase::ExprBuilderTaskBase; + + Node operator()(const ParserNode &parser_node, const Args &args) override; +}; + template <> struct BuilderTask : public ExprBuilderTaskBase { using ExprBuilderTaskBase::ExprBuilderTaskBase; @@ -90,6 +97,8 @@ struct BuilderTask // or // '[[' expression+ ']]' Node operator()(const ParserNode &parser_node, const Args &) override { + Log::Context logc(executor.log(), Log::Area::kParse); + const auto kind = std::is_same_v ? nodes::Container::BLOCK : nodes::Container::ARRAY; @@ -103,10 +112,12 @@ struct BuilderTask current_node = current_node.next_named_sibling(); } - return state().Insert(nodes::Container{ - .kind = kind, - .exprs = std::move(exprs), - }); + return Build( + nodes::Container{ + .kind = kind, + .exprs = std::move(exprs), + }, + parser_node.get_pos()); } }; @@ -162,13 +173,18 @@ struct BuilderTask // or // expression ('?' | '!') Node operator()(const ParserNode &parser_node, const Args &) override { + Log::Context logc(executor.log(), Log::Area::kParse); + const size_t modifier_pos = std::is_same_v ? 0 : parser_node.child_count() - 1; - return state().Insert(nodes::ModifierExpression{ - .modifier = Run(parser_node.nth_child(modifier_pos)), - .expr = Run(parser_node.nth_named_child(0)), - }); + return Build( + nodes::ModifierExpression{ + .modifier = RunOther( + parser_node.nth_child(modifier_pos)), + .expr = Run(parser_node.nth_named_child(0)), + }, + parser_node.get_pos()); } }; diff --git a/lang/builders/include/type_builders.hpp b/lang/builders/include/type_builders.hpp index 6cebea5..47cdba6 100644 --- a/lang/builders/include/type_builders.hpp +++ b/lang/builders/include/type_builders.hpp @@ -1,26 +1,69 @@ #pragma once +#include "builders_utils.hpp" +#include "tokens.hpp" #include "tree_sitter_wrapper.hpp" #include "type_nodes.hpp" +namespace utils { + +template struct TypeTag {}; + +} // namespace utils + namespace builders { -nodes::Type build_type(parser::ParseTree::Node parse_node, - nodes::TypeStorage &type_storage); +template <> +struct BuilderTask : public TypeBuilderTaskBase { + using TypeBuilderTaskBase::TypeBuilderTaskBase; -nodes::Type build_variant_type(parser::ParseTree::Node parse_node, - nodes::TypeStorage &type_storage); + nodes::Type operator()(const ParserNode &parser_node, + const Args &args) override; +}; -nodes::Type build_tuple_type(parser::ParseTree::Node parse_node, - nodes::TypeStorage &type_storage); +template <> +struct BuilderTask> + : public TypeBuilderTaskBase { + using TypeBuilderTaskBase::TypeBuilderTaskBase; -nodes::Type build_reference_type(parser::ParseTree::Node parse_node, - nodes::TypeStorage &type_storage); + nodes::Type operator()(const ParserNode &parser_node, + const Args &args) override; +}; -nodes::Type build_modified_type(parser::ParseTree::Node parse_node, - nodes::TypeStorage &type_storage); +template <> +struct BuilderTask> + : public TypeBuilderTaskBase { + using TypeBuilderTaskBase::TypeBuilderTaskBase; -nodes::Type build_simple_type(parser::ParseTree::Node parse_node, - nodes::TypeStorage &type_storage); + nodes::Type operator()(const ParserNode &parser_node, + const Args &args) override; +}; + +template <> +struct BuilderTask> + : public TypeBuilderTaskBase { + using TypeBuilderTaskBase::TypeBuilderTaskBase; + + nodes::Type operator()(const ParserNode &parser_node, + const Args &args) override; +}; + +template <> +struct BuilderTask> + : public TypeBuilderTaskBase { + using TypeBuilderTaskBase::TypeBuilderTaskBase; + + nodes::Type operator()(const ParserNode &parser_node, + const Args &args) override; +}; + +template <> +struct BuilderTask> + : public TypeBuilderTaskBase { + using TypeBuilderTaskBase::TypeBuilderTaskBase; + + nodes::Type operator()(const ParserNode &parser_node, + const Args &args) override; +}; } // namespace builders diff --git a/lang/builders/src/doc_builders.cpp b/lang/builders/src/doc_builders.cpp index 9d5f6db..0b3b170 100644 --- a/lang/builders/src/doc_builders.cpp +++ b/lang/builders/src/doc_builders.cpp @@ -1,15 +1,17 @@ #include "doc_builders.hpp" #include "basic_builders.hpp" #include "doc_nodes.hpp" -#include "error_handling.hpp" +#include "log.hpp" namespace builders { // TODO: check, that all annotations are exist in function definition -nodes::SymbolDocs build_symbol_docs( - std::optional description_parser_node, - const std::vector &annotation_parser_nodes, - const std::unordered_set &annotations) { +nodes::SymbolDocs +build_symbol_docs(std::optional description_parser_node, + const std::vector &annotation_parser_nodes, + const std::unordered_set &annotations, + Executor &executor) { + Log::Context logc(executor.log(), Log::Area::kParse); std::optional description; @@ -35,15 +37,16 @@ nodes::SymbolDocs build_symbol_docs( : nodes::SymbolDocs(); for (auto &annotation_parser_node : annotation_parser_nodes) { - std::string annotation = - build_annotation(annotation_parser_node.nth_named_child(0)); + std::string annotation = BuilderTask{executor}( + annotation_parser_node.nth_named_child(0), {}) + .value; - if (annotations.count(annotation) == 0) { - error_handling::handle_parsing_error( - "Annotation \"" + annotation + - "\" doesn't present in corresponding symbol", - annotation_parser_node); - } + logc.Expect( + annotations.count(annotation) == 0, + {{std::format( + "Annotation \"{}\" doesn't present in corresponding symbol", + annotation)}}, + annotation_parser_node.get_pos()); docs.add_annotation_info( annotation, annotation_parser_node.nth_named_child(1).get_value()); diff --git a/lang/builders/src/expression_builders.cpp b/lang/builders/src/expression_builders.cpp index 1f48b16..fee1c4c 100644 --- a/lang/builders/src/expression_builders.cpp +++ b/lang/builders/src/expression_builders.cpp @@ -12,15 +12,29 @@ namespace builders { +Node BuilderTask::operator()(const ParserNode &parser_node, + const Args &args) { + return Run(parser_node, args); +} + +// NOTE: use args in some way ?? Node BuilderTask::operator()(const ParserNode &parser_node, const Args &) { Log::Context logc(executor.log(), Log::Area::kParse); + logc.Default( + {{std::format("type is [{}]", parser_node.get_type())}}, + parser_node.get_pos()); + + logc.Default( + {{std::format("current sexpr is [{}]", parser_node.get_as_sexpression()), + Log::Fragment::Color::kImportant}}, + parser_node.get_pos()); + 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() == "("); @@ -66,8 +80,12 @@ Node BuilderTask::operator()(const ParserNode &parser_node, case tokens::Type::NAME_EXPRESSION: return Run(parser_node, {is_scoped}); - case tokens::Type::ARGUMENT_NAME_IDENTIFIER: case tokens::Type::SIMPLE_NAME_IDENTIFIER: + case tokens::Type::SIMPLE_TYPE_IDENTIFIER: + case tokens::Type::TYPECLASS_IDENTIFIER: + case tokens::Type::ARGUMENT_NAME_IDENTIFIER: + case tokens::Type::ARGUMENT_TYPE_IDENTIFIER: + case tokens::Type::OPERATOR: case tokens::Type::PLACEHOLDER: return Build( nodes::NameExpression{ @@ -79,43 +97,56 @@ Node BuilderTask::operator()(const ParserNode &parser_node, case tokens::Type::LAMBDA: return Run(parser_node); // --- literals - // 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); + case tokens::Type::FLOAT_LITERAL: + return Build(RunOther(parser_node), + parser_node.get_pos()); + case tokens::Type::DOUBLE_LITERAL: + return Build(RunOther(parser_node), + parser_node.get_pos()); + case tokens::Type::INT_LITERAL: + return Build(RunOther(parser_node), + parser_node.get_pos()); + case tokens::Type::LONG_LITERAL: + return Build(RunOther(parser_node), + parser_node.get_pos()); + case tokens::Type::INDEX_LITERAL: + return Build(RunOther(parser_node), + parser_node.get_pos()); + case tokens::Type::STRING_LITERAL: + return Build(RunOther(parser_node), + parser_node.get_pos()); + case tokens::Type::UNICODE_STRING_LITERAL: + return Build(RunOther(parser_node), + parser_node.get_pos()); + case tokens::Type::CHAR_LITERAL: + return Build(RunOther(parser_node), + parser_node.get_pos()); + case tokens::Type::UNICODE_LITERAL: + return Build(RunOther(parser_node), + parser_node.get_pos()); + case tokens::Type::BOOL_LITERAL: + return Build(RunOther(parser_node), + parser_node.get_pos()); + case tokens::Type::UNIT_LITERAL: + return Build(RunOther(parser_node), + parser_node.get_pos()); + case tokens::Type::NULL_LITERAL: + return Build(RunOther(parser_node), + parser_node.get_pos()); + case tokens::Type::EXTRA: + return Build(RunOther(parser_node), + parser_node.get_pos()); + case tokens::Type::EMPTY_LINES: + return Build(RunOther(parser_node), + parser_node.get_pos()); default: break; } - utils::Assert(true, std::format("Unexpected expression node type {}", - static_cast(type))); // TODO: magic_enum + utils::Assert(false, std::format("Unexpected expression node type [{}]\n", + parser_node.get_type())); // TODO: magic_enum // FIXME: change to fatal error ? - throw std::exception(); + utils::unreachable(); } // --- flow control @@ -124,8 +155,9 @@ Node BuilderTask::operator()(const ParserNode &parser_node, Node BuilderTask::operator()(const ParserNode &parser_node, const Args &) { Log::Context logc(executor.log(), Log::Area::kParse); + std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!"; - std::string case_type = parser_node.nth_child(0).get_value(); + std::string case_kind = parser_node.nth_child(0).get_value(); std::optional condition_node; std::optional expression_node; @@ -146,15 +178,15 @@ Node BuilderTask::operator()(const ParserNode &parser_node, return Build( nodes::Match::Case{ - .kind = case_type == ":=" ? nodes::Match::Case::PATTERN_VALUE + .kind = case_kind == ":=" ? 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(), + : std::optional(), .expr = expression_node.has_value() ? Run(expression_node.value()) - : std::optional(), + : std::optional(), }, parser_node.get_pos()); } @@ -164,7 +196,8 @@ Node BuilderTask::operator()(const ParserNode &parser_node, const Args &) { Log::Context logc(executor.log(), Log::Area::kParse); - std::vector cases; // TODO + std::cout << "????????????????"; + std::vector cases; // TODO auto current_node = parser_node.nth_named_child(1); while (!current_node.is_null()) { @@ -175,7 +208,8 @@ Node BuilderTask::operator()(const ParserNode &parser_node, return Build( nodes::Match{ - .value = Run(parser_node.nth_named_child(0)), + .value = Run(parser_node.nth_named_child( + 0)), // TODO: is_scoped info (always false ??) .cases = std::move(cases), }, parser_node.get_pos()); @@ -189,14 +223,14 @@ Node BuilderTask::operator()(const ParserNode &parser_node, 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; @@ -253,13 +287,13 @@ Node BuilderTask::operator()( const ParserNode &parser_node, const Args &) { Log::Context logc(executor.log(), Log::Area::kParse); - std::vector, storage::Id>> args; + std::vector, nodes::NodeId>> 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 Build( nodes::NameExpression{ @@ -284,7 +318,7 @@ Node BuilderTask::operator()( auto name_node = parser_node.child_by_field_name("name"); - std::vector, storage::Id>> args; + std::vector, nodes::NodeId>> args; args.emplace_back(std::nullopt, Run(name_node.previous_named_sibling())); @@ -455,7 +489,8 @@ Node BuilderTask::operator()( .name = RunOther(name_node), .args = std::move(args), .prefix = prefix_node.has_value() - ? build_type(prefix_node.value(), state()) + ? RunOther( + prefix_node.value()) : nodes::MaybeType(), .is_point_call = is_point_call, .is_operator_call = false, @@ -479,8 +514,8 @@ Node BuilderTask::operator()(const ParserNode &parser_node, return Build( nodes::Constructor{ - .type = build_type(parser_node.child_by_field_name("type"), - state()), + .type = RunOther( + parser_node.child_by_field_name("type")), .args = std::move(args), }, parser_node.get_pos()); diff --git a/lang/builders/src/statement_builders.cpp b/lang/builders/src/statement_builders.cpp index df1f705..67292dd 100644 --- a/lang/builders/src/statement_builders.cpp +++ b/lang/builders/src/statement_builders.cpp @@ -239,9 +239,10 @@ BuilderTask::operator()(const ParserNode &parser_node, } } - nodes::MaybeType type = type_node.has_value() - ? build_type(type_node.value(), state()) - : nodes::MaybeType(); + nodes::MaybeType type = + type_node.has_value() + ? RunOther(type_node.value()) + : nodes::MaybeType(); std::unordered_set annotations; @@ -252,8 +253,8 @@ BuilderTask::operator()(const ParserNode &parser_node, } return nodes::TypeDefinition{ - .docs = - build_symbol_docs(description_node, annotation_nodes, annotations), + .docs = build_symbol_docs(description_node, annotation_nodes, annotations, + executor), .is_on_heap = is_on_heap, .name = std::move(name), .typeclasses = std::move(typeclasses), @@ -377,11 +378,13 @@ nodes::FunctionDefinition BuilderTask::operator()( case tokens::Type::SIMPLE_TYPE: if (current_type_id >= args.size()) { args.push_back(nodes::FunctionDefinition::Argument( - last_annotation, build_type(current_node, state()), + last_annotation, + RunOther(current_node), last_before_modifier)); } else { if (!args[current_type_id].add_type( - last_annotation, build_type(current_node, state()), + last_annotation, + RunOther(current_node), last_before_modifier)) { logc.Fatal( {{"It is impossible to use argument modifiers (annotations, " @@ -427,7 +430,7 @@ 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()->value; + std::string new_annotation = args[i].name.value().value; if (!args[i].add_annotation( new_annotation.substr(1, new_annotation.size() - 1))) { logc.Fatal({{"no annotations provided ( => all annotations " @@ -440,8 +443,8 @@ nodes::FunctionDefinition BuilderTask::operator()( std::unordered_set annotations_set; for (auto &arg : args) { - if (arg.get_annotation().has_value()) { - if (!annotations_set.insert(*arg.get_annotation().value()).second) { + if (arg.annotation.has_value()) { + if (!annotations_set.insert(arg.annotation.value()).second) { logc.Fatal( {{"Two or more same annotations found in function definition"}}, parser_node.get_pos()); @@ -450,7 +453,8 @@ nodes::FunctionDefinition BuilderTask::operator()( } return nodes::FunctionDefinition( - build_symbol_docs(description_node, annotation_nodes, annotations_set), + build_symbol_docs(description_node, annotation_nodes, annotations_set, + executor), std::move(constraints), return_modifier, is_method, name_prefix, Run(name_node), std::move(args), are_annotations_same_to_names, diff --git a/lang/builders/src/type_builders.cpp b/lang/builders/src/type_builders.cpp index eded975..d7fcb00 100644 --- a/lang/builders/src/type_builders.cpp +++ b/lang/builders/src/type_builders.cpp @@ -2,14 +2,19 @@ #include "basic_builders.hpp" #include "basic_nodes.hpp" #include "builtin_types.hpp" -#include "error_handling.hpp" +// #include "error_handling.hpp" #include "tokens.hpp" #include "type_nodes.hpp" namespace builders { -nodes::Type build_type(parser::ParseTree::Node parser_node, - nodes::TypeStorage &type_storage) { +using Tp = tokens::Type; +using utils::TypeTag; + +nodes::Type 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()); // TODO: for better formatted printing @@ -19,26 +24,29 @@ nodes::Type build_type(parser::ParseTree::Node parser_node, // maybe_parenthesis.get_value() == "("); switch (type) { - case tokens::Type::VARIANT_TYPE: - return build_variant_type(parser_node, type_storage); - case tokens::Type::TUPLE_TYPE: - return build_tuple_type(parser_node, type_storage); - case tokens::Type::REFERENCE_TYPE: - return build_reference_type(parser_node, type_storage); - case tokens::Type::MODIFIED_TYPE: - return build_modified_type(parser_node, type_storage); - case tokens::Type::SIMPLE_TYPE: - return build_simple_type(parser_node, type_storage); + case Tp::VARIANT_TYPE: + return Run>(parser_node); + case Tp::TUPLE_TYPE: + return Run>(parser_node); + case Tp::REFERENCE_TYPE: + return Run>(parser_node); + case Tp::MODIFIED_TYPE: + return Run>(parser_node); + case Tp::SIMPLE_TYPE: + return Run>(parser_node); default: - error_handling::handle_parsing_error("Unexprected type node type", - parser_node); + logc.Fatal({{"Unexprected type node type"}}, + parser_node.get_pos()); } - error_handling::handle_general_error("Unreachable"); - exit(1); // unreachable + + utils::unreachable(); + exit(1); } std::vector collect_parameters(parser::ParseTree::Node first_node, - nodes::TypeStorage &type_storage) { + Executor &executor) { + Log::Context logc(executor.log(), Log::Area::kParse); + std::vector parameters; std::optional current_annotation; @@ -47,9 +55,11 @@ std::vector collect_parameters(parser::ParseTree::Node first_node, while (!current_node.is_null()) { if (tokens::string_to_type(current_node.get_type()) == tokens::Type::ANNOTATION_IDENTIFIER) { - current_annotation = build_annotation(current_node); + current_annotation = + BuilderTask{executor}(current_node, {}).value; } else { - parameters.push_back(build_type(current_node, type_storage)); + parameters.push_back( + BuilderTask{executor}(current_node, {})); if (current_annotation.has_value()) { parameters.back().get()->set_annotation(current_annotation.value()); } @@ -61,45 +71,55 @@ std::vector collect_parameters(parser::ParseTree::Node first_node, } nodes::Type build_container_type(parser::ParseTree::Node parser_node, - nodes::TypeStorage &type_storage, - builtin::Type container) { - std::vector parameters = - collect_parameters(parser_node.nth_named_child(0), type_storage); + Executor &executor, builtin::Type container) { + Log::Context logc(executor.log(), Log::Area::kParse); - return type_storage.add_container_of(std::move(parameters), container, - build_node(parser_node)); + std::vector parameters = + collect_parameters(parser_node.nth_named_child(0), executor); + + return executor.state().add_container_of(std::move(parameters), + container); } // '|'? annotation? type ('|' annotation? type)+ -nodes::Type build_variant_type(parser::ParseTree::Node parser_node, - nodes::TypeStorage &type_storage) { - return build_container_type(parser_node, type_storage, - builtin::Type::VARIANT); +nodes::Type BuilderTask>::operator()( + const ParserNode &parser_node, const Args &) { + Log::Context logc(executor.log(), Log::Area::kParse); + + return build_container_type(parser_node, executor, builtin::Type::VARIANT); } // '&'? annotation? type ('&' annotation? type)+ -nodes::Type build_tuple_type(parser::ParseTree::Node parser_node, - nodes::TypeStorage &type_storage) { - return build_container_type(parser_node, type_storage, builtin::Type::TUPLE); +nodes::Type BuilderTask>::operator()( + const ParserNode &parser_node, const Args &) { + Log::Context logc(executor.log(), Log::Area::kParse); + + return build_container_type(parser_node, executor, builtin::Type::TUPLE); } // _reference_ type -nodes::Type build_reference_type(parser::ParseTree::Node parser_node, - nodes::TypeStorage &type_storage) { - nodes::Type type = build_type(parser_node.nth_named_child(0), type_storage); - type.get()->set_modifier(build_modifier(parser_node.nth_child(0))); +nodes::Type BuilderTask>::operator()( + const ParserNode &parser_node, const Args &) { + Log::Context logc(executor.log(), Log::Area::kParse); + + nodes::Type type = Run(parser_node.nth_named_child(0)); + type.get()->set_modifier( + RunOther( + parser_node.nth_child(0))); return type; } // type ('?' | '!') -nodes::Type build_modified_type(parser::ParseTree::Node parser_node, - nodes::TypeStorage &type_storage) { +nodes::Type BuilderTask>::operator()( + const ParserNode &parser_node, const Args &) { + Log::Context logc(executor.log(), Log::Area::kParse); + std::vector parameters; - parameters.push_back( - build_type(parser_node.nth_named_child(0), type_storage)); + parameters.push_back(Run(parser_node.nth_named_child(0))); nodes::Modifier modifier = - build_modifier(parser_node.nth_child(parser_node.child_count() - 1)); + RunOther( + parser_node.nth_child(parser_node.child_count() - 1)); std::string identifier; @@ -111,27 +131,30 @@ nodes::Type build_modified_type(parser::ParseTree::Node parser_node, identifier = builtin::types::RESULT_IDENTIFIER; break; default: - error_handling::handle_parsing_error( - "Unexpected modifier type in modified type", parser_node); + logc.Fatal({{"Unexpected modifier type in modified type"}}, + parser_node.get_pos()); break; } - return type_storage.add_type(nodes::TypeData( - nodes::Identifier(build_node(parser_node), nodes::Identifier::SIMPLE_TYPE, - identifier), - std::move(parameters))); + return executor.state().add_type( + nodes::TypeData(nodes::Identifier{.kind = nodes::Identifier::kSimpleType, + .value = identifier}, + std::move(parameters))); } // type_identifier ('[' (annotation? type)+ ']')? -nodes::Type build_simple_type(parser::ParseTree::Node parser_node, - nodes::TypeStorage &type_storage) { +nodes::Type BuilderTask>::operator()( + const ParserNode &parser_node, const Args &) { + Log::Context logc(executor.log(), Log::Area::kParse); + auto name_node = parser_node.child_by_field_name("name"); std::vector parameters = - collect_parameters(name_node.next_named_sibling(), type_storage); + collect_parameters(name_node.next_named_sibling(), executor); - return type_storage.add_type( - nodes::TypeData(build_identifier(name_node), std::move(parameters))); + return executor.state().add_type(nodes::TypeData( + RunOther(name_node), + std::move(parameters))); } } // namespace builders diff --git a/lang/nodes/include/basic_nodes.hpp b/lang/nodes/include/basic_nodes.hpp index 85b513d..d816249 100644 --- a/lang/nodes/include/basic_nodes.hpp +++ b/lang/nodes/include/basic_nodes.hpp @@ -1,13 +1,14 @@ #pragma once +#include "log.hpp" #include "utils.hpp" +#include #include #include #include #include #include -#include namespace nodes { @@ -252,55 +253,55 @@ public: Kind kind; std::string value; - // TODO + // TODO: rewrite identifier modification - // void append_before(const std::string &name) { - // value_ = name + NAME_DELIMITER + value_; - // } + void append_before(std::string_view other) { + value = std::format("{}{}{}", other, kNameDelimiter, 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 &other, + std::source_location source_location = std::source_location::current()) { + ::utils::Assert(other.kind == kind, + "different Identifier types on append_before", + source_location); + value = std::format("{}{}{}", other.value, kNameDelimiter, value); + } - // void append_after(const std::string &name) { - // value_ += NAME_DELIMITER + name; - // } + void append_after(std::string_view other) { + value += std::format("{}{}", kNameDelimiter, other); + } - // 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 &other, + std::source_location source_location = std::source_location::current()) { + ::utils::Assert(other.kind == kind, + "different Identifier types on append_after", + source_location); + value += std::format("{}{}", kNameDelimiter, other.value); + } - // 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, kNameDelimiter)) { + fragments.push_back({ + .kind = kind, + .value = 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 - // } + std::pair split_first() { + const auto pos = value.find(kNameDelimiter); + if (pos == std::string::npos) { + return {Identifier{.kind = kind, .value = {}}, *this}; + } + return {Identifier{.kind = kind, .value = value.substr(0, pos)}, + Identifier{.kind = kind, + .value = value.substr(pos + 1)}}; // '.' is leaved + } }; struct Extra { diff --git a/lang/nodes/include/expression_nodes.hpp b/lang/nodes/include/expression_nodes.hpp index d1640a6..5add610 100644 --- a/lang/nodes/include/expression_nodes.hpp +++ b/lang/nodes/include/expression_nodes.hpp @@ -197,7 +197,8 @@ class ExprData { public: using Type = std::variant< // --- flow control - Match, Condition, Loop, + // TODO: separate Case from Match + Match, Match::Case, Condition, Loop, // --- operators // CommaExpression is OperatorExpression for operator ',' diff --git a/lang/nodes/include/nodes_storage.hpp b/lang/nodes/include/nodes_storage.hpp index 135416a..9408afd 100644 --- a/lang/nodes/include/nodes_storage.hpp +++ b/lang/nodes/include/nodes_storage.hpp @@ -7,9 +7,12 @@ namespace nodes { template class Node_; +// TODO FIXME: always require is_scoped parameter struct NodeData { public: - template NodeData(T value) : value(std::move(value)) {} + template + NodeData(T value, bool is_scoped = false) + : value(std::move(value)), is_scoped(is_scoped) {} template std::optional get() { if (std::holds_alternative(value)) { @@ -31,6 +34,7 @@ public: public: nodes::ExprData::Type value; + bool is_scoped; }; class NodeStorage : public core::Storage { @@ -79,8 +83,14 @@ public: // template T &part() { return NodePart::data_[id_]; } + template const T &part() const { + return NodePart::data_[id_]; + } template T &get() { return std::get(data_[id_].value); } + template const T &get() const { + return std::get(data_[id_].value); + } Id id() const { return id_; } diff --git a/lang/nodes/include/statement_nodes.hpp b/lang/nodes/include/statement_nodes.hpp index d8a3e1e..2bb883a 100644 --- a/lang/nodes/include/statement_nodes.hpp +++ b/lang/nodes/include/statement_nodes.hpp @@ -38,170 +38,109 @@ struct Constraint { }; struct FunctionDefinition { - class Argument { + struct Argument { public: Argument(const std::optional &annotation, Identifier &&name, Modifier before_modifier = Modifier::NONE, Modifier after_modifier = Modifier::NONE) - : annotation_(annotation), name_(std::move(name)), - before_modifier_(before_modifier), after_modifier_(after_modifier) {} + : annotation(annotation), name(std::move(name)), + before_modifier(before_modifier), after_modifier(after_modifier) {} Argument(const std::optional &annotation, const Identifier &name, Modifier before_modifier = Modifier::NONE, Modifier after_modifier = Modifier::NONE) - : annotation_(annotation), name_(name), - before_modifier_(before_modifier), after_modifier_(after_modifier) {} + : annotation(annotation), name(name), before_modifier(before_modifier), + after_modifier(after_modifier) {} Argument(const std::optional &annotation, Type type, Modifier before_modifier = Modifier::NONE) - : annotation_(annotation), type_(type), - before_modifier_(before_modifier), - after_modifier_( + : annotation(annotation), type(type), before_modifier(before_modifier), + after_modifier( builtin::types::get_modifier(type.get()->to_builtin())) {} // // add type with same annotation and same before_modifier bool update_type_from(const Argument &other) { - if (type_.has_value() || !other.type_.has_value()) { + if (type.has_value() || !other.type.has_value()) { return false; } - if (annotation_.has_value() && - (!other.annotation_.has_value() || - annotation_.value() != other.annotation_.value())) { + if (annotation.has_value() && + (!other.annotation.has_value() || + annotation.value() != other.annotation.value())) { return false; } - if (before_modifier_ != other.before_modifier_) { + if (before_modifier != other.before_modifier) { return false; } - if (after_modifier_ != other.after_modifier_) { + if (after_modifier != other.after_modifier) { return false; } - annotation_ = other.annotation_; - type_ = other.type_; - before_modifier_ = other.before_modifier_; - after_modifier_ = other.after_modifier_; + annotation = other.annotation; + type = other.type; + before_modifier = other.before_modifier; + after_modifier = other.after_modifier; return true; } // check, that argument modifiers are none or same to different from type // modifiers - bool add_type(const std::optional &annotation, Type type, - nodes::Modifier before_modifier = Modifier::NONE) { - if (type_.has_value()) { + bool add_type(const std::optional &new_annotation, + Type new_type, + nodes::Modifier new_before_modifier = Modifier::NONE) { + if (type.has_value()) { return false; } - if (annotation_.has_value() && - (!annotation.has_value() || - annotation_.value() != annotation.value())) { + if (annotation.has_value() && + (!new_annotation.has_value() || + annotation.value() != new_annotation.value())) { return false; } - if (before_modifier_ != Modifier::NONE && - before_modifier_ != before_modifier) { + if (before_modifier != Modifier::NONE && + before_modifier != new_before_modifier) { return false; } auto type_after_modifier = - builtin::types::get_modifier(type.get()->to_builtin()); + builtin::types::get_modifier(new_type.get()->to_builtin()); - if (after_modifier_ != Modifier::NONE && - after_modifier_ != type_after_modifier) { + if (after_modifier != Modifier::NONE && + after_modifier != type_after_modifier) { return false; } - annotation_ = annotation; - type_ = type; - before_modifier_ = before_modifier; - after_modifier_ = type_after_modifier; + annotation = new_annotation; + type = new_type; + before_modifier = new_before_modifier; + after_modifier = type_after_modifier; return true; } - bool add_annotation(const std::string &annotation) { - if (annotation_.has_value()) { + bool add_annotation(const std::string &new_annotation) { + if (annotation.has_value()) { return false; } - annotation_ = annotation; + annotation = new_annotation; return true; } - // - - std::optional get_annotation() { - if (annotation_.has_value()) { - return &annotation_.value(); - } - return std::nullopt; - } - - std::optional get_annotation() const { - if (annotation_.has_value()) { - return &annotation_.value(); - } - return std::nullopt; - } - - // - - std::optional get_name() { - if (name_.has_value()) { - return &name_.value(); - } - return std::nullopt; - } - - std::optional get_name() const { - if (name_.has_value()) { - return &name_.value(); - } - return std::nullopt; - } - - // - - std::optional get_type() { - if (type_.has_value()) { - return type_.value().get(); - } - return std::nullopt; - } - - std::optional get_type() const { - if (type_.has_value()) { - return type_.value().get(); - } - return std::nullopt; - } - - std::optional get_type_proxy() const { - if (type_.has_value()) { - return type_.value(); - } - return std::nullopt; - } - - // - - Modifier get_before_modifier() const { return before_modifier_; } - - Modifier get_after_modifier() const { return after_modifier_; } - - private: - std::optional annotation_; - std::optional name_; // no name for output args - std::optional type_; // no type if it is deduced - Modifier before_modifier_ = + public: + std::optional annotation; + std::optional name; // no name for output args + std::optional type; // no type if it is deduced + Modifier before_modifier = Modifier::NONE; // in, out, ref, none // sync with type - Modifier after_modifier_ = + Modifier after_modifier = Modifier::NONE; // optional, result, none // sync with type }; @@ -267,15 +206,15 @@ public: // template std::optional get() { - if (std::holds_alternative(expr)) { - return &std::get(expr); + if (std::holds_alternative(value)) { + return &std::get(value); } return std::nullopt; } template std::optional get() const { - if (std::holds_alternative(expr)) { - return &std::get(expr); + if (std::holds_alternative(value)) { + return &std::get(value); } return std::nullopt; } @@ -286,7 +225,7 @@ public: // - Type expr; + Type value; }; } // namespace nodes diff --git a/lang/nodes/src/statement_nodes.cpp b/lang/nodes/src/statement_nodes.cpp index 9adcff6..eb05aa0 100644 --- a/lang/nodes/src/statement_nodes.cpp +++ b/lang/nodes/src/statement_nodes.cpp @@ -1,7 +1,5 @@ #include "statement_nodes.hpp" -// #include "error_handling.hpp" -#include "error_handling.hpp" #include "utils.hpp" #include @@ -62,55 +60,50 @@ CombineResult FunctionDefinition::combine(FunctionDefinition &&other) { 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].annotation.has_value() && + !other.args[i].annotation.has_value()) || + (args[i].annotation.has_value() && + other.args[i].annotation.has_value() && + args[i].annotation.value() != other.args[i].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].name.has_value() && !other.args[i].name.has_value()) || + (args[i].name.has_value() && other.args[i].name.has_value() && + args[i].name.value() != other.args[i].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].type.has_value() && other.args[i].type.has_value() && + args[i].type.value() != other.args[i].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].before_modifier != other.args[i].before_modifier || + args[i].after_modifier != other.args[i].after_modifier) { return CombineResult::ARGUMENTS_ERROR; } } else if (i < args.size()) { // annotations should be the same - if (args[i].get_annotation().has_value()) { + if (args[i].annotation.has_value()) { return CombineResult::ARGUMENTS_ERROR; } // names should be the same - if (args[i].get_name().has_value()) { + if (args[i].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].annotation.has_value()) { return CombineResult::ARGUMENTS_ERROR; } // names should be the same - if (other.args[i].get_name().has_value()) { + if (other.args[i].name.has_value()) { return CombineResult::ARGUMENTS_ERROR; } } @@ -138,13 +131,11 @@ CombineResult FunctionDefinition::combine(FunctionDefinition &&other) { 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", - *this); - } + if (other.args[i].type.has_value()) { + ::utils::Assert( + not args[i].update_type_from(other.args[i]), + "Function arguments are not properly checked before merging " + "during combination"); // TODO: proper log error } } else { args.push_back(std::move(other.args[i])); @@ -231,19 +222,19 @@ CombineResult TypeDefinition::combine(TypeDefinition &&other) { } bool Statement::is_same_to(const Statement &other) const { - if (expr.index() != other.expr.index()) { + if (value.index() != other.value.index()) { return false; } - switch (expr.index()) { + switch (value.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(value).is_same_to( + std::move(std::get(other.value))); case 2: // FunctionDefinition - return std::get(expr).is_same_to( - std::move(std::get(other.expr))); + return std::get(value).is_same_to( + std::move(std::get(other.value))); case 3: // Extra return false; case 4: // EmptyLines @@ -259,30 +250,31 @@ bool Statement::is_same_to(const Statement &other) const { } CombineResult Statement::combine(Statement &&other) { - if (expr.index() != other.expr.index()) { + if (value.index() != other.value.index()) { return CombineResult::DIFFERENT_STATEMENT_TYPES; } - switch (expr.index()) { + switch (value.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(value).combine( + std::move(std::get(other.value))); case 2: // FunctionDefinition - return std::get(expr).combine( - std::move(std::get(other.expr))); + return std::get(value).combine( + std::move(std::get(other.value))); case 3: // Extra return CombineResult::STATEMENTS_CANT_BE_COMBINED_ERROR; case 4: // EmptyLines return CombineResult::STATEMENTS_CANT_BE_COMBINED_ERROR; default: - error_handling::handle_general_error( - "Unexpected statement type in combine"); + ::utils::Assert( + false, + "Unexpected statement type in combine"); // TODO: log context break; } - error_handling::handle_general_error("Unreachable"); + ::utils::Assert(false, "Unreachable"); // TODO: log context exit(1); } diff --git a/lang/printers/include/basic_printers.hpp b/lang/printers/include/basic_printers.hpp index 9b48f6b..574044e 100644 --- a/lang/printers/include/basic_printers.hpp +++ b/lang/printers/include/basic_printers.hpp @@ -1,147 +1,79 @@ #pragma once #include "basic_nodes.hpp" -#include +#include "printers_utils.hpp" namespace printers { -class Printer { -public: - Printer(std::ostream &output, size_t tab_width, size_t width_limit, - bool print_words_instead_of_symbols) - : output_(output), tab_width_(tab_width), width_limit_(width_limit), - print_words_instead_of_symbols_(print_words_instead_of_symbols), - current_position_(0), indentation_level_(0) {} +// void print(const nodes::Modifier &modifier, Printer &printer, +// bool const_is_none = false); +template <> +struct PrintTask : public PrintTaskBase { + using PrintTaskBase::PrintTaskBase; - void print_converted(const std::string &value) { - for (auto &ch : value) { - output_ << to_printable_symbol(ch); - current_position_ += to_printable_symbol(ch).size(); - } - } - - // value shouldn't contain '\n', '\t', etc. - void print(const std::string &value) { - output_ << value; - current_position_ += value.size(); - } - - void column_down() { - size_t current_position = current_position_; - end_line(); - print_spaces(current_position); - } - - void new_indent_line() { - end_line(); - print_spaces(indentation_level_); - } - - void new_line(size_t indentation) { - end_line(); - print_spaces(indentation); - } - - void to_indentation_level() { - if (indentation_level_ > current_position_) { - print_spaces(indentation_level_ - current_position_); - } - } - - void indent() { indentation_level_ += tab_width_; } - - void deindent() { indentation_level_ -= tab_width_; } - - void tab() { print_spaces(tab_width_); } - - void space() { print_spaces(1); } - - size_t current_position() const { return current_position_; } - - size_t width_limit() const { return width_limit_; } - - size_t width_left() const { - return std::max(static_cast(width_limit_) - - static_cast(current_position_), - static_cast(0)); - } - - bool print_words_instead_of_symbols() const { - return print_words_instead_of_symbols_; - } - - size_t get_current_position() const { return current_position_; } - - size_t get_indentation_level() const { return indentation_level_; } - - void set_indentation_level(size_t indentation_level) { - indentation_level_ = indentation_level; - } - -private: - void end_line() { - output_ << "\n"; - current_position_ = 0; - } - void print_spaces(size_t n) { print(std::string(n, ' ')); } - - static std::string to_printable_symbol(char ch) { - switch (ch) { - case '\a': - return "\\a"; - case '\b': - return "\\b"; - case '\e': - return "\\e"; - case '\f': - return "\\f"; - case '\n': - return "\\n"; - case '\r': - return "\\r"; - case '\t': - return "\\t"; - case '\v': - return "\\v"; - case '\'': - return "\\\'"; - case '\"': - return "\\\""; - // case ' ': - // return "\\s"; - default: - return std::string(1, ch); - } - } - -private: - std::ostream &output_; - size_t tab_width_ = 0; - size_t width_limit_ = 0; - bool print_words_instead_of_symbols_ = false; - - size_t current_position_ = 0; - size_t indentation_level_ = 0; + Result operator()(const nodes::Modifier &modifier, const Args &args) override; }; -void print(const nodes::Modifier &modifier, Printer &printer, - bool const_is_none = false); +// void print(const nodes::Literal &literal, Printer &printer); +template <> +struct PrintTask : public PrintTaskBase { + using PrintTaskBase::PrintTaskBase; -void print(const nodes::Literal &literal, Printer &printer); + Result operator()(const nodes::Literal &literal, const Args &args) override; +}; -void print(const nodes::Identifier &identifier, Printer &printer); +// void print(const nodes::Identifier &identifier, Printer &printer); +template <> +struct PrintTask : public PrintTaskBase { + using PrintTaskBase::PrintTaskBase; -void print_annotation(const std::string &annotation, Printer &printer); + Result operator()(const nodes::Identifier &identifier, + const Args &args) override; +}; -void print(const nodes::Extra &extra, Printer &printer); +// void print_annotation(const nodes::Annotation &annotation, Printer &printer); +template <> +struct PrintTask : public PrintTaskBase { + using PrintTaskBase::PrintTaskBase; -void print(const nodes::EmptyLines &empty_lines, Printer &printer); + Result operator()(const nodes::Annotation &annotation, + const Args &args) override; +}; +// void print(const nodes::Extra &extra, Printer &printer); +template <> +struct PrintTask : public PrintTaskBase { + using PrintTaskBase::PrintTaskBase; + + Result operator()(const nodes::Extra &extra, const Args &args) override; +}; + +// void print(const nodes::EmptyLines &empty_lines, Printer &printer); +template <> +struct PrintTask : public PrintTaskBase { + using PrintTaskBase::PrintTaskBase; + + Result operator()(const nodes::EmptyLines &empty_lines, + const Args &args) override; +}; + +// template +// inline void print(const std::vector &nodes, Printer &printer) { +// for (const auto &node : nodes) { +// print(node, printer); +// } +// } template -inline void print(const std::vector &nodes, Printer &printer) { - for (const auto &node : nodes) { - print(node, printer); +struct PrintTask> : public PrintTaskBase> { + using PrintTaskBase>::PrintTaskBase; + + Result operator()(const std::vector &exprs, const Args &args) override { + for (const auto &expr : exprs) { + PrintTaskBase>::Run(expr, args); + } + + return {}; } -} +}; } // namespace printers diff --git a/lang/printers/include/doc_printers.hpp b/lang/printers/include/doc_printers.hpp index 234bc51..1a6021a 100644 --- a/lang/printers/include/doc_printers.hpp +++ b/lang/printers/include/doc_printers.hpp @@ -5,6 +5,11 @@ namespace printers { -void print(const nodes::SymbolDocs &docs, Printer &printer); +template <> +struct PrintTask : public PrintTaskBase { + using PrintTaskBase::PrintTaskBase; + + Result operator()(const nodes::SymbolDocs &docs, const Args &args) override; +}; } // namespace printers diff --git a/lang/printers/include/expression_printers.hpp b/lang/printers/include/expression_printers.hpp index eca995c..f017715 100644 --- a/lang/printers/include/expression_printers.hpp +++ b/lang/printers/include/expression_printers.hpp @@ -1,44 +1,129 @@ #pragma once -#include "basic_printers.hpp" #include "expression_nodes.hpp" +#include "printers_utils.hpp" + namespace printers { -void print(const nodes::ExprData &expression, printers::Printer &printer); +template <> +struct PrintTask : public PrintTaskBase { + using PrintTaskBase::PrintTaskBase; + + Result operator()(const nodes::NodeId &expr, const Args &args) override; +}; + +template <> +struct PrintTask : public PrintTaskBase { + using PrintTaskBase::PrintTaskBase; + + Result operator()(const nodes::NodeData &expr, const Args &args) override; +}; // --- flow control -void print(const nodes::Match::Case &expression, Printer &printer); +template <> +struct PrintTask + : public PrintTaskBase { + using PrintTaskBase::PrintTaskBase; -void print(const nodes::Match &expression, printers::Printer &printer); + Result operator()(const nodes::Match::Case &expr, const Args &args) override; +}; -void print(const nodes::Condition &expression, printers::Printer &printer); +template <> +struct PrintTask : public PrintTaskBase { + using PrintTaskBase::PrintTaskBase; -void print(const nodes::Loop &expression, printers::Printer &printer); + Result operator()(const nodes::Match &expr, const Args &args) override; +}; + +template <> +struct PrintTask : public PrintTaskBase { + using PrintTaskBase::PrintTaskBase; + + Result operator()(const nodes::Condition &expr, const Args &args) override; +}; + +template <> struct PrintTask : public PrintTaskBase { + using PrintTaskBase::PrintTaskBase; + + Result operator()(const nodes::Loop &expr, const Args &args) override; +}; // --- containers -void print(const nodes::Container &expression, printers::Printer &printer); +template <> +struct PrintTask : public PrintTaskBase { + using PrintTaskBase::PrintTaskBase; + + Result operator()(const nodes::Container &expr, const Args &args) override; +}; // --- modifiers -void print(const nodes::Return &expression, printers::Printer &printer); +template <> +struct PrintTask : public PrintTaskBase { + using PrintTaskBase::PrintTaskBase; -void print(const nodes::NameDefinition &expression, printers::Printer &printer); + Result operator()(const nodes::Return &expr, const Args &args) override; +}; -void print(const nodes::Access &expression, printers::Printer &printer); +template <> +struct PrintTask + : public PrintTaskBase { + using PrintTaskBase::PrintTaskBase; -void print(const nodes::LoopControl &expression, printers::Printer &printer); + Result operator()(const nodes::NameDefinition &expr, + const Args &args) override; +}; -void print(const nodes::ModifierExpression &expression, - printers::Printer &printer); +template <> +struct PrintTask : public PrintTaskBase { + using PrintTaskBase::PrintTaskBase; + + Result operator()(const nodes::Access &expr, const Args &args) override; +}; + +template <> +struct PrintTask + : public PrintTaskBase { + using PrintTaskBase::PrintTaskBase; + + Result operator()(const nodes::LoopControl &expr, const Args &args) override; +}; + +template <> +struct PrintTask + : public PrintTaskBase { + using PrintTaskBase::PrintTaskBase; + + Result operator()(const nodes::ModifierExpression &expr, + const Args &args) override; +}; // --- other -void print(const nodes::NameExpression &expression, printers::Printer &printer); +template <> +struct PrintTask + : public PrintTaskBase { + using PrintTaskBase::PrintTaskBase; -void print(const nodes::Constructor &expression, printers::Printer &printer); + Result operator()(const nodes::NameExpression &expr, + const Args &args) override; +}; -void print(const nodes::Lambda &expression, printers::Printer &printer); +template <> +struct PrintTask + : public PrintTaskBase { + using PrintTaskBase::PrintTaskBase; + + Result operator()(const nodes::Constructor &expr, const Args &args) override; +}; + +template <> +struct PrintTask : public PrintTaskBase { + using PrintTaskBase::PrintTaskBase; + + Result operator()(const nodes::Lambda &expr, const Args &args) override; +}; } // namespace printers diff --git a/lang/printers/include/printers_utils.hpp b/lang/printers/include/printers_utils.hpp new file mode 100644 index 0000000..903f127 --- /dev/null +++ b/lang/printers/include/printers_utils.hpp @@ -0,0 +1,212 @@ +#pragma once + +#include "executor.hpp" +#include "nodes_storage.hpp" +namespace printers { + +class Printer { +public: + Printer(std::ostream &output, size_t tab_width, size_t width_limit, + bool print_words_instead_of_symbols) + : output_(output), tab_width_(tab_width), width_limit_(width_limit), + print_words_instead_of_symbols_(print_words_instead_of_symbols), + current_position_(0), indentation_level_(0) {} + + void PrintConverted(std::string_view value) { + for (auto &ch : value) { + output_ << ToPrintableSymbol(ch); + current_position_ += ToPrintableSymbol(ch).size(); + } + } + + // value shouldn't contain '\n', '\t', etc. + void Print(std::string_view value) { + output_ << value; + current_position_ += value.size(); + } + + void ColumnDown() { + size_t current_position = current_position_; + EndLine(); + PrintSpaces(current_position); + } + + void NewIndentLine() { + EndLine(); + PrintSpaces(indentation_level_); + } + + void NewLine(size_t indentation) { + EndLine(); + PrintSpaces(indentation); + } + + void ToIndentationLevel() { + if (indentation_level_ > current_position_) { + PrintSpaces(indentation_level_ - current_position_); + } + } + + void Indent() { indentation_level_ += tab_width_; } + + void Deindent() { indentation_level_ -= tab_width_; } + + void Tab() { PrintSpaces(tab_width_); } + + void Space() { PrintSpaces(1); } + + void SetIndentationLevel(size_t indentation) { + indentation_level_ = indentation; + } + + // + + bool words_instead_of_symbols() const { + return print_words_instead_of_symbols_; + } + + size_t current_position() const { return current_position_; } + + size_t width_limit() const { return width_limit_; } + + size_t width_left() const { + return std::max(static_cast(width_limit_) - + static_cast(current_position_), + static_cast(0)); + } + + size_t indentation_level() const { return indentation_level_; } + +private: + void EndLine() { + output_ << "\n"; + current_position_ = 0; + } + void PrintSpaces(size_t n) { Print(std::string(n, ' ')); } + + static std::string ToPrintableSymbol(char ch) { + switch (ch) { + case '\a': + return "\\a"; + case '\b': + return "\\b"; + case '\e': + return "\\e"; + case '\f': + return "\\f"; + case '\n': + return "\\n"; + case '\r': + return "\\r"; + case '\t': + return "\\t"; + case '\v': + return "\\v"; + case '\'': + return "\\\'"; + case '\"': + return "\\\""; + // case ' ': + // return "\\s"; + default: + return std::string(1, ch); + } + } + +private: + std::ostream &output_; + size_t tab_width_ = 0; + size_t width_limit_ = 0; + bool print_words_instead_of_symbols_ = false; + + size_t current_position_ = 0; + size_t indentation_level_ = 0; +}; + +using Exprs = nodes::NodeStorage; // nodes::ExprStorage; + +using Executor = utils::Executor; + +using Node = nodes::Node_<>; + +struct Args { + // TODO FIXME + bool const_is_none = false; +}; + +using Result = utils::None; + +template using Task = utils::Task; + +template struct PrintTask { + static_assert(false); +}; + +template struct PrintTaskBase : public Task { + using Task::Task; + + Node Ext(storage::Id id) { return Node(id, this->template state()); } + + template + Result Run(const OtherN &node, const Args &args = {}) { + PrintTask task(this->executor); + return task(node, args); + } + + // + + void PrintConverted(const std::string_view value) { + Task::template state().PrintConverted(value); + } + + // value shouldn't contain '\n', '\t', etc. + void Print(std::string_view value) { + Task::template state().Print(value); + } + + void ColumnDown() { Task::template state().ColumnDown(); } + + void NewIndentLine() { Task::template state().NewIndentLine(); } + + void NewLine(size_t indentation) { + Task::template state().NewLine(indentation); + } + + void ToIndentationLevel() { + Task::template state().ToIndentationLevel(); + } + + void Indent() { Task::template state().Indent(); } + + void Deindent() { Task::template state().Deindent(); } + + void Tab() { Task::template state().Tab(); } + + void Space() { Task::template state().Space(); } + + void SetIndentationLevel(size_t indentation) { + Task::template state().SetIndentationLevel(indentation); + } + + // + + bool words_instead_of_symbols() const { + return Task::template state().words_instead_of_symbols(); + } + + size_t current_position() const { + return Task::template state().current_position(); + } + + size_t width_limit() const { + return Task::template state().width_limit(); + } + + size_t width_left() const { Task::template state().width_left(); } + + size_t indentation_level() const { + return Task::template state().indentation_level(); + } +}; + +} // namespace printers diff --git a/lang/printers/include/statement_printers.hpp b/lang/printers/include/statement_printers.hpp index 7fd745c..9c12d47 100644 --- a/lang/printers/include/statement_printers.hpp +++ b/lang/printers/include/statement_printers.hpp @@ -1,23 +1,52 @@ #pragma once -#include "basic_printers.hpp" +#include "printers_utils.hpp" #include "statement_nodes.hpp" -#include - namespace printers { // void print_source_file(const std::vector &statements, // Printer &printer); -void print(const nodes::Statement &statements, Printer &printer); +template <> +struct PrintTask : public PrintTaskBase { + using PrintTaskBase::PrintTaskBase; -void print(const nodes::Import &statement, Printer &printer); + Result operator()(const nodes::Statement &statement, + const Args &args) override; +}; -void print(const nodes::Constraint &statement, Printer &printer); +template <> +struct PrintTask : public PrintTaskBase { + using PrintTaskBase::PrintTaskBase; -void print(const nodes::TypeDefinition &statement, Printer &printer); + Result operator()(const nodes::Import &statement, const Args &args) override; +}; -void print(const nodes::FunctionDefinition &statement, Printer &printer); +template <> +struct PrintTask : public PrintTaskBase { + using PrintTaskBase::PrintTaskBase; + + Result operator()(const nodes::Constraint &statement, + const Args &args) override; +}; + +template <> +struct PrintTask + : public PrintTaskBase { + using PrintTaskBase::PrintTaskBase; + + Result operator()(const nodes::TypeDefinition &statement, + const Args &args) override; +}; + +template <> +struct PrintTask + : public PrintTaskBase { + using PrintTaskBase::PrintTaskBase; + + Result operator()(const nodes::FunctionDefinition &statement, + const Args &args) override; +}; } // namespace printers diff --git a/lang/printers/include/type_printers.hpp b/lang/printers/include/type_printers.hpp index 28bc71e..812b47c 100644 --- a/lang/printers/include/type_printers.hpp +++ b/lang/printers/include/type_printers.hpp @@ -5,7 +5,18 @@ namespace printers { -void print(const nodes::TypeData &type, printers::Printer &printer); +template <> struct PrintTask : public PrintTaskBase { + using PrintTaskBase::PrintTaskBase; + + Result operator()(const nodes::Type &type, const Args &args) override; +}; + +template <> +struct PrintTask : public PrintTaskBase { + using PrintTaskBase::PrintTaskBase; + + Result operator()(const nodes::TypeData &type, const Args &args) override; +}; // void print_tuple_type(const nodes::TupleType &type, printers::Printer // &printer); diff --git a/lang/printers/src/basic_printers.cpp b/lang/printers/src/basic_printers.cpp index 61b57dd..6c3f112 100644 --- a/lang/printers/src/basic_printers.cpp +++ b/lang/printers/src/basic_printers.cpp @@ -7,157 +7,161 @@ namespace printers { -void print(const nodes::Modifier &modifier, Printer &printer, - bool const_is_none) { +Result PrintTask::operator()(const nodes::Modifier &modifier, + const Args &args) { switch (modifier) { case nodes::Modifier::IN: - printer.print(printer.print_words_instead_of_symbols() ? "in " : "<- "); + Print(words_instead_of_symbols() ? "in " : "<- "); break; case nodes::Modifier::REF: - printer.print(printer.print_words_instead_of_symbols() ? "ref " : "<> "); + Print(words_instead_of_symbols() ? "ref " : "<> "); break; case nodes::Modifier::CONST: - if (!const_is_none) { - printer.print(printer.print_words_instead_of_symbols() ? "ref " : "<> "); + if (!args.const_is_none) { + Print(words_instead_of_symbols() ? "ref " : "<> "); } break; case nodes::Modifier::OUT: - printer.print(printer.print_words_instead_of_symbols() ? "out " : "-> "); + Print(words_instead_of_symbols() ? "out " : "-> "); break; // --- case nodes::Modifier::IN_OR_REF: - printer.print(printer.print_words_instead_of_symbols() ? "in|ref " - : "<-|<> "); + Print(words_instead_of_symbols() ? "in|ref " : "<-|<> "); break; case nodes::Modifier::IN_OR_CONST: - printer.print(printer.print_words_instead_of_symbols() ? "in|const " - : "<-|-- "); + Print(words_instead_of_symbols() ? "in|const " : "<-|-- "); break; case nodes::Modifier::REF_OR_OUT: - printer.print(printer.print_words_instead_of_symbols() ? "ref|out " - : "<>|-> "); + Print(words_instead_of_symbols() ? "ref|out " : "<>|-> "); break; case nodes::Modifier::CONST_OR_OUT: - printer.print(printer.print_words_instead_of_symbols() ? "const|out " - : "--|-> "); + Print(words_instead_of_symbols() ? "const|out " : "--|-> "); break; case nodes::Modifier::REF_OR_CONST: - printer.print(printer.print_words_instead_of_symbols() ? "ref|const " - : "<>|-- "); + Print(words_instead_of_symbols() ? "ref|const " : "<>|-- "); break; case nodes::Modifier::IN_OR_OUT: - printer.print(printer.print_words_instead_of_symbols() ? "in|out " - : "<-|-> "); + Print(words_instead_of_symbols() ? "in|out " : "<-|-> "); break; // --- case nodes::Modifier::IN_OR_REF_OR_OUT: - printer.print(printer.print_words_instead_of_symbols() ? "in|ref|out " - : "<-|<>|-> "); + Print(words_instead_of_symbols() ? "in|ref|out " : "<-|<>|-> "); break; case nodes::Modifier::IN_OR_CONST_OR_OUT: - printer.print(printer.print_words_instead_of_symbols() ? "in|const|out " - : "<-|--|-> "); + Print(words_instead_of_symbols() ? "in|const|out " : "<-|--|-> "); break; case nodes::Modifier::IN_OR_REF_OR_CONST: - printer.print(printer.print_words_instead_of_symbols() ? "in|ref|const " - : "<-|<>|-- "); + Print(words_instead_of_symbols() ? "in|ref|const " : "<-|<>|-- "); break; case nodes::Modifier::REF_OR_CONST_OR_OUT: - printer.print(printer.print_words_instead_of_symbols() ? "ref|const|out " - : "<>|--|-> "); + Print(words_instead_of_symbols() ? "ref|const|out " : "<>|--|-> "); break; // --- case nodes::Modifier::IN_OR_REF_OR_CONST_OR_OUT: - printer.print(printer.print_words_instead_of_symbols() ? "in|ref|const|out " - : "<-|<>|--|-> "); + Print(words_instead_of_symbols() ? "in|ref|const|out " : "<-|<>|--|-> "); break; // case nodes::Modifier::OPTIONAL: - printer.print("?"); + Print("?"); break; case nodes::Modifier::RESULT: - printer.print("!"); + Print("!"); break; case nodes::Modifier::NONE: break; default: break; } + return {}; } -void print(const nodes::Literal &literal, Printer &printer) { - switch (literal.get_any().index()) { +Result PrintTask::operator()(const nodes::Literal &literal, + const Args &) { + switch (literal.value.index()) { case 0: // float - printer.print(std::to_string(*literal.get().value())); - return; + Print(std::to_string(*literal.get().value())); + return {}; case 1: // double - printer.print(std::to_string(*literal.get().value())); - return; + Print(std::to_string(*literal.get().value())); + break; case 2: // int32_t - printer.print(std::to_string(*literal.get().value())); - return; + Print(std::to_string(*literal.get().value())); + break; case 3: // int64_t - printer.print(std::to_string(*literal.get().value())); - return; + Print(std::to_string(*literal.get().value())); + break; case 4: // size_t - printer.print(std::to_string(*literal.get().value())); - return; + Print(std::to_string(*literal.get().value())); + break; case 5: // std::string - printer.print("\""); - printer.print_converted( - *literal.get() - .value()); // special symbols are converted inside - printer.print("\""); - return; + Print("\""); + PrintConverted(*literal.get() + .value()); // special symbols are converted inside + Print("\""); + break; case 6: // unicode_string - printer.print("\""); - printer.print_converted(literal.get() - .value() - ->str); // special symbols are converted inside - printer.print("\"u"); - return; + Print("\""); + PrintConverted(literal.get() + .value() + ->str); // special symbols are converted inside + Print("\"u"); + break; case 7: // char - printer.print("\'\'"); - printer.print_converted(std::string(1, *literal.get().value())); - printer.print("\'\'"); - return; + Print("\'\'"); + PrintConverted(std::string(1, *literal.get().value())); + Print("\'\'"); + break; case 8: // unicode - printer.print("\'\'"); - printer.print_converted(literal.get().value()->ch); - printer.print("\'\'u"); - return; + Print("\'\'"); + PrintConverted(literal.get().value()->ch); + Print("\'\'u"); + break; case 9: // bool - printer.print(*literal.get().value() ? "true" : "false"); - return; + Print(*literal.get().value() ? "true" : "false"); + break; case 10: // unit - printer.print("()"); - return; + Print("()"); + break; case 11: // null - printer.print("null"); - return; + Print("null"); + break; + default: + error_handling::handle_general_error("Unreachable"); + exit(1); // unreachable + break; } - error_handling::handle_general_error("Unreachable"); - exit(1); // unreachable + return {}; } -void print(const nodes::Identifier &identifier, Printer &printer) { - printer.print(*identifier.get()); +Result +PrintTask::operator()(const nodes::Identifier &identifier, + const Args &) { + Print(identifier.value); + return {}; } -void print_annotation(const std::string &annotation, Printer &printer) { - printer.print("@"); - printer.print(annotation); +Result +PrintTask::operator()(const nodes::Annotation &annotation, + const Args &) { + Print("@"); + Print(annotation.value); + return {}; } -void print(const nodes::Extra &extra, Printer &printer) { - printer.print(*extra.content()); +Result PrintTask::operator()(const nodes::Extra &extra, + const Args &) { + Print(extra.content); + return {}; } -void print(const nodes::EmptyLines &empty_lines, Printer &printer) { - for (size_t i = 0; i < empty_lines.line_count(); ++i) { - printer.new_indent_line(); +Result +PrintTask::operator()(const nodes::EmptyLines &empty_lines, + const Args &) { + for (size_t i = 0; i < empty_lines.count; ++i) { + NewIndentLine(); } + return {}; } } // namespace printers diff --git a/lang/printers/src/doc_printers.cpp b/lang/printers/src/doc_printers.cpp index e596978..10c60c7 100644 --- a/lang/printers/src/doc_printers.cpp +++ b/lang/printers/src/doc_printers.cpp @@ -6,29 +6,31 @@ namespace printers { // TODO -void print(const nodes::SymbolDocs &docs, Printer &printer) { +Result PrintTask::operator()(const nodes::SymbolDocs &docs, + const Args &) { auto description = docs.get_description(); if (description.has_value()) { - printer.print(": "); + Print(": "); for (auto &ch : *description.value()) { if (ch == '\n') { - printer.new_indent_line(); - printer.print(": "); + NewIndentLine(); + Print(": "); } else { - printer.print(std::string(1, ch)); + Print(std::string(1, ch)); } } - printer.new_indent_line(); + NewIndentLine(); } for (size_t i = 0; i < docs.annotations_info_size(); ++i) { - print_annotation(*docs.get_annotation(i), printer); - printer.space(); - printer.print(*docs.get_annotation_info(i)); - printer.new_indent_line(); + Run(nodes::Annotation{*docs.get_annotation(i)}); + Space(); + Print(*docs.get_annotation_info(i)); + NewIndentLine(); } + return {}; } // IN PROGRESS } // namespace printers diff --git a/lang/printers/src/expression_printers.cpp b/lang/printers/src/expression_printers.cpp index 91bebb4..588f232 100644 --- a/lang/printers/src/expression_printers.cpp +++ b/lang/printers/src/expression_printers.cpp @@ -5,375 +5,417 @@ #include "type_printers.hpp" #include "utils.hpp" +// TODO Run, get for Ids + namespace printers { namespace utils { -bool is_block_expression(const nodes::ExprData &expression) { - return expression.get().has_value() && - expression.get().value()->get_type() == - nodes::Container::BLOCK; +bool is_block_expression(const Node &expr) { + return expr.Holds() && + expr.get().kind == nodes::Container::BLOCK; } } // namespace utils -void print(const nodes::ExprData &expression, printers::Printer &printer) { - if (expression.is_scoped()) { - printer.print("("); +Result PrintTask::operator()(const nodes::NodeId &expr, + const Args &args) { + Run(*Ext(expr), args); + + return {}; +} + +Result PrintTask::operator()(const nodes::NodeData &expr, + const Args &args) { + if (expr.is_scoped) { + Print("("); } - std::visit([&printer](const auto &arg) -> void { print(arg, printer); }, - expression.get_any()); + std::visit([this, &args](const auto &expr) -> void { Run(expr, args); }, + expr.value); - if (expression.is_scoped()) { - printer.print(")"); + if (expr.is_scoped) { + Print(")"); } + + return {}; } // --- flow control -void print(const nodes::Match::Case &expression, Printer &printer) { +Result PrintTask::operator()(const nodes::Match::Case &expr, + const Args &) { - switch (expression.kind()) { + switch (expr.kind) { case nodes::Match::Case::PATTERN_VALUE: - printer.print(":="); + Print(":="); break; case nodes::Match::Case::VALUE_PATTERN: - printer.print("=:"); + Print("=:"); break; } - printer.space(); + Space(); - print(*expression.get_value(), printer); + Run(expr.value); - if (expression.get_condition().has_value()) { - printer.print(printer.print_words_instead_of_symbols() ? " if " : " ?? "); - print(*expression.get_condition().value(), printer); + if (expr.condition.has_value()) { + Print(words_instead_of_symbols() ? " if " : " ?? "); + Run(expr.condition.value()); } - if (expression.get_expression().has_value()) { - printer.print(printer.print_words_instead_of_symbols() ? " do " : " => "); - print(*expression.get_expression().value(), printer); + if (expr.expr.has_value()) { + Print(words_instead_of_symbols() ? " do " : " => "); + Run(expr.expr.value()); } + + return {}; } // IN PROGRESS -void print(const nodes::Match &expression, printers::Printer &printer) { - print(*expression.get_value(), printer); +Result PrintTask::operator()(const nodes::Match &expr, + const Args &) { + Run(expr.value, {}); - printer.space(); + Space(); - size_t previous_indentation_level = printer.get_indentation_level(); + size_t previous_indentation_level = indentation_level(); - printer.set_indentation_level(printer.current_position()); + SetIndentationLevel(current_position()); - for (size_t i = 0; i < expression.cases_size(); ++i) { - print(*expression.get_case(i), printer); + for (size_t i = 0; i < expr.cases.size(); ++i) { + Run(expr.cases.at(i)); - if (i + 1 < expression.cases_size()) { - printer.new_indent_line(); + if (i + 1 < expr.cases.size()) { + NewIndentLine(); } } - printer.set_indentation_level(previous_indentation_level); + SetIndentationLevel(previous_indentation_level); + return {}; } // IN PROGRESS -void print(const nodes::Condition &expression, printers::Printer &printer) { +Result PrintTask::operator()(const nodes::Condition &expr, + const Args &) { - for (size_t i = 0; i < expression.cases_size(); ++i) { + for (size_t i = 0; i < expr.cases.size(); ++i) { if (i > 0) { - if (utils::is_block_expression(*expression.get_case(i - 1).second)) { - printer.space(); + if (utils::is_block_expression( + Ext(expr.cases.at(i - 1).second))) { // TODO + Space(); } else { - printer.new_indent_line(); + NewIndentLine(); } } if (i == 0) { - printer.print(printer.print_words_instead_of_symbols() ? "if " : "?? "); + Print(words_instead_of_symbols() ? "if " : "?? "); } else { - printer.print(printer.print_words_instead_of_symbols() ? "elif " : "!! "); + Print(words_instead_of_symbols() ? "elif " : "!! "); } - print(*expression.get_case(i).first, printer); + Run(expr.cases.at(i).first); - printer.print(printer.print_words_instead_of_symbols() ? " do " : " => "); + Print(words_instead_of_symbols() ? " do " : " => "); - print(*expression.get_case(i).second, printer); + Run(expr.cases.at(i).second); } - if (expression.cases_size() == 0) { + if (expr.cases.size() == 0) { error_handling::handle_general_error( "Condition with zero cases"); // TODO ?? } - if (expression.get_else_case().has_value()) { + if (expr.else_case.has_value()) { if (utils::is_block_expression( - *expression.get_case(expression.cases_size() - 1).second)) { - printer.space(); + Ext(expr.cases.at(expr.cases.size() - 1).second))) { + Space(); } else { - printer.new_indent_line(); + NewIndentLine(); } - printer.print(printer.print_words_instead_of_symbols() ? "else " : "!!=> "); - print(*expression.get_else_case().value(), printer); + Print(words_instead_of_symbols() ? "else " : "!!=> "); + Run(expr.else_case.value()); } + + return {}; } -void print(const nodes::Loop &expression, printers::Printer &printer) { - printer.print(printer.print_words_instead_of_symbols() ? "for" : "@"); +Result PrintTask::operator()(const nodes::Loop &expr, + const Args &) { + Print(words_instead_of_symbols() ? "for" : "@"); - switch (expression.get_type()) { + switch (expr.kind) { case nodes::Loop::LOOP: - printer.space(); + Space(); break; case nodes::Loop::WHILE: - printer.space(); - print(*expression.get_condition().value(), printer); - printer.space(); + Space(); + Run(expr.condition.value()); + Space(); break; case nodes::Loop::FOR: - printer.space(); - print(*expression.get_variable().value(), printer); - printer.print(" : "); - print(*expression.get_interval().value(), printer); - printer.space(); + Space(); + Run(expr.variable.value()); + Print(" : "); + Run(expr.interval.value()); + Space(); break; } - printer.print(printer.print_words_instead_of_symbols() ? "do " : "=> "); + Print(words_instead_of_symbols() ? "do " : "=> "); - print(*expression.get_expression(), printer); + Run(expr.expr); + + return {}; } // IN PROGRESS // --- containers -void print(const nodes::Container &expression, printers::Printer &printer) { - bool is_array = expression.get_type() == nodes::Container::ARRAY; +Result PrintTask::operator()(const nodes::Container &expr, + const Args &) { + bool is_array = expr.kind == nodes::Container::ARRAY; if (is_array) { - printer.print("[["); + Print("[["); } else { - printer.print("{"); - printer.indent(); + Print("{"); + Indent(); } - for (size_t i = 0; i < expression.expressions_size(); ++i) { - bool is_empty_lines = - expression.get_expression(i)->get().has_value(); - - bool is_extra = - expression.get_expression(i)->get().has_value(); + for (size_t i = 0; i < expr.exprs.size(); ++i) { + bool is_empty_lines = Ext(expr.exprs.at(i)).Holds(); + bool is_extra = Ext(expr.exprs.at(i)).Holds(); if (!is_array && !is_empty_lines) { - printer.new_indent_line(); + NewIndentLine(); } - print(*expression.get_expression(i), printer); + Run(expr.exprs.at(i)); if (is_array) { - if (i + 1 < expression.expressions_size()) { - printer.space(); + if (i + 1 < expr.exprs.size()) { + Space(); } } else { if (!is_empty_lines && !is_extra) { - printer.print(";"); + Print(";"); } } } if (is_array) { - printer.print("]]"); + Print("]]"); } else { - printer.deindent(); - printer.new_indent_line(); - printer.print("}"); + Deindent(); + NewIndentLine(); + Print("}"); } + + return {}; } // IN PROGRESS // --- modifiers -void print(const nodes::Return &expression, printers::Printer &printer) { +Result PrintTask::operator()(const nodes::Return &expr, + const Args &) { - switch (expression.get_type()) { + switch (expr.kind) { case nodes::Return::RETURN: - printer.print("return "); + Print("return "); break; case nodes::Return::BRING: - printer.print("bring "); + Print("bring "); break; default: break; } - print(*expression.get_expression(), printer); + Run(expr.expr); + + return {}; } -void print(const nodes::NameDefinition &expression, - printers::Printer &printer) { +Result +PrintTask::operator()(const nodes::NameDefinition &expr, + const Args &) { - if (printer.print_words_instead_of_symbols()) { - switch (expression.get_modifier()) { + if (words_instead_of_symbols()) { + switch (expr.kind) { case nodes::NameDefinition::LET: - printer.print("let "); + Print("let "); break; case nodes::NameDefinition::VAR: - printer.print("var "); + Print("var "); break; default: break; } } else { - switch (expression.get_modifier()) { + switch (expr.kind) { case nodes::NameDefinition::LET: - printer.print("%"); + Print("%"); break; case nodes::NameDefinition::VAR: - printer.print("$"); + Print("$"); break; default: break; } } - print(*expression.get_name(), printer); + Run(expr.name); + + return {}; } -void print(const nodes::Access &expression, printers::Printer &printer) { - print(*expression.get_value(), printer); +Result PrintTask::operator()(const nodes::Access &expr, + const Args &) { + Run(expr.value); - switch (expression.get_type()) { + switch (expr.kind) { case nodes::Access::ARRAY: - printer.print("["); + Print("["); break; case nodes::Access::TUPLE: - printer.print("."); + Print("."); break; default: break; } - print(*expression.get_index(), printer); + Run(expr.index); - switch (expression.get_type()) { + switch (expr.kind) { case nodes::Access::ARRAY: - printer.print("]"); + Print("]"); break; case nodes::Access::TUPLE: break; default: break; } + + return {}; } -void print(const nodes::LoopControl &expression, printers::Printer &printer) { - switch (expression.get_type()) { +Result PrintTask::operator()(const nodes::LoopControl &expr, + const Args &) { + switch (expr.kind) { case nodes::LoopControl::BREAK: - printer.print("break"); + Print("break"); break; case nodes::LoopControl::CONTINUE: - printer.print("continue"); + Print("continue"); break; default: break; } + + return {}; } -void print(const nodes::ModifierExpression &expression, - printers::Printer &printer) { - if (expression.get_modifier() != nodes::Modifier::OPTIONAL && - expression.get_modifier() != nodes::Modifier::RESULT) { - print(expression.get_modifier(), printer); +Result PrintTask::operator()( + const nodes::ModifierExpression &expr, const Args &) { + if (expr.modifier != nodes::Modifier::OPTIONAL && + expr.modifier != nodes::Modifier::RESULT) { + Run(expr.modifier); } - print(*expression.get_expression(), printer); + Run(expr.expr); - if (expression.get_modifier() == nodes::Modifier::OPTIONAL || - expression.get_modifier() == nodes::Modifier::RESULT) { - print(expression.get_modifier(), printer); + if (expr.modifier == nodes::Modifier::OPTIONAL || + expr.modifier == nodes::Modifier::RESULT) { + Run(expr.modifier); } + + return {}; } // --- other -void print(const nodes::NameExpression &expression, - printers::Printer &printer) { - bool is_comma_operator = (*expression.get_name()->get() == ","); - bool is_range_operator = (*expression.get_name()->get() == ".."); +Result +PrintTask::operator()(const nodes::NameExpression &expr, + const Args &) { + bool is_comma_operator = (expr.name.value == ","); + bool is_range_operator = (expr.name.value == ".."); - if (expression.is_operator_call() || expression.is_point_call()) { - print(*expression.get_argument_value(0), printer); - if (expression.is_point_call()) { - printer.print("."); + if (expr.is_operator_call || expr.is_point_call) { + Run(expr.args.at(0).second); + if (expr.is_point_call) { + Print("."); // not comma operator and not range operator } else if (!is_comma_operator && !is_range_operator) { - printer.space(); + Space(); } - } else if (expression.get_prefix().has_value()) { - print(*expression.get_prefix().value(), printer); - printer.print("."); + } else if (expr.prefix.has_value()) { + Run(expr.prefix.value()); + Print("."); } // bool operator_called_as_function = - (!expression.is_operator_call() && - expression.get_name()->get_type() == nodes::Identifier::kOperator); + (!expr.is_operator_call && + expr.name.kind == nodes::Identifier::kOperator); if (operator_called_as_function) { - printer.print("( "); + Print("( "); } - print(*expression.get_name(), printer); + Run(expr.name); if (operator_called_as_function) { - printer.print(" )"); + Print(" )"); } // - for (size_t i = - expression.is_operator_call() || expression.is_point_call() ? 1 : 0; - i < expression.args_size(); ++i) { - if (!expression.is_operator_call() || !is_range_operator || i > 1) { - printer.space(); + for (size_t i = expr.is_operator_call || expr.is_point_call ? 1 : 0; + i < expr.args.size(); ++i) { + if (!expr.is_operator_call || !is_range_operator || i > 1) { + Space(); } - if (expression.get_argument_annotation(i).has_value()) { - print_annotation(*expression.get_argument_annotation(i).value(), printer); - printer.space(); + if (expr.args.at(i).first.has_value()) { + Run(nodes::Annotation{expr.args.at(i).first.value()}); + Space(); } - print(*expression.get_argument_value(i), printer); + Run(expr.args.at(i).second); } + return {}; } // IN PROGRESS -void print(const nodes::Constructor &expression, printers::Printer &printer) { - print(*expression.get_type(), printer); +Result PrintTask::operator()(const nodes::Constructor &expr, + const Args &) { + Run(expr.type); - for (size_t i = 0; i < expression.args_size(); ++i) { - printer.space(); + for (size_t i = 0; i < expr.args.size(); ++i) { + Space(); - if (expression.get_argument_annotation(i).has_value()) { - print_annotation(*expression.get_argument_annotation(i).value(), printer); - printer.space(); + if (expr.args.at(i).first.has_value()) { + Run(nodes::Annotation{expr.args.at(i).first.value()}); + Space(); } - print(*expression.get_argument_value(i), printer); + Run(expr.args.at(i).second); } + return {}; } // IN PROGRESS -void print(const nodes::Lambda &expression, printers::Printer &printer) { - printer.print(printer.print_words_instead_of_symbols() ? "lambda " : "\\ "); +Result PrintTask::operator()(const nodes::Lambda &expr, + const Args &) { + Print(words_instead_of_symbols() ? "lambda " : "\\ "); - for (size_t i = 0; i < expression.args_size(); ++i) { - print(*expression.get_argument(i), printer); - printer.space(); + for (size_t i = 0; i < expr.args.size(); ++i) { + Run(expr.args.at(i)); + Space(); } - printer.print(printer.print_words_instead_of_symbols() ? "do " : "=> "); + Print(words_instead_of_symbols() ? "do " : "=> "); - print(*expression.get_expression(), printer); + Run(expr.expr); + return {}; } // IN PROGRESS } // namespace printers diff --git a/lang/printers/src/statement_printers.cpp b/lang/printers/src/statement_printers.cpp index 1a09c32..409724d 100644 --- a/lang/printers/src/statement_printers.cpp +++ b/lang/printers/src/statement_printers.cpp @@ -17,177 +17,189 @@ namespace printers { // } // } -void print(const nodes::Statement &statement, Printer &printer) { - std::visit([&printer](const auto &arg) -> void { print(arg, printer); }, - statement.get_any()); +Result +PrintTask::operator()(const nodes::Statement &statement, + const Args &) { + std::visit([this](const auto &arg) -> void { Run(arg); }, statement.value); if (not statement.get().has_value()) { - printer.new_indent_line(); + NewIndentLine(); } + + return {}; } -void print(const nodes::Import &statement, Printer &printer) { - printer.print(":: "); +Result PrintTask::operator()(const nodes::Import &statement, + const Args &) { + Print(":: "); - print(*statement.get_import_name(), printer); + Run(statement.import_name); - if (*statement.get_import_name()->get() != - *statement.get_module_name()->get()) { - printer.print(" = "); - print(*statement.get_module_name(), printer); + if (statement.import_name.value != statement.module_name.value) { + Print(" = "); + Run(statement.module_name); } - if (statement.symbols_size() > 0) { - printer.print(" :"); - for (size_t i = 0; i < statement.symbols_size(); ++i) { - printer.space(); + if (not statement.symbols.empty()) { + Print(" :"); + for (const auto &symbol : statement.symbols) { + Space(); bool identifier_is_operator = - (statement.get_symbol(i)->get_type() == nodes::Identifier::OPERATOR); + (symbol.kind == nodes::Identifier::kOperator); if (identifier_is_operator) { - printer.print("( "); + Print("( "); } - print(*statement.get_symbol(i), printer); + Run(symbol); if (identifier_is_operator) { - printer.print(" )"); + Print(" )"); } } } - printer.print(";"); + Print(";"); + + return {}; } // IN PROGRESS -void print(const nodes::Constraint &statement, Printer &printer) { - printer.print("? "); - print(*statement.get_expression(), printer); - printer.print(";"); +Result +PrintTask::operator()(const nodes::Constraint &statement, + const Args &) { + Print("? "); + Run(statement.expr); + Print(";"); + + return {}; } -void print(const nodes::TypeDefinition &statement, Printer &printer) { - print(*statement.get_docs(), printer); +Result PrintTask::operator()( + const nodes::TypeDefinition &statement, const Args &) { + Run(statement.docs); - if (statement.is_on_heap()) { - printer.print("<> "); + if (statement.is_on_heap) { + Print("<> "); } - print(*statement.get_name(), printer); + Run(statement.name); - for (size_t i = 0; i < statement.args_size(); ++i) { - printer.space(); - print(*statement.get_argument(i), printer); + for (const auto &arg : statement.args) { + Space(); + Run(arg); } - if (statement.get_type().has_value()) { - printer.print(" = "); + if (statement.type.has_value()) { + Print(" = "); - size_t previous_indentation_level = printer.get_indentation_level(); + size_t previous_indentation_level = indentation_level(); - printer.set_indentation_level(printer.get_current_position() - 2); + SetIndentationLevel(current_position() - 2); - print(*statement.get_type().value().get(), printer); + Run(statement.type.value()); - printer.set_indentation_level(previous_indentation_level); + SetIndentationLevel(previous_indentation_level); } - printer.print(";"); + Print(";"); + + return {}; } // IN PROGRESS // TODO: do not print prefix type for names -void print(const nodes::FunctionDefinition &statement, Printer &printer) { - print(*statement.get_docs(), printer); +Result PrintTask::operator()( + const nodes::FunctionDefinition &statement, const Args &) { + Run(statement.docs); - for (size_t i = 0; i < statement.constraints_size(); ++i) { - print(*statement.get_constraint(i), printer); - printer.new_indent_line(); + for (const auto &constraint : statement.constraints) { + Run(constraint); + NewIndentLine(); } - if (statement.is_method()) { - printer.print("."); + if (statement.is_method) { + Print("."); } bool identifier_is_operator = - (statement.get_name()->get_type() == nodes::Identifier::OPERATOR); + (statement.name.kind == nodes::Identifier::kOperator); if (identifier_is_operator) { - printer.print("( "); + Print("( "); } - print(*statement.get_name(), printer); + Run(statement.name); if (identifier_is_operator) { - printer.print(" )"); + Print(" )"); } - print(statement.get_return_modifier(), printer); // ! or ? + Run(statement.return_modifier); // ! or ? - for (size_t i = 0; i < statement.args_size(); ++i) { - if (!statement.get_argument(i)->get_name().has_value()) { + for (const auto &arg : statement.args) { + if (not arg.name.has_value()) { break; } - printer.space(); + Space(); // all args are typed or are untyped in the same time - if (!statement.get_argument(i)->get_type().has_value()) { + if (not arg.type.has_value()) { // print annotation - if (!statement.are_annotations_same_to_names() && - statement.get_argument(i)->get_annotation().has_value()) { - print_annotation(*statement.get_argument(i)->get_annotation().value(), - printer); - printer.space(); + if (not statement.are_annotations_same_to_names && + arg.annotation.has_value()) { + Run(nodes::Annotation{arg.annotation.value()}); + Space(); } - print(statement.get_argument(i)->get_before_modifier(), printer, true); + Run(arg.before_modifier, {.const_is_none = true}); // TODO: check } - print(*statement.get_argument(i)->get_name().value(), printer); + Run(arg.name.value()); // all args are typed or are untyped in the same time - if (!statement.get_argument(i)->get_type().has_value()) { - print(statement.get_argument(i)->get_after_modifier(), printer); + if (not arg.type.has_value()) { + Run(arg.after_modifier); } } // all args are typed or are untyped in the same time - if (statement.args_size() > 0 && - statement.get_argument(0)->get_type().has_value()) { + if (not statement.args.empty() && statement.args.at(0).type.has_value()) { - printer.print(" :"); + Print(" :"); - for (size_t i = 0; i < statement.args_size(); ++i) { - printer.space(); - if (statement.get_argument(i)->get_annotation().has_value()) { - print_annotation(*statement.get_argument(i)->get_annotation().value(), - printer); - printer.space(); + for (const auto &arg : statement.args) { + Space(); + if (arg.annotation.has_value()) { + Run(nodes::Annotation{arg.annotation.value()}); + Space(); } - print(statement.get_argument(i)->get_before_modifier(), printer, true); + Run(arg.before_modifier, {.const_is_none = true}); // TODO: check - print(*statement.get_argument(i)->get_type().value(), printer); + Run(arg.type.value()); } } - if (statement.get_expression().has_value()) { + if (statement.expr.has_value()) { bool expression_is_container = - statement.get_expression().value()->get().has_value(); + Ext(statement.expr.value()).Holds(); - printer.print(expression_is_container ? " " : " = "); + Print(expression_is_container ? " " : " = "); - size_t previous_indentation_level = printer.get_indentation_level(); + size_t previous_indentation_level = indentation_level(); if (!expression_is_container) { - printer.set_indentation_level(printer.current_position()); + SetIndentationLevel(current_position()); } - print(*statement.get_expression().value(), printer); + Run(statement.expr.value()); if (!expression_is_container) { - printer.set_indentation_level(previous_indentation_level); - printer.print(";"); + SetIndentationLevel(previous_indentation_level); + Print(";"); } } else { - printer.print(";"); + Print(";"); } + + return {}; } // IN PROGRESS } // namespace printers diff --git a/lang/printers/src/type_printers.cpp b/lang/printers/src/type_printers.cpp index a558e7c..cf57e3e 100644 --- a/lang/printers/src/type_printers.cpp +++ b/lang/printers/src/type_printers.cpp @@ -5,29 +5,36 @@ namespace printers { +Result PrintTask::operator()(const nodes::Type &type, + const Args &args) { + return Run(*type.get(), args); +} // TODO: better printing format for builtin types -void print(const nodes::TypeData &type, printers::Printer &printer) { +Result PrintTask::operator()(const nodes::TypeData &type, + const Args &) { if (type.has_annotation()) { - print_annotation(*type.get_annotation().value(), printer); - printer.space(); + Run(nodes::Annotation{.value = *type.get_annotation().value()}); + Space(); } if (type.get_modifier() != nodes::Modifier::CONST) { - print(type.get_modifier(), printer); + Run(type.get_modifier()); } - print(*type.get_name(), printer); + Run(*type.get_name()); if (type.parameters_size() > 0) { - printer.print("["); + Print("["); for (size_t i = 0; i < type.parameters_size(); ++i) { - print(*type.get_parameter(i), printer); + Run(*type.get_parameter(i)); if (i + 1 < type.parameters_size()) { - printer.space(); + Space(); } } - printer.print("]"); + Print("]"); } + + return {}; } // void print_tuple_type(const nodes::TupleType &type, diff --git a/lang/type_check/include/type_check_utils.hpp b/lang/type_check/include/type_check_utils.hpp index 59a653f..306c146 100644 --- a/lang/type_check/include/type_check_utils.hpp +++ b/lang/type_check/include/type_check_utils.hpp @@ -4,6 +4,7 @@ #include "expression_nodes.hpp" #include "log.hpp" #include "name_tree.hpp" +#include "nodes_storage.hpp" #include "type_nodes.hpp" #include @@ -82,10 +83,10 @@ public: } private: - void enter_context(const nodes::Node &node) { + void enter_context(const utils::Pos &pos) { Log::Context logc(log_, Log::Area::kTypeCheck); - contexts_.emplace_back(node); + contexts_.emplace_back(pos); } // TODO: argument for property is returned type should be merged @@ -134,7 +135,7 @@ private: public: class Context { public: - Context(const nodes::Node &node) : node_(node) {} + Context(const utils::Pos &pos) : pos_(pos) {} // void log_typecheck_error( // const std::string &message = "Context typecheck error") { @@ -148,7 +149,7 @@ public: std::unordered_map variables; private: - const nodes::Node &node_; // TODO: use as position + const utils::Pos &pos_; // TODO: use as position }; private: @@ -159,7 +160,7 @@ private: // -using Exprs = nodes::ExprStorage; +using Exprs = nodes::NodeStorage; using Types = nodes::TypeStorage; using Names = names::NameTree; @@ -230,10 +231,10 @@ private: class ContextHolder { public: - ContextHolder(State &state, const nodes::Node &node, + ContextHolder(State &state, const utils::Pos &pos, nodes::MaybeType *context_exit_type) : state_(state), context_exit_type_(context_exit_type) { - state.enter_context(node); + state.enter_context(pos); } ContextHolder(const ContextHolder &) = delete; @@ -299,46 +300,46 @@ using MaybeResult = std::optional; // nodes::Type check_same_to_pass_type_in_args( - nodes::Type type, const Args &args, const nodes::Node &node, + nodes::Type type, const Args &args, const utils::Pos &pos, Executor &executor, const std::string &message = "Different type with passed one", bool handle_errors = true); // bool check_no_pass_type_in_args( -// const Args &args, const nodes::Node &node, +// const Args &args, const utils::Pos &pos, // SourcesManager &sources_manager, // const std::string &message = "Type can't be passed to this node"); Result type_same_to_expected( - nodes::Type type, const Args &argumensr, const nodes::Node &node, + nodes::Type type, const Args &args, const utils::Pos &pos, Executor &executor, const std::string &message = "Different type with expected one", bool handle_errors = true); Result type_check_from_args(nodes::Type type, const Args &args, - const nodes::Node &node, Executor &executor, + const utils::Pos &pos, Executor &executor, bool handle_errors = true); std::optional -find_type_definition(const std::string &name, const nodes::Node &node, +find_type_definition(const std::string &name, const utils::Pos &pos, Executor &executor, bool handle_errors = true); std::optional -find_name_definition(const std::string &name, const nodes::Node &node, +find_name_definition(const std::string &name, const utils::Pos &pos, Executor &executor, bool handle_errors = true); nodes::MaybeType unfold_user_defined_type(nodes::Type type, - const nodes::Node &node, + const utils::Pos &pos, Executor &executor, bool handle_errors = true); nodes::MaybeType get_field_type_by_name(nodes::Type type, const std::string &field, - const nodes::Node &node, + const utils::Pos &pos, Executor &executor, bool handle_errors = true); -void type_check_error(const std::string &message, const nodes::Node &node, +void type_check_error(const std::string &message, const utils::Pos &pos, Executor &executor, bool handle_error = true); // diff --git a/lang/type_check/src/basic_type_check.cpp b/lang/type_check/src/basic_type_check.cpp index 79c83af..fbf3892 100644 --- a/lang/type_check/src/basic_type_check.cpp +++ b/lang/type_check/src/basic_type_check.cpp @@ -4,7 +4,7 @@ namespace type_check { nodes::Type get_literal_type(const nodes::Literal &literal, Executor &executor) { - switch (literal.get_any().index()) { + switch (literal.value.index()) { case 0: // float return executor.state().primitive(builtin::Type::FLOAT); case 1: // double diff --git a/lang/type_check/src/type_check_utils.cpp b/lang/type_check/src/type_check_utils.cpp index c516272..852da79 100644 --- a/lang/type_check/src/type_check_utils.cpp +++ b/lang/type_check/src/type_check_utils.cpp @@ -7,7 +7,7 @@ namespace type_check { // pass type -> compare types, return bool // no pass type -> return type nodes::Type check_same_to_pass_type_in_args(nodes::Type type, const Args &args, - const nodes::Node & /*node*/, + const utils::Pos &, Executor &executor, const std::string &message, bool handle_errors) { @@ -24,13 +24,13 @@ nodes::Type check_same_to_pass_type_in_args(nodes::Type type, const Args &args, return executor.state().primitive(builtin::Type::BOOL); } -bool check_no_pass_type_in_args(const Args &args, const nodes::Node &node, +bool check_no_pass_type_in_args(const Args &args, const utils::Pos &pos, Executor &executor, const std::string &message, bool handle_errors) { Log::Context logc(executor.log(), Log::Area::kTypeCheck); if (args.get_passed().has_value()) { - type_check_error(message, node, executor, handle_errors); + type_check_error(message, pos, executor, handle_errors); return false; } @@ -38,7 +38,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 utils::Pos &, Executor &executor, const std::string &message, bool handle_errors) { Log::Context logc(executor.log(), Log::Area::kTypeCheck); @@ -61,7 +61,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, + const utils::Pos &, Executor &executor, bool /*handle_errors*/) { Log::Context logc(executor.log(), Log::Area::kTypeCheck); @@ -72,8 +72,8 @@ Result type_check_from_args(nodes::Type /*type*/, const Args & /*args*/, template std::optional -find_statement(const std::string &name, const nodes::Node & /*node*/, - Executor &executor, const std::string &message_not_found, +find_statement(const std::string &name, const utils::Pos &, Executor &executor, + const std::string &message_not_found, const std::string &message_different_statement, bool handle_errors) { Log::Context logc(executor.log(), Log::Area::kTypeCheck); @@ -98,43 +98,43 @@ find_statement(const std::string &name, const nodes::Node & /*node*/, } std::optional -find_type_definition(const std::string &name, const nodes::Node &node, +find_type_definition(const std::string &name, const utils::Pos &pos, Executor &executor, bool handle_errors) { Log::Context logc(executor.log(), Log::Area::kTypeCheck); return find_statement( - name, node, executor, "No type definition found in name tree", + name, pos, executor, "No type definition found in name tree", "Node in name tree is not type definition", handle_errors); } std::optional -find_name_definition(const std::string &name, const nodes::Node &node, +find_name_definition(const std::string &name, const utils::Pos &pos, Executor &executor, bool handle_errors) { Log::Context logc(executor.log(), Log::Area::kTypeCheck); return find_statement( - name, node, executor, "No name definition found in name tree", + name, pos, executor, "No name definition found in name tree", "Node in name tree is not name definition", handle_errors); } std::optional unfold_user_defined_type(nodes::Type type, - const nodes::Node &node, + const utils::Pos &pos, Executor &executor, bool handle_errors) { 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); + type.get()->get_name()->value, pos, executor, handle_errors); if (!maybe_type_definition.has_value()) { return std::nullopt; } - if (maybe_type_definition.value()->get_type().has_value()) { + if (maybe_type_definition.value()->type.has_value()) { if (handle_errors) { logc.Error({{std::format( "Only type declaration found for type {} (type is not defined)", - *type.get()->get_name()->get())}} /* TODO: node*/); + type.get()->get_name()->value)}} /* TODO: node*/); } return std::nullopt; } @@ -143,12 +143,12 @@ std::optional unfold_user_defined_type(nodes::Type type, logc.Require(type.get()->parameters_size() == 0, {{"Unfold of generic type is not supported (yet)"}}); // - return maybe_type_definition.value()->get_type().value(); + return maybe_type_definition.value()->type.value(); } std::optional get_field_type_by_name(nodes::Type type, const std::string &field, - const nodes::Node &node, + const utils::Pos &pos, Executor &executor, bool handle_errors) { Log::Context logc(executor.log(), Log::Area::kTypeCheck); @@ -170,12 +170,12 @@ std::optional get_field_type_by_name(nodes::Type type, // remove recursion ?? const auto maybe_internal_type = - unfold_user_defined_type(type, node, executor, handle_errors); + unfold_user_defined_type(type, pos, executor, handle_errors); if (!maybe_internal_type.has_value()) { return std::nullopt; } - return get_field_type_by_name(maybe_internal_type.value(), field, node, + return get_field_type_by_name(maybe_internal_type.value(), field, pos, executor, handle_errors); } default: // variant, function, optional, result, error (TODO: add message @@ -192,7 +192,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 &, +void type_check_error(const std::string &message, const utils::Pos &, Executor &executor, bool handle_error) { Log::Context logc(executor.log(), Log::Area::kTypeCheck); diff --git a/lang/type_check/xmake.lua b/lang/type_check/xmake.lua index 08e52b8..039f03e 100644 --- a/lang/type_check/xmake.lua +++ b/lang/type_check/xmake.lua @@ -3,10 +3,10 @@ includes("../nodes/xmake.lua") set_languages("c++20") -target("lang.type_check") - set_kind("static") - add_includedirs("include", {public = true}) - add_files("src/**.cpp") - add_deps("lang.utils", "lang.nodes") - set_warnings("allextra") -- , "error") - set_rundir("$(projectdir)") +-- target("lang.type_check") +-- set_kind("static") +-- add_includedirs("include", {public = true}) +-- add_files("src/**.cpp") +-- add_deps("lang.utils", "lang.nodes") +-- set_warnings("allextra") -- , "error") +-- set_rundir("$(projectdir)") diff --git a/lang/utils/include/error_handling.hpp b/lang/utils/include/error_handling.hpp index 690844f..1067bda 100644 --- a/lang/utils/include/error_handling.hpp +++ b/lang/utils/include/error_handling.hpp @@ -1,3 +1,5 @@ +// FIXME: DEPRECATED, TO DELETE + #pragma once #include "basic_nodes.hpp" @@ -8,69 +10,69 @@ namespace error_handling { -inline void handle_internal_error( - std::string_view message, const nodes::Node &node, - const std::source_location &location = std::source_location::current()) { - std::cerr << "\x1b[1;31mInternal Error:\x1b[0m " << message << " at "; - print_position(std::cerr, node.get_start_position(), node.get_end_position()); - std::cerr << ".\n"; - print_source_location(std::cerr, location); - exit(1); -} +// inline void handle_internal_error( +// std::string_view message, const nodes::Node &node, +// const std::source_location &location = std::source_location::current()) { +// std::cerr << "\x1b[1;31mInternal Error:\x1b[0m " << message << " at "; +// print_position(std::cerr, node.get_start_position(), +// node.get_end_position()); std::cerr << ".\n"; +// print_source_location(std::cerr, location); +// exit(1); +// } -inline void handle_internal_error( - std::string_view message, parser::ParseTree::Node node, - const std::source_location &location = std::source_location::current()) { - std::cerr << "\x1b[1;31mInternal Error:\x1b[0m " << message << " at "; - print_position(std::cerr, node.get_start_point(), node.get_end_point()); - std::cerr << ".\n"; - print_source_location(std::cerr, location); - exit(1); -} +// inline void handle_internal_error( +// std::string_view message, parser::ParseTree::Node node, +// const std::source_location &location = std::source_location::current()) { +// std::cerr << "\x1b[1;31mInternal Error:\x1b[0m " << message << " at "; +// print_position(std::cerr, node.get_start_point(), node.get_end_point()); +// std::cerr << ".\n"; +// print_source_location(std::cerr, location); +// exit(1); +// } -inline void handle_parsing_error( - std::string_view message, parser::ParseTree::Node parse_node, - const std::source_location &location = std::source_location::current()) { - std::cerr << "\x1b[1;31mParsing Error:\x1b[0m " << message << " at "; - print_position(std::cerr, parse_node.get_start_point(), - parse_node.get_end_point()); - std::cerr << ".\n"; - print_source_location(std::cerr, location); - exit(1); -} +// inline void handle_parsing_error( +// std::string_view message, parser::ParseTree::Node parse_node, +// const std::source_location &location = std::source_location::current()) { +// std::cerr << "\x1b[1;31mParsing Error:\x1b[0m " << message << " at "; +// print_position(std::cerr, parse_node.get_start_point(), +// parse_node.get_end_point()); +// std::cerr << ".\n"; +// print_source_location(std::cerr, location); +// exit(1); +// } -inline void handle_typecheck_error( - std::string_view message, nodes::Node node, - const std::source_location &location = std::source_location::current()) { - std::cerr << "\x1b[1;31mTypecheck Error:\x1b[0m " << message << " at "; - print_position(std::cerr, node.get_start_position(), node.get_end_position()); - std::cerr << ".\n"; - print_source_location(std::cerr, location); - exit(1); -} +// inline void handle_typecheck_error( +// std::string_view message, nodes::Node node, +// const std::source_location &location = std::source_location::current()) { +// std::cerr << "\x1b[1;31mTypecheck Error:\x1b[0m " << message << " at "; +// print_position(std::cerr, node.get_start_position(), +// node.get_end_position()); std::cerr << ".\n"; +// print_source_location(std::cerr, location); +// exit(1); +// } -inline void handle_runtime_error( - std::string_view message, nodes::Node node, - const std::source_location &location = std::source_location::current()) { - std::cerr << "\x1b[1;31mRuntime Error:\x1b[0m " << message << " at "; - print_position(std::cerr, node.get_start_position(), node.get_end_position()); - std::cerr << ".\n"; - print_source_location(std::cerr, location); - exit(1); -} +// inline void handle_runtime_error( +// std::string_view message, nodes::Node node, +// const std::source_location &location = std::source_location::current()) { +// std::cerr << "\x1b[1;31mRuntime Error:\x1b[0m " << message << " at "; +// print_position(std::cerr, node.get_start_position(), +// node.get_end_position()); std::cerr << ".\n"; +// print_source_location(std::cerr, location); +// exit(1); +// } -inline void handle_names_error( - std::string_view message, nodes::Node node, - const std::source_location &location = std::source_location::current()) { - std::cerr << "\x1b[1;31mNames Error:\x1b[0m " << message << " at "; - print_position(std::cerr, node.get_start_position(), node.get_end_position()); - std::cerr << ".\n"; - print_source_location(std::cerr, location); - exit(1); -} +// inline void handle_names_error( +// std::string_view message, nodes::Node node, +// const std::source_location &location = std::source_location::current()) { +// std::cerr << "\x1b[1;31mNames Error:\x1b[0m " << message << " at "; +// print_position(std::cerr, node.get_start_position(), +// node.get_end_position()); std::cerr << ".\n"; +// print_source_location(std::cerr, location); +// exit(1); +// } -template inline void debug_print(const T &value) { - std::cerr << "\x1b[1;33mDebug:\x1b[0m " << value << '\n'; -} +// template inline void debug_print(const T &value) { +// std::cerr << "\x1b[1;33mDebug:\x1b[0m " << value << '\n'; +// } } // namespace error_handling diff --git a/lang/utils/include/log.hpp b/lang/utils/include/log.hpp index e9a41e3..9773531 100644 --- a/lang/utils/include/log.hpp +++ b/lang/utils/include/log.hpp @@ -87,6 +87,7 @@ public: enum class Area { kDefault, + kBuild, kParse, kTypeCheck, kIntepret, diff --git a/lang/utils/include/storage.hpp b/lang/utils/include/storage.hpp index e98aaf5..0214b9e 100644 --- a/lang/utils/include/storage.hpp +++ b/lang/utils/include/storage.hpp @@ -48,8 +48,8 @@ template class DependentStorage : public Storage { using Id = storage::Id; public: - void ForceInsert(Id id, T &&elem) { - utils::Assert(Storage::data_.insert(id, elem).second, + void ForceInsert(Id id, T elem) { + utils::Assert(Storage::data_.insert({id, std::move(elem)}).second, std::format("insert failed, id={}", *id)); } diff --git a/tests/test.lang b/tests/test.lang index 2ddf1fe..d00a659 100644 --- a/tests/test.lang +++ b/tests/test.lang @@ -33,8 +33,7 @@ func { : example of function with optional arguments (without type annotation) : real type is 'A? 'A? -> 'A? sum 'a? 'b? = - 'a & 'b =: %a? & %b? => a + b - =: _ => null; + 'a & 'b =: %a => a; : example that shows that default annotations are argument names (without ')