#include #include // for clangd #include "../include/build_visitor.hpp" #include "../include/parse_token_types.hpp" #include "../include/error_handling.hpp" namespace interpreter { void SetPosition(BaseNode& base_node, parser::ParseTree::Node& parse_node) { base_node.start_position = parse_node.GetStartPoint(); base_node.end_position = parse_node.GetEndPoint(); } // Sources ----------------- void BuildVisitor::Visit(SourceFile* node) { SetPosition(node->base, current_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(NamespaceSources* node) { SetPosition(node->base, current_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) { SetPosition(node->base, current_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 = utils::ClassInternalsModifier::Const; } else if (modifier == "var") { node->modifier = utils::ClassInternalsModifier::Var; } else { error_handling::HandleInternalError("Can't parse namespace modifier", "BuildVisitor.Namespace", &node->base); } } else { node->modifier = utils::ClassInternalsModifier::Static; } node->type = parse_node.ChildByFieldName("type").GetValue(); current_node_ = parse_node.ChildByFieldName("scope"); Visit(&node->scope); current_node_ = parse_node; } // Definitions ----------------- void BuildVisitor::Visit(ImportStatement* node) { SetPosition(node->base, current_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) { node->symbols[i] = parse_node.NthNamedChild(i + excluded_child_count).GetValue(); } } current_node_ = parse_node; } void BuildVisitor::Visit(AliasDefinitionStatement* node) { SetPosition(node->base, current_node_); auto parse_node = current_node_; std::string modifier = parse_node.NthChild(0).GetValue(); if (modifier == "alias") { node->modifier = utils::AliasModifier::Alias; } else if (modifier == "type") { node->modifier = utils::AliasModifier::Type; } else if (modifier == "let") { node->modifier = utils::AliasModifier::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) { SetPosition(node->base, current_node_); auto parse_node = current_node_; std::string modifier = parse_node.NthChild(0).GetValue(); if (modifier == "const") { node->modifier = utils::IsConstModifier::Const; } else if (modifier == "var") { node->modifier = utils::IsConstModifier::Var; } else { // error } 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 = utils::AssignmentModifier::Assign; } else if (assignment_modifier == "<-") { node->assignment_modifier = utils::AssignmentModifier::Move; } else { // error } current_node_ = parse_node; } void BuildVisitor::Visit(FunctionDeclaration* node) { SetPosition(node->base, current_node_); auto parse_node = current_node_; // ['decl'] ['interface'] name if (parse_node.NthChild(0).GetValue() == "decl") { node->is_in_interface = (parse_node.NthChild(1).GetValue() == "interface"); } else { node->is_in_interface = false; } node->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) { SetPosition(node->base, current_node_); auto parse_node = current_node_; 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) { SetPosition(node->base, current_node_); auto parse_node = current_node_; std::string modifier = parse_node.NthChild(0).GetValue(); if (modifier == "class") { node->modifier = utils::ClassModifier::Class; } else if (modifier == "struct") { node->modifier = utils::ClassModifier::Struct; } node->is_in_interface = (parse_node.NthChild(1).GetValue() == "interface"); 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) { SetPosition(node->base, current_node_); auto parse_node = current_node_; std::string modifier = parse_node.NthChild(0).GetValue(); if (modifier == "basic") { node->modifier = utils::AbstractTypeModifier::Basic; } else if (modifier == "abstract") { node->modifier = utils::AbstractTypeModifier::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) { SetPosition(node->base, current_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.reserve(child_count - 1); for (size_t i = 0; i + 1 < child_count; ++i) { current_node_ = parse_node.NthNamedChild(i + 1); std::string modifier_name = current_node_.PreviousSibling().GetValue(); utils::ClassInternalsModifier modifier; if (modifier_name == "const") { modifier = utils::ClassInternalsModifier::Const; } else if (modifier_name == "var") { modifier = utils::ClassInternalsModifier::Var; } else { modifier = utils::ClassInternalsModifier::Static; } node->requirements.push_back({modifier, std::make_unique()}); Visit(node->requirements.back().second.get()); } } current_node_ = parse_node; } void BuildVisitor::Visit(PartitionStatement* node) { SetPosition(node->base, current_node_); auto parse_node = current_node_; std::string partition_modifier = parse_node.NthChild(0).GetValue(); if (partition_modifier == "exec") { node->modifier = utils::PartitionModifier::Exec; } else if (partition_modifier == "test") { node->modifier = utils::PartitionModifier::Test; } else { // error } current_node_ = parse_node.ChildByFieldName("name"); Visit(&node->name); current_node_ = parse_node.ChildByFieldName("value"); Visit(node->value); 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::PartitionStatement) { 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(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::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; } // Definition parts void BuildVisitor::Visit(FunctionDefinition* node) { SetPosition(node->base, current_node_); auto parse_node = current_node_; node->name = parse_node.ChildByFieldName("name").GetValue(); 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) { node->arguments[i] = parse_node.NthNamedChild(i + 1).GetValue(); } } current_node_ = parse_node; } void BuildVisitor::Visit(TypeDefinition* node) { SetPosition(node->base, current_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) { SetPosition(node->base, current_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) { SetPosition(node->base, current_node_); auto parse_node = current_node_; size_t child_count = parse_node.NamedChildCount(); if (child_count > 1) { node->name.value() = parse_node.ChildByFieldName("name").GetValue(); } current_node_ = parse_node.ChildByFieldName("value"), Visit(node->value); current_node_ = parse_node; } void BuildVisitor::Visit(TypeConstructorPattern* node) { SetPosition(node->base, current_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(Pattern& node) { // <-> ScopedPattern 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::NameIdentifier) { // optimize ?? node = std::make_unique(current_node_.GetValue()); // 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(MatchCase* node) { SetPosition(node->base, current_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) { SetPosition(node->base, current_node_); auto parse_node = current_node_; node->is_consuming_value = (parse_node.NthChild(1).GetValue() == "<-"); 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) { SetPosition(node->base, current_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) { SetPosition(node->base, current_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) { SetPosition(node->base, current_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) { SetPosition(node->base, current_node_); auto parse_node = current_node_; if (parse_node.ChildCount() < 7) { // no "var" node node->variable_modifier = utils::IsConstModifier::Const; } else { node->variable_modifier = utils::IsConstModifier::Var; } 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) { SetPosition(node->base, current_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) { SetPosition(node->base, current_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(); VisitBinaryOperatorExpression(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::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) { SetPosition(node->base, current_node_); auto parse_node = current_node_; current_node_ = parse_node.ChildByFieldName("statement"); Visit(node->statement); current_node_ = parse_node; } // Operators void BuildVisitor::VisitBinaryOperatorExpression(FunctionCallExpression* node) { SetPosition(node->base, current_node_); auto parse_node = current_node_; node->is_binary_operator_expression = true; node->arguments.resize(2); current_node_ = parse_node.ChildByFieldName("left_expression"); Visit(node->arguments[0]); node->name = parse_node.ChildByFieldName("operator_name").GetValue(); { // remove operator precedence markers size_t operator_size = 0; for (; operator_size < node->name.size() && node->name[operator_size] != '.'; ++operator_size) {} node->precedence = utils::MaxOperatorPrecedence - (node->name.size() - operator_size); node->name = node->name.substr(0, operator_size); } current_node_ = parse_node.ChildByFieldName("right_expression"); Visit(node->arguments[1]); // ?? for (size_t i = 0; i < node->arguments.size(); ++i) { if (std::holds_alternative>(node->arguments[i])) { FunctionCallExpression* argument_node = std::get>(node->arguments[i]).get(); if (argument_node->is_binary_operator_expression && argument_node->precedence.has_value() && argument_node->precedence.value() >= node->precedence.value()) { error_handling::HandleParsingError("Operators can't be chained (left argument)", node->base.start_position, node->base.end_position); } } } current_node_ = parse_node; } void BuildVisitor::Visit(ReferenceExpression* node) { SetPosition(node->base, current_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::ReferenceModifier::Reference; } else if (reference == "~") { node->references[i] = utils::ReferenceModifier::Dereference; } else if (reference == "@") { node->references[i] = utils::ReferenceModifier::UniqueReference; // TODO: rename to move ?? } } } current_node_ = parse_node.ChildByFieldName("expression"); node->expression = std::make_unique(); Visit(node->expression.get()); current_node_ = parse_node; } void BuildVisitor::Visit(AccessExpression* node) { SetPosition(node->base, current_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) { SetPosition(node->base, current_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 } node->name = parse_node.ChildByFieldName("name").GetValue(); ++excluded_child_count; size_t child_count = parse_node.NamedChildCount(); if (child_count > excluded_child_count) { bool parameters_ended = false; 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.push_back(std::make_unique()); Visit(*std::get>(node->arguments.back())); } } } current_node_ = parse_node; } void BuildVisitor::Visit(TupleExpression* node) { SetPosition(node->base, current_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) { SetPosition(node->base, current_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) { SetPosition(node->base, current_node_); auto parse_node = current_node_; node->is_from_definition = (parse_node.NthChild(0).GetValue() == "return"); // "return" to return from definition and "bring" to return from block current_node_ = parse_node.ChildByFieldName("expression"); Visit(node->expression); current_node_ = parse_node; } void BuildVisitor::Visit(TypeConstructorParameter* node) { SetPosition(node->base, current_node_); auto parse_node = current_node_; size_t child_count = parse_node.NamedChildCount(); if (child_count > 1) { node->name = parse_node.ChildByFieldName("name").GetValue(); std::string assignment_modifier = current_node_.NextSibling().GetValue(); if (assignment_modifier == "=") { node->asignment_modifier = utils::AssignmentModifier::Assign; } else if (assignment_modifier == "<-") { node->asignment_modifier = utils::AssignmentModifier::Move; } } current_node_ = parse_node.ChildByFieldName("value"); Visit(node->value); current_node_ = parse_node; } void BuildVisitor::Visit(TypeConstructor* node) { SetPosition(node->base, current_node_); auto parse_node = current_node_; node->is_allocated_on_heap = (parse_node.NthChild(1).GetValue() == "@"); 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) { SetPosition(node->base, current_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(); node->arguments.back() = current_node_.GetValue(); } } } current_node_ = parse_node.ChildByFieldName("expression"); Visit(node->expression); current_node_ = parse_node; } void BuildVisitor::Visit(ArrayExpression* node) { SetPosition(node->base, current_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(PartitionName* node) { SetPosition(node->base, current_node_); auto parse_node = current_node_; size_t child_count = parse_node.NamedChildCount(); if (child_count > 1) { node->path.resize(child_count - 1); for (size_t i = 0; i + 1 < child_count; ++i) { node->path[i] = parse_node.NthNamedChild(i).GetValue(); } } node->path.push_back(parse_node.ChildByFieldName("name").GetValue()); current_node_ = parse_node; } void BuildVisitor::Visit(NameExpression* node) { SetPosition(node->base, current_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) { node->names[i] = parse_node.NthNamedChild(i).GetValue(); } current_node_ = parse_node; } void BuildVisitor::Visit(TupleName* node) { SetPosition(node->base, current_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) { SetPosition(node->base, current_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) { SetPosition(node->base, current_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) { SetPosition(node->base, current_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) { SetPosition(node->base, current_node_); auto parse_node = current_node_; size_t current_child = 0; current_node_ = parse_node.NthNamedChild(current_child); if (parse_node.NthChild(0).GetValue() != "&") { node->type = current_node_.GetValue(); ++current_child; current_node_ = parse_node.NthNamedChild(current_child); } while (current_child < parse_node.NamedChildCount()) { node->entities.emplace_back(); if (current_node_.GetType() == parser::tokens::NameIdentifier) { node->entities.back().first = current_node_.GetValue(); ++current_child; current_node_ = parse_node.NthNamedChild(current_child); } node->entities.back().second = std::make_unique(); Visit(node->entities.back().second.get()); ++current_child; current_node_ = parse_node.NthNamedChild(current_child); } current_node_ = parse_node; } void BuildVisitor::Visit(VariantType* node) { SetPosition(node->base, current_node_); auto parse_node = current_node_; size_t excluded_child_count = 0; size_t child_count = parse_node.NamedChildCount(); if (parse_node.NthChild(0).GetValue() != "|") { node->type = parse_node.NthNamedChild(0).GetValue(); ++excluded_child_count; } node->constructors.resize(child_count - excluded_child_count); for (size_t i = 0; i < node->constructors.size(); ++i) { current_node_ = parse_node.NthNamedChild(i + excluded_child_count); std::string current_node_type = current_node_.GetType(); if (current_node_type == parser::tokens::Constructor) { node->constructors[i] = current_node_.GetValue(); } else if (current_node_type == parser::tokens::TupleType) { node->constructors[i] = std::make_unique(); Visit(std::get>(node->constructors[i]).get()); } else { // error } } current_node_ = parse_node; } void BuildVisitor::Visit(TypeExpression* node) { SetPosition(node->base, current_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) { SetPosition(node->base, current_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::ReferenceModifier::Reference; } else if (reference == "@") { node->references[i] = utils::ReferenceModifier::UniqueReference; } } } current_node_ = parse_node.ChildByFieldName("type"); Visit(node->type); current_node_ = parse_node; } // Typeclass void BuildVisitor::Visit(ParametrizedTypeclass* node) { SetPosition(node->base, current_node_); auto parse_node = current_node_; std::string prefixed_typeclass = parse_node.ChildByFieldName("typeclass").GetValue(); // prefix # removed node->typeclass = prefixed_typeclass.substr(1, prefixed_typeclass.size() - 1); 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) { SetPosition(node->base, current_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(AnyIdentifier* node) { // std::string // *node = current_node_.GetValue(); // } void BuildVisitor::Visit(FloatNumberLiteral* node) { SetPosition(node->base, current_node_); node->value = std::stod(current_node_.GetValue()); } void BuildVisitor::Visit(NumberLiteral* node) { SetPosition(node->base, current_node_); node->value = std::stoll(current_node_.GetValue()); } void BuildVisitor::Visit(StringLiteral* node) { SetPosition(node->base, current_node_); std::string literal = current_node_.GetValue(); node->value = literal.substr(1, literal.size() - 2); } void BuildVisitor::Visit(CharLiteral* node) { SetPosition(node->base, current_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) { SetPosition(node->base, current_node_); } void BuildVisitor::Visit(BoolLiteral* node) { SetPosition(node->base, current_node_); std::string literal = current_node_.GetValue(); node->value = (literal == "true"); // always "false" in other way } 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 if (current_node_type == parser::tokens::BoolLiteral) { node = std::make_unique(); Visit(std::get>(node).get()); } else { // error } current_node_ = parse_node; } } // namespace interpreter