#include #include // for clangd #include "../include/build_visitor.hpp" #include "../include/parse_token_types.hpp" namespace interpreter { // Sources ----------------- void BuildVisitor::Visit(SourceFile* node) { auto parse_node = current_node_; size_t statement_count = parse_node.NamedChildCount(); node->statements.resize(statement_count); for (size_t i = 0; i < statement_count; ++i) { current_node_ = parse_node.NthNamedChild(i); Visit(node->statements[i]); } current_node_ = parse_node; } // Namespaces, partitions ----------------- void BuildVisitor::Visit(PartitionSources* node) { auto parse_node = current_node_; size_t statement_count = parse_node.NamedChildCount(); node->statements.resize(statement_count); for (size_t i = 0; i < statement_count; ++i) { current_node_ = parse_node.NthNamedChild(i); Visit(node->statements[i]); } current_node_ = parse_node; } void BuildVisitor::Visit(Partition* node) { auto parse_node = current_node_; std::string name = parse_node.ChildByFieldName("name").GetValue(); if (name == "TEST") { node->name = Partition::Test; } else if (name == "INTERFACE") { node->name = Partition::Interface; } else if (name == "CODE") { node->name = Partition::Code; } current_node_ = parse_node.ChildByFieldName("scope"); Visit(&node->scope); current_node_ = parse_node; } void BuildVisitor::Visit(NamespaceSources* node) { auto parse_node = current_node_; size_t statement_count = parse_node.NamedChildCount(); node->statements.resize(statement_count); for (size_t i = 0; i < statement_count; ++i) { current_node_ = parse_node.NthNamedChild(i); Visit(node->statements[i]); } current_node_ = parse_node; } void BuildVisitor::Visit(Namespace* node) { auto parse_node = current_node_; size_t child_count = parse_node.ChildCount(); if (child_count > 3) { // "namespace", ["var"/"const",] type, scope std::string modifier = parse_node.NthChild(1).GetValue(); if (modifier == "const") { node->modifier = Namespace::Const; } else if (modifier == "var") { node->modifier = Namespace::Var; } } current_node_ = parse_node.ChildByFieldName("type"); Visit(&node->type); current_node_ = parse_node.ChildByFieldName("scope"); Visit(&node->scope); current_node_ = parse_node; } // Definitions ----------------- void BuildVisitor::Visit(ImportStatement* node) { auto parse_node = current_node_; size_t excluded_child_count = 0; if (parse_node.NthChild(0).GetValue() == "use") { node->name = parse_node.ChildByFieldName("name").GetValue(); ++excluded_child_count; } StringLiteral module_name; current_node_ = parse_node.ChildByFieldName("module_name"); Visit(&module_name); node->module_name = module_name.value; ++excluded_child_count; size_t child_count = parse_node.NamedChildCount(); if (child_count > excluded_child_count) { node->symbols.resize(child_count - excluded_child_count); for (size_t i = 0; i < child_count - excluded_child_count; ++i) { current_node_ = parse_node.NthNamedChild(i + excluded_child_count); Visit(&node->symbols[i]); } } current_node_ = parse_node; } void BuildVisitor::Visit(AliasDefinitionStatement* node) { auto parse_node = current_node_; std::string modifier = parse_node.NthChild(0).GetValue(); if (modifier == "alias") { node->modifier = AliasDefinitionStatement::Alias; } else if (modifier == "type") { node->modifier = AliasDefinitionStatement::Type; } else if (modifier == "let") { node->modifier = AliasDefinitionStatement::Let; } node->type = parse_node.ChildByFieldName("type").GetValue(); size_t child_count = parse_node.NamedChildCount(); if (child_count > 2) { node->parameters.resize(child_count - 2); for (size_t i = 0; i + 2 < child_count; ++i) { node->parameters[i] = parse_node.NthNamedChild(i + 1).GetValue(); } } current_node_ = parse_node.ChildByFieldName("value"); node->value = std::make_unique(); Visit(node->value.get()); current_node_ = parse_node; } void BuildVisitor::Visit(VariableDefinitionStatement* node) { auto parse_node = current_node_; std::string modifier = parse_node.NthChild(0).GetValue(); if (modifier == "const") { node->modifier = VariableDefinitionStatement::Const; } else if (modifier == "var") { node->modifier = VariableDefinitionStatement::Var; } current_node_ = parse_node.ChildByFieldName("name"); Visit(node->name); current_node_ = parse_node.ChildByFieldName("value"); Visit(node->value); std::string assignment_modifier = parse_node.NthChild(2).GetValue(); if (assignment_modifier == "=") { node->assignment_modifier = VariableDefinitionStatement::Assign; } else if (assignment_modifier == "<-") { node->assignment_modifier = VariableDefinitionStatement::Move; } current_node_ = parse_node; } void BuildVisitor::Visit(FunctionDeclaration* node) { auto parse_node = current_node_; node->name.name = parse_node.ChildByFieldName("name").GetValue(); size_t child_count = parse_node.NamedChildCount(); if (child_count > 2) { node->parameters.resize(child_count - 2); for (size_t i = 0; i + 2 < child_count; ++i) { current_node_ = parse_node.NthNamedChild(i + 1); node->parameters[i] = std::make_unique(); Visit(node->parameters.back().get()); } } current_node_ = parse_node.ChildByFieldName("type"); node->type = std::make_unique(); Visit(node->type.get()); current_node_ = parse_node; } void BuildVisitor::Visit(FunctionDefinitionStatement* node) { auto parse_node = current_node_; node->is_inline = (parse_node.NthChild(1).GetValue() == "inline"); current_node_ = parse_node.ChildByFieldName("definition"); node->definition = std::make_unique(); Visit(node->definition.get()); current_node_ = parse_node.ChildByFieldName("value"); Visit(node->value); current_node_ = parse_node; } void BuildVisitor::Visit(TypeDefinitionStatement* node) { auto parse_node = current_node_; std::string modifier = parse_node.NthChild(0).GetValue(); if (modifier == "class") { node->modifier = TypeDefinitionStatement::Class; } else if (modifier == "struct") { node->modifier = TypeDefinitionStatement::Struct; } current_node_ = parse_node.ChildByFieldName("definition"); node->definition = std::make_unique(); Visit(node->definition.get()); current_node_ = parse_node.ChildByFieldName("value"); Visit(node->value); current_node_ = parse_node; } void BuildVisitor::Visit(AbstractTypeDefinitionStatement* node) { auto parse_node = current_node_; std::string modifier = parse_node.NthChild(0).GetValue(); if (modifier == "basic") { node->modifier = AbstractTypeDefinitionStatement::Basic; } else if (modifier == "abstract") { node->modifier = AbstractTypeDefinitionStatement::Abstract; } current_node_ = parse_node.ChildByFieldName("type"); node->type = std::make_unique(); Visit(node->type.get()); current_node_ = parse_node; } void BuildVisitor::Visit(TypeclassDefinitionStatement* node) { auto parse_node = current_node_; current_node_ = parse_node.ChildByFieldName("definition"); node->definition = std::make_unique(); Visit(node->definition.get()); size_t child_count = parse_node.NamedChildCount(); if (child_count > 1) { node->requirements.resize(child_count - 1); for (size_t i = 0; i + 1 < child_count; ++i) { current_node_ = parse_node.NthNamedChild(i + 1); node->requirements[i] = std::make_unique(); Visit(node->requirements[i].get()); } } current_node_ = parse_node; } // void BuildVisitor::Visit(NamespaceStatement& 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::AliasDefinitionStatement) { // optimize ?? node = std::make_unique(); Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::FunctionDeclaration) { node = std::make_unique(); Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::FunctionDefinitionStatement) { node = std::make_unique(); Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::TypeDefinitionStatement) { node = std::make_unique(); Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::Namespace) { node = std::make_unique(); Visit(std::get>(node).get()); } else { // error } current_node_ = parse_node; } void BuildVisitor::Visit(PartitionStatement& 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::AbstractTypeDefinitionStatement) { // optimize ?? node = std::make_unique(); Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::TypeclassDefinitionStatement) { node = std::make_unique(); Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::NamespaceStatement) { node = std::make_unique(); Visit(*std::get>(node)); } else { // error } current_node_ = parse_node; } void BuildVisitor::Visit(SourceStatement& 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::ImportStatement) { // optimize ?? node = std::make_unique(); Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::Partition) { node = std::make_unique(); Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::PartitionStatement) { node = std::make_unique(); Visit(*std::get>(node)); } else { // error } current_node_ = parse_node; } // Definition parts void BuildVisitor::Visit(FunctionDefinition* node) { auto parse_node = current_node_; node->name.name = parse_node.ChildByFieldName("name").GetValue(); if (parse_node.NthChild(0).GetValue() == "(") { node->modifier = FunctionDefinition::Operator; } else { node->modifier = FunctionDefinition::Function; } size_t child_count = parse_node.NamedChildCount(); if (child_count > 1) { node->arguments.resize(child_count - 1); for (size_t i = 0; i + 1 < child_count; ++i) { current_node_ = parse_node.NthNamedChild(i + 1); Visit(&node->arguments[i]); } } current_node_ = parse_node; } void BuildVisitor::Visit(TypeDefinition* node) { auto parse_node = current_node_; current_node_ = parse_node.ChildByFieldName("type"); node->type = std::make_unique(); Visit(node->type.get()); size_t child_count = parse_node.NamedChildCount(); if (child_count > 1) { for (size_t i = 0; i + 1 < child_count; ++i) { current_node_ = parse_node.NthNamedChild(i + 1); node->parameters.push_back(std::make_unique()); Visit(node->parameters.back().get()); } } current_node_ = parse_node; } void BuildVisitor::Visit(AnyAnnotatedType* node) { auto parse_node = current_node_; node->type = parse_node.ChildByFieldName("type").GetValue(); size_t child_count = parse_node.NamedChildCount(); if (child_count > 1) { node->typeclasses.resize(child_count - 1); for (size_t i = 0; i + 1 < child_count; ++i) { current_node_ = parse_node.NthNamedChild(i + 1); node->typeclasses[i] = std::make_unique(); Visit(node->typeclasses[i].get()); } } current_node_ = parse_node; } // Flow control ----------------- void BuildVisitor::Visit(TypeConstructorPatternParameter* node) { auto parse_node = current_node_; size_t child_count = parse_node.NamedChildCount(); if (child_count > 1) { current_node_ = parse_node.ChildByFieldName("name"), node->name.emplace(); Visit(&node->name.value()); } current_node_ = parse_node.ChildByFieldName("value"), Visit(node->value); current_node_ = parse_node; } void BuildVisitor::Visit(TypeConstructorPattern* node) { auto parse_node = current_node_; current_node_ = parse_node.ChildByFieldName("constructor"); Visit(node->constructor.get()); size_t child_count = parse_node.NamedChildCount(); if (child_count > 1) { node->parameters.resize(child_count - 1); for (size_t i = 0; i + 1 < child_count; ++i) { current_node_ = parse_node.NthNamedChild(i + 1); Visit(&node->parameters[i]); } } current_node_ = parse_node; } void BuildVisitor::Visit(PatternToken& 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::ExtendedName) { // optimize ?? node = std::make_unique(); Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::Literal) { node = std::make_unique(); Visit(*std::get>(node)); } else if (current_node_type == parser::tokens::TypeConstructorPattern) { node = std::make_unique(); Visit(std::get>(node).get()); } else { // error } current_node_ = parse_node; } void BuildVisitor::Visit(Pattern& 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::TypeConstructorPattern) { // optimize ?? node = std::make_unique(); Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::PatternToken) { node = std::make_unique(); Visit(*std::get>(node)); } else { // error } current_node_ = parse_node; } void BuildVisitor::Visit(MatchCase* node) { auto parse_node = current_node_; current_node_ = parse_node.ChildByFieldName("value"); Visit(node->value); size_t child_count = parse_node.NamedChildCount(); if (child_count > 1) { std::string prefix = parse_node.NthChild(2).GetValue(); if (child_count > 2 || prefix == "?") { current_node_ = parse_node.ChildByFieldName("condition"); node->condition.emplace(); Visit(node->condition.value()); } if (child_count > 2 || prefix == "->") { current_node_ = parse_node.ChildByFieldName("statement"); node->statement.emplace(); Visit(node->statement.value()); } } current_node_ = parse_node; } void BuildVisitor::Visit(Match* node) { auto parse_node = current_node_; current_node_ = parse_node.ChildByFieldName("value"); Visit(node->value); size_t child_count = parse_node.NamedChildCount(); // if (child_count > 1) { // always true (repeat1) node->matches.resize(child_count - 1); for (size_t i = 0; i + 1 < child_count; ++i) { current_node_ = parse_node.NthNamedChild(i + 1); Visit(&node->matches[i]); } // } current_node_ = parse_node; } void BuildVisitor::Visit(Condition* node) { auto parse_node = current_node_; size_t child_count = parse_node.NamedChildCount(); node->conditions.resize(child_count / 2); node->statements.resize((child_count + 1) / 2); for (size_t i = 0; i < child_count; ++i) { current_node_ = parse_node.NthNamedChild(i); if (i % 2 == 0 && i / 2 < node->conditions.size()) { Visit(node->conditions[i / 2]); } else { Visit(node->statements[i / 2]); } } current_node_ = parse_node; } void BuildVisitor::Visit(DoWhileLoop* node) { auto parse_node = current_node_; current_node_ = parse_node.ChildByFieldName("statement"); Visit(node->statement); current_node_ = parse_node.ChildByFieldName("condition"); Visit(node->condition); current_node_ = parse_node; } void BuildVisitor::Visit(WhileLoop* node) { auto parse_node = current_node_; current_node_ = parse_node.ChildByFieldName("condition"); Visit(node->condition); current_node_ = parse_node.ChildByFieldName("statement"); Visit(node->statement); current_node_ = parse_node; } void BuildVisitor::Visit(ForLoop* node) { auto parse_node = current_node_; current_node_ = parse_node.ChildByFieldName("variable"); Visit(node->variable); current_node_ = parse_node.ChildByFieldName("interval"); Visit(node->interval); current_node_ = parse_node.ChildByFieldName("statement"); Visit(node->statement); current_node_ = parse_node; } void BuildVisitor::Visit(LoopLoop* node) { auto parse_node = current_node_; current_node_ = parse_node.ChildByFieldName("statement"); Visit(node->statement); current_node_ = parse_node; } void BuildVisitor::Visit(FlowControl& 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::Match) { // optimize ?? node = std::make_unique(); Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::Condition) { node = std::make_unique(); Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::DoWhileLoop) { node = std::make_unique(); Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::WhileLoop) { node = std::make_unique(); Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::ForLoop) { node = std::make_unique(); Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::LoopLoop) { node = std::make_unique(); Visit(std::get>(node).get()); } else { // error } current_node_ = parse_node; } // Statements, expressions, blocks, etc. ----------------- void BuildVisitor::Visit(BlockStatement& 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::Expression) { // optimize ?? node = std::make_unique(); Visit(*std::get>(node)); } else if (current_node_type == parser::tokens::VariableDefinitionStatement) { node = std::make_unique(); Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::FlowControl) { node = std::make_unique(); Visit(*std::get>(node)); } else if (current_node_type == parser::tokens::PrefixedExpression) { node = std::make_unique(); Visit(*std::get>(node)); } else { // error } current_node_ = parse_node; } void BuildVisitor::Visit(Block* node) { auto parse_node = current_node_; size_t statement_count = parse_node.NamedChildCount(); node->statements.resize(statement_count); for (size_t i = 0; i < statement_count; ++i) { current_node_ = parse_node.NthNamedChild(i); Visit(node->statements[i]); } current_node_ = parse_node; } void BuildVisitor::Visit(SubExpressionToken& 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::NameExpression) { node = std::make_unique(); Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::ScopedStatement) { node = std::make_unique(); Visit(std::get>(node).get()); } if (current_node_type == parser::tokens::AccessExpression) { node = std::make_unique(); Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::Literal) { node = std::make_unique(); Visit(*std::get>(node)); } else { // error } current_node_ = parse_node; } void BuildVisitor::Visit(SubExpression& 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::FunctionCallExpression) { // optimize ?? node = std::make_unique(); Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::BinaryOperatorExpression) { node = std::make_unique(); Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::SubExpressionToken) { node = std::make_unique(); Visit(*std::get>(node)); } else if (current_node_type == parser::tokens::ReferenceExpression) { node = std::make_unique(); Visit(std::get>(node).get()); } else { // error } current_node_ = parse_node; } void BuildVisitor::Visit(PrefixedExpression& 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::ReturnExpression) { // optimize ?? node = std::make_unique(); Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::LoopControlExpression) { node = std::make_unique(); Visit(*std::get>(node)); } else if (current_node_type == parser::tokens::Block) { node = std::make_unique(); Visit(std::get>(node).get()); } else { // error } current_node_ = parse_node; } void BuildVisitor::Visit(Expression& 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::LambdaFunction) { // optimize ?? node = std::make_unique(); Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::TypeConstructor) { node = std::make_unique(); Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::PrefixedExpression) { node = std::make_unique(); Visit(*std::get>(node)); } else if (current_node_type == parser::tokens::UnaryOperatorExpression) { node = std::make_unique(); Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::SubExpression) { node = std::make_unique(); Visit(*std::get>(node)); } else { // error } current_node_ = parse_node; } void BuildVisitor::Visit(SuperExpression& 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::FlowControl) { // optimize ?? node = std::make_unique(); Visit(*std::get>(node)); } else if (current_node_type == parser::tokens::TupleExpression) { node = std::make_unique(); Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::VariantExpression) { node = std::make_unique(); Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::ArrayExpression) { 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)); } else { // error } current_node_ = parse_node; } void BuildVisitor::Visit(ScopedStatement* node) { auto parse_node = current_node_; current_node_ = parse_node.ChildByFieldName("statement"); Visit(node->statement); current_node_ = parse_node; } // Operators void BuildVisitor::Visit(BinaryOperatorExpression* node) { auto parse_node = current_node_; current_node_ = parse_node.ChildByFieldName("left_expression"); Visit(node->left_expression); node->operator_name = parse_node.ChildByFieldName("operator_name").GetValue(); current_node_ = parse_node.ChildByFieldName("right_expression"); Visit(node->right_expression); current_node_ = parse_node; } void BuildVisitor::Visit(UnaryOperatorExpression* node) { auto parse_node = current_node_; node->operator_name = parse_node.ChildByFieldName("operator_name").GetValue(); current_node_ = parse_node.ChildByFieldName("expression"); Visit(node->expression); current_node_ = parse_node; } void BuildVisitor::Visit(ReferenceExpression* node) { auto parse_node = current_node_; size_t child_count = parse_node.ChildCount(); if (child_count > 1) { node->references.resize(child_count - 1); for (size_t i = 0; i + 1 < child_count; ++i) { std::string reference = parse_node.NthChild(i).GetValue(); if (reference == "~") { node->references[i] = utils::ReferenceType::Reference; } else if (reference == "@") { node->references[i] = utils::ReferenceType::UniqueReference; } } } current_node_ = parse_node.ChildByFieldName("expression"); node->expression = std::make_unique(); Visit(node->expression.get()); current_node_ = parse_node; } void BuildVisitor::Visit(AccessExpression* node) { auto parse_node = current_node_; current_node_ = parse_node.ChildByFieldName("name"); node->name = std::make_unique(); Visit(node->name.get()); current_node_ = parse_node.ChildByFieldName("id"); Visit(node->id); current_node_ = parse_node; } // Other expressions void BuildVisitor::Visit(FunctionCallExpression* node) { auto parse_node = current_node_; size_t excluded_child_count = 0; current_node_ = parse_node.NthNamedChild(0); std::string current_node_type = current_node_.GetType(); if (current_node_type == parser::tokens::SubExpressionToken) { node->prefix = std::make_unique(); Visit(*std::get>(node->prefix.value())); ++excluded_child_count; } else if (current_node_type == parser::tokens::TypeExpression) { node->prefix = std::make_unique(); Visit(std::get>(node->prefix.value()).get()); ++excluded_child_count; } else { // no prefix } current_node_ = parse_node.ChildByFieldName("name"); Visit(&node->name); ++excluded_child_count; size_t child_count = parse_node.NamedChildCount(); if (child_count > excluded_child_count) { // always true (repeat1) bool parameters_ended = false; node->arguments.resize(child_count - excluded_child_count); for (size_t i = 0; i + excluded_child_count < child_count; ++i) { current_node_ = parse_node.NthNamedChild(i + excluded_child_count); if (current_node_.GetType() != parser::tokens::TypeExpression) { parameters_ended = true; } if (!parameters_ended) { node->parameters.push_back(std::make_unique()); Visit(node->parameters.back().get()); } else { node->arguments.emplace_back(); Visit(node->arguments.back()); } } } current_node_ = parse_node; } void BuildVisitor::Visit(TupleExpression* node) { auto parse_node = current_node_; size_t expressions_count = parse_node.NamedChildCount(); node->expressions.resize(expressions_count); for (size_t i = 0; i < expressions_count; ++i) { current_node_ = parse_node.NthNamedChild(i); Visit(node->expressions[i]); } current_node_ = parse_node; } void BuildVisitor::Visit(VariantExpression* node) { auto parse_node = current_node_; size_t expressions_count = parse_node.NamedChildCount(); node->expressions.resize(expressions_count); for (size_t i = 0; i < expressions_count; ++i) { current_node_ = parse_node.NthNamedChild(i); Visit(node->expressions[i]); } current_node_ = parse_node; } void BuildVisitor::Visit(ReturnExpression* node) { auto parse_node = current_node_; current_node_ = parse_node.ChildByFieldName("expression"); Visit(node->expression); current_node_ = parse_node; } void BuildVisitor::Visit(TypeConstructorParameter* node) { auto parse_node = current_node_; size_t child_count = parse_node.NamedChildCount(); if (child_count > 1) { current_node_ = parse_node.ChildByFieldName("name"); node->name.emplace(); Visit(&node->name.value()); std::string assignment_modifier = current_node_.NextSibling().GetValue(); if (assignment_modifier == "=") { node->asignment_modifier = TypeConstructorParameter::Assign; } else if (assignment_modifier == "<-") { node->asignment_modifier = TypeConstructorParameter::Move; } } current_node_ = parse_node.ChildByFieldName("value"); Visit(node->value); current_node_ = parse_node; } void BuildVisitor::Visit(TypeConstructor* node) { auto parse_node = current_node_; current_node_ = parse_node.ChildByFieldName("constructor"); node->constructor = std::make_unique(); Visit(node->constructor.get()); size_t child_count = parse_node.NamedChildCount(); if (child_count > 1) { node->parameters.resize(child_count - 1); for (size_t i = 0; i + 1 < child_count; ++i) { current_node_ = parse_node.NthNamedChild(i + 1); Visit(&node->parameters[i]); } } current_node_ = parse_node; } void BuildVisitor::Visit(LambdaFunction* node) { auto parse_node = current_node_; size_t child_count = parse_node.NamedChildCount(); if (child_count > 1) { bool parameters_ended = false; for (size_t i = 0; i + 1 < child_count; ++i) { current_node_ = parse_node.NthNamedChild(i); if (current_node_.GetType() != parser::tokens::AnnotatedAbstractType) { parameters_ended = true; } if (!parameters_ended) { node->parameters.push_back(std::make_unique()); Visit(node->parameters.back().get()); } else { node->arguments.emplace_back(); Visit(&node->arguments.back()); } } } current_node_ = parse_node.ChildByFieldName("expression"); Visit(node->expression); current_node_ = parse_node; } void BuildVisitor::Visit(ArrayExpression* node) { auto parse_node = current_node_; size_t elements_count = parse_node.NamedChildCount(); node->elements.resize(elements_count); for (size_t i = 0; i < elements_count; ++i) { current_node_ = parse_node.NthNamedChild(i); Visit(node->elements[i]); } current_node_ = parse_node; } void BuildVisitor::Visit(LoopControlExpression& node) { std::string value = current_node_.NthChild(0).GetValue(); if (value == "break") { node = LoopControlExpression::Break; } else if (value == "continue") { node = LoopControlExpression::Continue; } else { // error } } // Name void BuildVisitor::Visit(NameExpression* node) { auto parse_node = current_node_; size_t child_count = parse_node.NamedChildCount(); node->names.resize(child_count); for (size_t i = 0; i < child_count; ++i) { current_node_ = parse_node.NthNamedChild(i); Visit(&node->names[i]); } current_node_ = parse_node; } void BuildVisitor::Visit(TupleName* node) { auto parse_node = current_node_; size_t names_count = parse_node.NamedChildCount(); node->names.resize(names_count); for (size_t i = 0; i < names_count; ++i) { current_node_ = parse_node.NthNamedChild(i); node->names[i] = std::make_unique(); Visit(node->names[i]); } current_node_ = parse_node; } void BuildVisitor::Visit(VariantName* node) { auto parse_node = current_node_; size_t names_count = parse_node.NamedChildCount(); node->names.resize(names_count); for (size_t i = 0; i < names_count; ++i) { current_node_ = parse_node.NthNamedChild(i); node->names[i] =std::make_unique(); Visit(node->names[i]); } current_node_ = parse_node; } void BuildVisitor::Visit(AnnotatedName* node) { auto parse_node = current_node_; node->name = parse_node.ChildByFieldName("name").GetValue(); if (parse_node.NamedChildCount() > 1) { current_node_ = parse_node.ChildByFieldName("type"); node->type.emplace(); Visit(node->type.value()); current_node_ = parse_node; } } void BuildVisitor::Visit(AnyName& 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::AnnotatedName) { node = std::make_unique(); Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::TupleName) { node = std::make_unique(); Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::VariantName) { node = std::make_unique(); Visit(std::get>(node).get()); } else { // error } current_node_ = parse_node; } // Type, typeclass, etc. ----------------- // Type void BuildVisitor::Visit(FunctionType* node) { auto parse_node = current_node_; size_t types_count = parse_node.NamedChildCount(); node->types.resize(types_count); for (size_t i = 0; i < types_count; ++i) { current_node_ = parse_node.NthNamedChild(i); Visit(node->types[i]); } current_node_ = parse_node; } void BuildVisitor::Visit(TupleType* node) { 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::Constructor) { node->type = current_node_.GetValue(); ++current_node_n; current_node_ = parse_node.NthNamedChild(current_node_n); } while (current_node_n < parse_node.NamedChildCount()) { node->entities.emplace_back(); if (current_node_.GetType() == parser::tokens::ExtendedName) { node->entities.back().first.emplace(); Visit(&node->entities.back().first.value()); ++current_node_n; current_node_ = parse_node.NthNamedChild(current_node_n); } node->entities.back().second = std::make_unique(); Visit(node->entities.back().second.get()); ++current_node_n; current_node_ = parse_node.NthNamedChild(current_node_n); } current_node_ = parse_node; } void BuildVisitor::Visit(VariantType* node) { 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::Constructor) { node->type = current_node_.GetValue(); ++current_node_n; current_node_ = parse_node.NthNamedChild(current_node_n); } 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::Constructor) { node->constructors.back() = current_node_.GetValue(); } 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(TypeExpression* node) { auto parse_node = current_node_; size_t excluded_child_count = 0; size_t child_count = parse_node.NamedChildCount(); current_node_ = parse_node.ChildByFieldName("type"); Visit(&node->type); ++excluded_child_count; current_node_ = current_node_.NextSibling(); if (!current_node_.IsNull()) { current_node_ = current_node_.NextSibling(); if (!current_node_.IsNull()) { NumberLiteral literal; Visit(&literal); node->array_size = literal.value; ++excluded_child_count; } else { node->array_size = 0; } } if (child_count > excluded_child_count) { node->path.resize(child_count - excluded_child_count); for (size_t i = 0; i + excluded_child_count < child_count; ++i) { current_node_ = parse_node.NthNamedChild(i); Visit(&node->path[i]); } } 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::TypeExpression) { 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 if (current_node_type == parser::tokens::FunctionType) { node = std::make_unique(); Visit(std::get>(node).get()); } else { // error } current_node_ = parse_node; } void BuildVisitor::Visit(ExtendedScopedAnyType* node) { auto parse_node = current_node_; size_t child_count = parse_node.ChildCount(); if (child_count > 1) { node->references.resize(child_count - 1); for (size_t i = 0; i + 1 < child_count; ++i) { std::string reference = parse_node.NthChild(i).GetValue(); if (reference == "~") { node->references[i] = utils::ReferenceType::Reference; } else if (reference == "@") { node->references[i] = utils::ReferenceType::UniqueReference; } } } current_node_ = parse_node.ChildByFieldName("type"); Visit(node->type); current_node_ = parse_node; } // Typeclass void BuildVisitor::Visit(ParametrizedTypeclass* node) { auto parse_node = current_node_; node->typeclass = parse_node.ChildByFieldName("typeclass").GetValue(); size_t child_count = parse_node.NamedChildCount(); if (child_count > 1) { node->parameters.resize(child_count - 1); for (size_t i = 0; i + 1 < child_count; ++i) { current_node_ = parse_node.NthNamedChild(i + 1); node->parameters[i] = std::make_unique(); Visit(node->parameters[i].get()); } } current_node_ = parse_node; } // Typeclass & Type ----------------- void BuildVisitor::Visit(ParametrizedType* node) { auto parse_node = current_node_; node->type = parse_node.ChildByFieldName("type").GetValue(); size_t child_count = parse_node.NamedChildCount(); if (child_count > 1) { node->parameters.resize(child_count - 1); for (size_t i = 0; i + 1 < child_count; ++i) { current_node_ = parse_node.NthNamedChild(i + 1); node->parameters[i] = std::make_unique(); Visit(node->parameters[i].get()); } } current_node_ = parse_node; } // Identifiers, constants, etc. ----------------- void BuildVisitor::Visit(ExtendedName* node) { size_t child_count = current_node_.NamedChildCount(); if (child_count > 1) { node->name = current_node_.GetValue(); } else { node->name = current_node_.NthNamedChild(0).GetValue(); } } void BuildVisitor::Visit(AnyIdentifier* node) { // std::string *node = current_node_.GetValue(); } void BuildVisitor::Visit(FloatNumberLiteral* node) { node->value = std::stod(current_node_.GetValue()); } void BuildVisitor::Visit(NumberLiteral* node) { node->value = std::stoll(current_node_.GetValue()); } void BuildVisitor::Visit(StringLiteral* node) { std::string literal = current_node_.GetValue(); node->value = literal.substr(1, literal.size() - 2); } void BuildVisitor::Visit(CharLiteral* node) { std::string literal = current_node_.GetValue(); node->value = literal.substr(1, literal.size() - 2).back(); // TODO: special symbols, etc. } void BuildVisitor::Visit(UnitLiteral* node) {} void BuildVisitor::Visit(Literal& 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::FloatNumberLiteral) { node = std::make_unique(); Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::NumberLiteral) { node = std::make_unique(); Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::StringLiteral) { node = std::make_unique(); Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::CharLiteral) { node = std::make_unique(); Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::UnitLiteral) { node = std::make_unique(); Visit(std::get>(node).get()); } else { // error } current_node_ = parse_node; } } // namespace interpreter