From 582ad5668e952acf183833a7547855af9d3cb267 Mon Sep 17 00:00:00 2001 From: ProgramSnail Date: Wed, 29 Mar 2023 23:19:54 +0300 Subject: [PATCH] build_visitor first iteration --- include/build_visitor.hpp | 2 +- include/interpreter_tree.hpp | 10 +- include/parse_token_types.hpp | 2 + src/build_visitor.cpp | 419 +++++++++++++++++++++++++--------- src/print_visitor.cpp | 21 +- 5 files changed, 338 insertions(+), 116 deletions(-) diff --git a/include/build_visitor.hpp b/include/build_visitor.hpp index 84296b6..5472677 100644 --- a/include/build_visitor.hpp +++ b/include/build_visitor.hpp @@ -131,7 +131,7 @@ private: // Identifiers, constants, etc. ----------------- - // // void Visit(AnyIdentifier* node) override; // std::string + void Visit(AnyIdentifier* node) override; // std::string void Visit(FloatNumberLiteral* node) override; void Visit(NumberLiteral* node) override; diff --git a/include/interpreter_tree.hpp b/include/interpreter_tree.hpp index 8c5f439..75fe6e3 100644 --- a/include/interpreter_tree.hpp +++ b/include/interpreter_tree.hpp @@ -480,7 +480,7 @@ struct LambdaFunction : public Node { struct NameSuperExpression : public Node { std::vector namespaces; - std::vector expressions; // last is not SuperExpression + std::vector expressions; }; struct NameExpression : public Node { @@ -511,13 +511,13 @@ struct TypeConstructor : public Node { }; struct TupleType : public Node { - TypeIdentifierDefinition type; // optional - std::vector> entities; // NameIdentifier is optional + std::optional type; + std::vector, AnyType>> entities; }; struct VariantType : public Node { - TypeIdentifierDefinition type; // optional - std::vector>> constructors; + std::optional type; + std::vector>> constructors; }; struct AnnotatedType : public Node { diff --git a/include/parse_token_types.hpp b/include/parse_token_types.hpp index 561af4a..ab865d0 100644 --- a/include/parse_token_types.hpp +++ b/include/parse_token_types.hpp @@ -118,6 +118,8 @@ const std::string TypeclassExpression = "typeclass_expression"; // Identifiers, constants, etc. ----------------- +const std::string TypeIdentifierDefinition = "type_identifier_definition"; + const std::string TypeclassIdentifier = "typeclass_identifer"; const std::string NameIdentifier = "name_identifier"; const std::string TypeIdentifier = "type_identifer"; diff --git a/src/build_visitor.cpp b/src/build_visitor.cpp index 8d9731d..4c429a7 100644 --- a/src/build_visitor.cpp +++ b/src/build_visitor.cpp @@ -25,6 +25,7 @@ void BuildVisitor::Visit(SourceFile* node) { Visit(&std::get(node->statements[i])); } } + current_node_ = parse_node; } @@ -38,6 +39,7 @@ void BuildVisitor::Visit(Sources* node) { current_node_ = parse_node.NthNamedChild(i); Visit(node->statements[i]); } + current_node_ = parse_node; } @@ -46,8 +48,7 @@ void BuildVisitor::Visit(Sources* node) { void BuildVisitor::Visit(Partition* node) { auto parse_node = current_node_; - auto name_node = parse_node.ChildByFieldName("name"); - std::string name = name_node.GetValue(); + std::string name = parse_node.ChildByFieldName("name").GetValue(); if (name == "TEST") { node->type = Partition::Test; @@ -113,8 +114,8 @@ void BuildVisitor::Visit(ImportStatement* node) { if (child_count > 1) { node->symbols.resize(child_count - 1); - for (size_t i = 1; i < child_count; ++i) { - current_node_ = parse_node.NthNamedChild(i); + for (size_t i = 0; i < child_count - 1; ++i) { + current_node_ = parse_node.NthNamedChild(i + 1); Visit(node->symbols[i]); } } @@ -169,16 +170,15 @@ void BuildVisitor::Visit(VariableDefinition* node) { void BuildVisitor::Visit(FunctionDeclaration* node) { auto parse_node = current_node_; - auto name_node = parse_node.ChildByFieldName("name"); - std::string name = name_node.GetValue(); + node->name = parse_node.ChildByFieldName("name").GetValue(); size_t child_count = parse_node.NamedChildCount(); if (child_count > 1) { bool parameters_ended = false; - for (size_t i = 1; i < child_count; ++i) { - current_node_ = parse_node.NthNamedChild(i); + for (size_t i = 0; i < child_count - 1; ++i) { + current_node_ = parse_node.NthNamedChild(i + 1); if (current_node_.GetType() != parser::tokens::DefinitionParameter) { parameters_ended = true; @@ -256,8 +256,8 @@ void BuildVisitor::Visit(TypeclassDefinition* node) { if (child_count > 1) { node->requirements.resize(child_count - 1, std::make_unique()); - for (size_t i = 1; i < child_count; ++i) { - current_node_ = parse_node.NthNamedChild(i); + for (size_t i = 0; i < child_count - 1; ++i) { + current_node_ = parse_node.NthNamedChild(i + 1); Visit(node->requirements[i].get()); } } @@ -339,8 +339,7 @@ void BuildVisitor::Visit(ImportSymbol& node) { void BuildVisitor::Visit(DefinedName* node) { auto parse_node = current_node_; - auto name_node = parse_node.ChildByFieldName("name"); // Operator or NameIdentifier - std::string name = name_node.GetValue(); + node->name = parse_node.ChildByFieldName("name").GetValue(); node->is_operator = (parse_node.NthChild(0).GetValue() == "("); // TODO @@ -349,8 +348,8 @@ void BuildVisitor::Visit(DefinedName* node) { if (child_count > 1) { bool parameters_ended = false; - for (size_t i = 1; i < child_count; ++i) { - current_node_ = parse_node.NthNamedChild(i); + for (size_t i = 0; i < child_count - 1; ++i) { + current_node_ = parse_node.NthNamedChild(i + 1); if (current_node_.GetType() != parser::tokens::DefinitionParameter) { parameters_ended = true; @@ -372,8 +371,7 @@ void BuildVisitor::Visit(DefinedName* node) { void BuildVisitor::Visit(DefinedAnnotatedName* node) { auto parse_node = current_node_; - auto name_node = parse_node.ChildByFieldName("name"); - std::string name = name_node.GetValue(); + node->name = parse_node.ChildByFieldName("name").GetValue(); size_t child_count = parse_node.NamedChildCount(); @@ -405,8 +403,8 @@ void BuildVisitor::Visit(DefinedType* node) { if (child_count > 1) { bool parameters_ended = false; - for (size_t i = 1; i < child_count; ++i) { - current_node_ = parse_node.NthNamedChild(i); + for (size_t i = 0; i < child_count - 1; ++i) { + current_node_ = parse_node.NthNamedChild(i + 1); if (current_node_.GetType() != parser::tokens::DefinitionParameter) { parameters_ended = true; @@ -437,8 +435,8 @@ void BuildVisitor::Visit(DefinedTypeclass* node) { if (child_count > 1) { bool parameters_ended = false; - for (size_t i = 1; i < child_count; ++i) { - current_node_ = parse_node.NthNamedChild(i); + for (size_t i = 0; i < child_count - 1; ++i) { + current_node_ = parse_node.NthNamedChild(i + 1); if (current_node_.GetType() != parser::tokens::DefinitionParameter) { parameters_ended = true; @@ -460,16 +458,15 @@ void BuildVisitor::Visit(DefinedTypeclass* node) { void BuildVisitor::Visit(DefinitionParameter* node) { auto parse_node = current_node_; - auto name_node = parse_node.ChildByFieldName("type"); - std::string name = name_node.GetValue(); + node->type = parse_node.ChildByFieldName("type").GetValue(); size_t child_count = parse_node.NamedChildCount(); if (child_count > 1) { node->typeclasses.resize(child_count - 1, std::make_unique()); - for (size_t i = 1; i < child_count; ++i) { - current_node_ = parse_node.NthNamedChild(i); + for (size_t i = 0; i < child_count - 1; ++i) { + current_node_ = parse_node.NthNamedChild(i + 1); Visit(node->typeclasses[i].get()); // choose between typeclass_expression and parametrized_typeclass } @@ -481,16 +478,15 @@ void BuildVisitor::Visit(DefinitionParameter* node) { void BuildVisitor::Visit(DefinitionArgument* node) { auto parse_node = current_node_; - auto name_node = parse_node.ChildByFieldName("name"); - std::string name = name_node.GetValue(); + node->name = parse_node.ChildByFieldName("name").GetValue(); size_t child_count = parse_node.NamedChildCount(); if (child_count > 1) { node->types.resize(child_count - 1, std::make_unique()); - for (size_t i = 1; i < child_count; ++i) { - current_node_ = parse_node.NthNamedChild(i); + for (size_t i = 0; i < child_count - 1; ++i) { + current_node_ = parse_node.NthNamedChild(i + 1); Visit(node->types[i].get()); // choose between type_expression and parametrized_type } @@ -565,8 +561,8 @@ void BuildVisitor::Visit(Match* node) { // if (child_count > 1) { // always true (repeat1) node->matches.resize(child_count - 1); - for (size_t i = 1; i < child_count; ++i) { - current_node_ = parse_node.NthNamedChild(i); + for (size_t i = 0; i < child_count - 1; ++i) { + current_node_ = parse_node.NthNamedChild(i + 1); Visit(&node->matches[i]); } // } @@ -905,8 +901,8 @@ void BuildVisitor::Visit(FunctionCallExpression* node) { // if (child_count > 1) { // always true (repeat1) node->arguments.resize(child_count - 1); - for (size_t i = 1; i < child_count; ++i) { - current_node_ = parse_node.NthNamedChild(i); + for (size_t i = 0; i < child_count - 1; ++i) { + current_node_ = parse_node.NthNamedChild(i + 1); Visit(node->arguments[i]); } // } @@ -1010,8 +1006,45 @@ void BuildVisitor::Visit(LambdaFunction* node) { // Name -void BuildVisitor::Visit(NameSuperExpression* node) { // TODO - TODO; +void BuildVisitor::Visit(NameSuperExpression* node) { + auto parse_node = current_node_; + + size_t child_count = parse_node.NamedChildCount(); + + bool namespaces_ended = false; + + for (size_t i = 0; i < child_count; ++i) { + current_node_ = parse_node.NthNamedChild(i); + std::string current_node_type = current_node_.GetType(); + + if (current_node_type != parser::tokens::TypeSubExpression) { + namespaces_ended = true; + + if (i + 1 == child_count) { + node->expressions.emplace_back(); + + if (current_node_type == parser::tokens::NameIdentifier) { // optimize ?? + node->expressions.back() = std::make_unique(current_node_.GetValue()); + } else if (current_node_type == parser::tokens::Literal) { + node->expressions.back() = std::make_unique(); + Visit(*std::get>(node->expressions.back()).get()); + } else { + // error + } + break; + } + } + + if (!namespaces_ended) { + node->namespaces.emplace_back(); + Visit(node->namespaces.back()); + } else { + node->expressions.emplace_back(); + Visit(node->expressions.back()); + } + } + + current_node_ = parse_node; } void BuildVisitor::Visit(NameExpression* node) { @@ -1111,121 +1144,299 @@ void BuildVisitor::Visit(AnyName& node) { // Type void BuildVisitor::Visit(TypeConstructor* node) { - out_ << " "; + auto parse_node = current_node_; + + current_node_ = parse_node.ChildByFieldName("type"); + node->type = std::make_unique(); Visit(node->type.get()); - out_ << '\n'; - for (auto& parameter : node->parameters) { - Visit(¶meter.first); - out_ << " = "; - Visitor::Visit(parameter.second); - out_ << '\n'; + + size_t parameter_count = (parse_node.NamedChildCount() - 1) / 2; + + node->parameters.resize(parameter_count); + + for (size_t i = 0; i < parameter_count * 2; ++i) { + current_node_ = parse_node.NthNamedChild(i + 1); + + if (i % 2 == 0) { + node->parameters[i / 2].first = current_node_.GetValue(); + } else { + Visit(node->parameters[i / 2].second); + } } - out_ << "\n"; + + current_node_ = parse_node; } void BuildVisitor::Visit(TupleType* node) { - out_ << " "; - Visit(&node->type); // optional - out_ << ' '; - for (auto& entity : node->entities) { - out_ << "& "; - if (entity.first != "") { - Visit(&entity.first); - out_ << " : "; - } - Visitor::Visit(entity.second); + auto parse_node = current_node_; + + size_t current_node_n = 0; + + current_node_ = parse_node.NthNamedChild(current_node_n); + + if (current_node_.GetType() == parser::tokens::TypeIdentifierDefinition) { + node->type = current_node_.GetValue(); // TODO check + + ++current_node_n; + current_node_ = parse_node.NthNamedChild(current_node_n); } - out_ << ""; + + while (current_node_n < parse_node.NamedChildCount()) { + node->entities.emplace_back(); + + if (current_node_.GetType() == parser::tokens::NameIdentifier) { + node->entities.back().first = current_node_.GetValue(); + + ++current_node_n; + current_node_ = parse_node.NthNamedChild(current_node_n); + } + + Visit(node->entities.back().second); + + ++current_node_n; + current_node_ = parse_node.NthNamedChild(current_node_n); + } + + current_node_ = parse_node; } void BuildVisitor::Visit(VariantType* node) { - out_ << " "; - Visit(&node->type); // optional - out_ << ' '; - for (auto& constructor : node->constructors) { - out_ << "| "; - Visit(&constructor.first); - Visit(constructor.second.get()); + auto parse_node = current_node_; + + size_t current_node_n = 0; + + current_node_ = parse_node.NthNamedChild(current_node_n); + + if (current_node_.GetType() == parser::tokens::TypeIdentifierDefinition) { + node->type = current_node_.GetValue(); // TODO check + + ++current_node_n; + current_node_ = parse_node.NthNamedChild(current_node_n); } - out_ << ""; + + while (current_node_n < parse_node.NamedChildCount()) { + std::string current_node_type = current_node_.GetType(); + + node->constructors.emplace_back(); + + if (current_node_type == parser::tokens::TypeIdentifierDefinition) { // optimize ?? + node->constructors.back() = current_node_.GetValue(); // TODO check + } else if (current_node_type == parser::tokens::TupleType) { + node->constructors.back() = std::make_unique(); + Visit(std::get>(node->constructors.back()).get()); + } else { + // error + } + + ++current_node_n; + current_node_ = parse_node.NthNamedChild(current_node_n); + } + + current_node_ = parse_node; } void BuildVisitor::Visit(AnnotatedType* node) { - out_ << " "; + auto parse_node = current_node_; + + current_node_ = parse_node.ChildByFieldName("type_expression"); + node->type_expression = std::make_unique(); Visit(node->type_expression.get()); - if (node->annotations.size() > 0) { - out_ << " :"; + + size_t child_count = parse_node.NamedChildCount(); + + if (child_count > 1) { + node->annotations.resize(child_count - 1, std::make_unique()); + + for (size_t i = 0; i < child_count - 1; ++i) { + current_node_ = parse_node.NthNamedChild(i + 1); + Visit(node->annotations[i].get()); + } } - for (auto& annotation : node->annotations) { - out_ << " "; - Visit(annotation.get()); - } - out_ << ""; + + current_node_ = parse_node; } void BuildVisitor::Visit(ParametrizedType* node) { - out_ << " "; + auto parse_node = current_node_; + + current_node_ = parse_node.ChildByFieldName("type_expression"); + node->type_expression = std::make_unique(); Visit(node->type_expression.get()); - for (auto& paramater : node->parameters) { - out_ << ' '; - Visitor::Visit(paramater); + + size_t child_count = parse_node.NamedChildCount(); + + if (child_count > 1) { + node->parameters.resize(child_count - 1); + + for (size_t i = 0; i < child_count - 1; ++i) { + current_node_ = parse_node.NthNamedChild(i + 1); + Visit(node->parameters[i]); + } } - out_ << " "; + + current_node_ = parse_node; } void BuildVisitor::Visit(TypeExpression* node) { - out_ << " "; - for (auto& type_namespace : node->namespaces) { - Visitor::Visit(type_namespace); - out_ << '.'; + auto parse_node = current_node_; + + size_t child_count = parse_node.NamedChildCount(); + + if (child_count > 1) { + node->namespaces.resize(child_count - 1); + + for (size_t i = 0; i < child_count - 1; ++i) { + current_node_ = parse_node.NthNamedChild(i); + Visit(node->namespaces[i]); + } } - Visit(&node->type); - out_ << " "; + + node->type = parse_node.ChildByFieldName("type").GetValue(); + + current_node_ = parse_node; +} + +void BuildVisitor::Visit(AnyType& node) { + auto parse_node = current_node_; + + current_node_ = parse_node.NthNamedChild(0); + + std::string current_node_type = current_node_.GetType(); + + if (current_node_type == parser::tokens::ParametrizedType) { // optimize ?? + node = std::make_unique(); + Visit(std::get>(node).get()); + } else if (current_node_type == parser::tokens::TupleType) { + node = std::make_unique(); + Visit(std::get>(node).get()); + } else if (current_node_type == parser::tokens::VariantType) { + node = std::make_unique(); + Visit(std::get>(node).get()); + } else { + // error + } + + current_node_ = parse_node; +} + +void BuildVisitor::Visit(TypeSubExpression& node) { + auto parse_node = current_node_; + + current_node_ = parse_node.NthNamedChild(0); + + std::string current_node_type = current_node_.GetType(); + + if (current_node_type == parser::tokens::TypeIdentifier) { // optimize ?? + node = std::make_unique(); + Visit(std::get>(node).get()); + } else if (current_node_type == parser::tokens::AbstractTypeIdentifier) { + node = std::make_unique(); + Visit(std::get>(node).get()); + } else if (current_node_type == parser::tokens::ParametrizedType) { + node = std::make_unique(); + Visit(std::get>(node).get()); + } else { + // error + } + + current_node_ = parse_node; +} + +void BuildVisitor::Visit(TypeParameter& node) { + auto parse_node = current_node_; + + current_node_ = parse_node.NthNamedChild(0); + + std::string current_node_type = current_node_.GetType(); + + if (current_node_type == parser::tokens::ParametrizedType) { // optimize ?? + node = std::make_unique(); + Visit(std::get>(node).get()); + } else if (current_node_type == parser::tokens::Expression) { + node = std::make_unique(); + Visit(*std::get>(node).get()); + } else { + // error + } + + current_node_ = parse_node; } // Typeclass void BuildVisitor::Visit(AnnotatedTypeclass* node) { - out_ << " "; + auto parse_node = current_node_; + + current_node_ = parse_node.ChildByFieldName("typeclass_expression"); + node->typeclass_expression = std::make_unique(); Visit(node->typeclass_expression.get()); - if (node->annotations.size() > 0) { - out_ << " :"; + + size_t child_count = parse_node.NamedChildCount(); + + if (child_count > 1) { + node->annotations.resize(child_count - 1, std::make_unique()); + + for (size_t i = 0; i < child_count - 1; ++i) { + current_node_ = parse_node.NthNamedChild(i + 1); + Visit(node->annotations[i].get()); + } } - for (auto& annotation : node->annotations) { - out_ << " "; - Visit(annotation.get()); - } - out_ << ""; + + current_node_ = parse_node; } void BuildVisitor::Visit(ParametrizedTypeclass* node) { - out_ << " "; + auto parse_node = current_node_; + + current_node_ = parse_node.ChildByFieldName("typeclass_expression"); + node->typeclass_expression = std::make_unique(); Visit(node->typeclass_expression.get()); - for (auto& paramater : node->parameters) { - out_ << ' '; - Visitor::Visit(paramater); + + size_t child_count = parse_node.NamedChildCount(); + + if (child_count > 1) { + node->parameters.resize(child_count - 1); + + for (size_t i = 0; i < child_count - 1; ++i) { + current_node_ = parse_node.NthNamedChild(i + 1); + Visit(node->parameters[i]); + } } - out_ << " "; + + current_node_ = parse_node; } void BuildVisitor::Visit(TypeclassExpression* node) { - out_ << " "; - for (auto& typeclass_namespace : node->namespaces) { - Visitor::Visit(typeclass_namespace); - out_ << '.'; + auto parse_node = current_node_; + + size_t child_count = parse_node.NamedChildCount(); + + if (child_count > 1) { + node->namespaces.resize(child_count - 1); + + for (size_t i = 0; i < child_count - 1; ++i) { + current_node_ = parse_node.NthNamedChild(i); + Visit(node->namespaces[i]); + } } - Visit(&node->typeclass); - out_ << " "; + + node->typeclass = parse_node.ChildByFieldName("typeclass").GetValue(); + + current_node_ = parse_node; } // Identifiers, constants, etc. ----------------- +void BuildVisitor::Visit(AnyIdentifier* node) { // std::string + *node = current_node_.GetValue(); +} // TODO use in other places ?? + void BuildVisitor::Visit(FloatNumberLiteral* node) { - node->value = current_node_.NthChild(0).GetValue(); + node->value = std::stod(current_node_.NthChild(0).GetValue()); } void BuildVisitor::Visit(NumberLiteral* node) { - node->value = current_node_.NthChild(0).GetValue(); + node->value = std::stoll(current_node_.NthChild(0).GetValue()); } void BuildVisitor::Visit(StringLiteral* node) { @@ -1233,7 +1444,7 @@ void BuildVisitor::Visit(StringLiteral* node) { } void BuildVisitor::Visit(CharLiteral* node) { - node->value = current_node_.NthChild(1).GetValue(); + node->value = current_node_.NthChild(1).GetValue()[0]; } void BuildVisitor::Visit(Literal& node) { @@ -1274,10 +1485,10 @@ void BuildVisitor::Visit(NameSubSuperExpression& node) { Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::Literal) { node = std::make_unique(); - Visit(std::get>(node).get()); + Visit(*std::get>(node).get()); } else if (current_node_type == parser::tokens::SuperExpression) { node = std::make_unique(); - Visit(std::get>(node).get()); + Visit(*std::get>(node).get()); } else { // error } diff --git a/src/print_visitor.cpp b/src/print_visitor.cpp index 8d2f292..1904a49 100644 --- a/src/print_visitor.cpp +++ b/src/print_visitor.cpp @@ -516,12 +516,14 @@ void PrintVisitor::Visit(TypeConstructor* node) { void PrintVisitor::Visit(TupleType* node) { out_ << " "; - Visit(&node->type); // optional + if (node->type.has_value()) { + Visit(&node->type.value()); // optional + } out_ << ' '; for (auto& entity : node->entities) { out_ << "& "; - if (entity.first != "") { - Visit(&entity.first); + if (entity.first.has_value()) { + Visit(&entity.first.value()); out_ << " : "; } Visitor::Visit(entity.second); @@ -531,12 +533,19 @@ void PrintVisitor::Visit(TupleType* node) { void PrintVisitor::Visit(VariantType* node) { out_ << " "; - Visit(&node->type); // optional + if (node->type.has_value()) { + Visit(&node->type.value()); + } out_ << ' '; for (auto& constructor : node->constructors) { out_ << "| "; - Visit(&constructor.first); - Visit(constructor.second.get()); + if (std::holds_alternative(constructor)) { + Visit(&std::get(constructor)); + } else if (std::holds_alternative>(constructor)) { + Visit(std::get>(constructor).get()); + } else { + // error + } } out_ << ""; }