2023-03-31 12:10:12 +03:00
|
|
|
#include <memory>
|
2023-05-13 13:11:12 +03:00
|
|
|
#include <variant>
|
2023-03-31 12:10:12 +03:00
|
|
|
|
2023-04-02 15:10:32 +03:00
|
|
|
// for clangd
|
2023-03-28 12:05:20 +03:00
|
|
|
#include "../include/build_visitor.hpp"
|
|
|
|
|
#include "../include/parse_token_types.hpp"
|
2023-05-13 13:11:12 +03:00
|
|
|
#include "../include/error_handling.hpp"
|
2023-03-28 12:05:20 +03:00
|
|
|
|
|
|
|
|
namespace interpreter {
|
|
|
|
|
|
2023-05-05 11:59:02 +03:00
|
|
|
void SetPosition(BaseNode& base_node, parser::ParseTree::Node& parse_node) {
|
|
|
|
|
base_node.start_position = parse_node.GetStartPoint();
|
|
|
|
|
base_node.end_position = parse_node.GetEndPoint();
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-28 12:05:20 +03:00
|
|
|
// Sources -----------------
|
|
|
|
|
void BuildVisitor::Visit(SourceFile* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-28 12:05:20 +03:00
|
|
|
auto parse_node = current_node_;
|
2023-03-29 11:42:00 +03:00
|
|
|
size_t statement_count = parse_node.NamedChildCount();
|
2023-03-28 12:05:20 +03:00
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
node->statements.resize(statement_count);
|
2023-03-28 12:05:20 +03:00
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
for (size_t i = 0; i < statement_count; ++i) {
|
2023-04-29 13:44:34 +03:00
|
|
|
current_node_ = parse_node.NthNamedChild(i);
|
|
|
|
|
Visit(node->statements[i]);
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
2023-03-29 23:19:54 +03:00
|
|
|
|
2023-03-28 12:05:20 +03:00
|
|
|
current_node_ = parse_node;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-29 13:44:34 +03:00
|
|
|
// Namespaces, partitions -----------------
|
|
|
|
|
|
|
|
|
|
void BuildVisitor::Visit(NamespaceSources* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-04-29 13:44:34 +03:00
|
|
|
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;
|
|
|
|
|
}
|
2023-03-28 12:05:20 +03:00
|
|
|
|
2023-04-09 18:49:52 +03:00
|
|
|
void BuildVisitor::Visit(Namespace* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-28 12:05:20 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
2023-04-29 12:33:05 +03:00
|
|
|
size_t child_count = parse_node.ChildCount();
|
2023-04-09 18:49:52 +03:00
|
|
|
|
2023-04-29 12:33:05 +03:00
|
|
|
if (child_count > 3) { // "namespace", ["var"/"const",] type, scope
|
2023-04-09 18:49:52 +03:00
|
|
|
std::string modifier = parse_node.NthChild(1).GetValue();
|
|
|
|
|
if (modifier == "const") {
|
2023-05-14 11:28:37 +03:00
|
|
|
node->modifier = utils::ClassInternalsModifier::Const;
|
2023-04-09 18:49:52 +03:00
|
|
|
} else if (modifier == "var") {
|
2023-05-14 11:28:37 +03:00
|
|
|
node->modifier = utils::ClassInternalsModifier::Var;
|
2023-05-13 22:40:33 +03:00
|
|
|
} else {
|
2023-05-20 00:01:54 +03:00
|
|
|
error_handling::HandleInternalError("Can't parse namespace modifier",
|
|
|
|
|
"BuildVisitor.Namespace",
|
|
|
|
|
&node->base);
|
2023-04-09 18:49:52 +03:00
|
|
|
}
|
2023-05-14 11:28:37 +03:00
|
|
|
} else {
|
|
|
|
|
node->modifier = utils::ClassInternalsModifier::Static;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
2023-05-05 11:59:02 +03:00
|
|
|
node->type = parse_node.ChildByFieldName("type").GetValue();
|
2023-04-09 18:49:52 +03:00
|
|
|
|
2023-03-28 12:05:20 +03:00
|
|
|
current_node_ = parse_node.ChildByFieldName("scope");
|
2023-04-29 13:44:34 +03:00
|
|
|
Visit(&node->scope);
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Definitions -----------------
|
|
|
|
|
|
|
|
|
|
void BuildVisitor::Visit(ImportStatement* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
2023-04-09 18:49:52 +03:00
|
|
|
size_t excluded_child_count = 0;
|
|
|
|
|
|
|
|
|
|
if (parse_node.NthChild(0).GetValue() == "use") {
|
|
|
|
|
node->name = parse_node.ChildByFieldName("name").GetValue();
|
|
|
|
|
++excluded_child_count;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-11 13:49:22 +03:00
|
|
|
StringLiteral module_name;
|
|
|
|
|
current_node_ = parse_node.ChildByFieldName("module_name");
|
|
|
|
|
Visit(&module_name);
|
|
|
|
|
node->module_name = module_name.value;
|
2023-04-09 18:49:52 +03:00
|
|
|
++excluded_child_count;
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
size_t child_count = parse_node.NamedChildCount();
|
|
|
|
|
|
2023-04-09 18:49:52 +03:00
|
|
|
if (child_count > excluded_child_count) {
|
|
|
|
|
node->symbols.resize(child_count - excluded_child_count);
|
2023-03-29 11:42:00 +03:00
|
|
|
|
2023-04-09 18:49:52 +03:00
|
|
|
for (size_t i = 0; i < child_count - excluded_child_count; ++i) {
|
2023-05-05 11:59:02 +03:00
|
|
|
node->symbols[i] = parse_node.NthNamedChild(i + excluded_child_count).GetValue();
|
2023-03-29 11:42:00 +03:00
|
|
|
}
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
2023-04-09 18:49:52 +03:00
|
|
|
void BuildVisitor::Visit(AliasDefinitionStatement* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
2023-04-09 18:49:52 +03:00
|
|
|
std::string modifier = parse_node.NthChild(0).GetValue();
|
|
|
|
|
if (modifier == "alias") {
|
2023-05-05 16:35:13 +03:00
|
|
|
node->modifier = utils::AliasModifier::Alias;
|
2023-04-09 18:49:52 +03:00
|
|
|
} else if (modifier == "type") {
|
2023-05-05 16:35:13 +03:00
|
|
|
node->modifier = utils::AliasModifier::Type;
|
2023-04-09 18:49:52 +03:00
|
|
|
} else if (modifier == "let") {
|
2023-05-05 16:35:13 +03:00
|
|
|
node->modifier = utils::AliasModifier::Let;
|
2023-04-09 18:49:52 +03:00
|
|
|
}
|
2023-03-29 11:42:00 +03:00
|
|
|
|
2023-04-09 18:49:52 +03:00
|
|
|
node->type = parse_node.ChildByFieldName("type").GetValue();
|
2023-03-29 11:42:00 +03:00
|
|
|
|
2023-04-09 18:49:52 +03:00
|
|
|
size_t child_count = parse_node.NamedChildCount();
|
2023-03-28 12:05:20 +03:00
|
|
|
|
2023-04-09 18:49:52 +03:00
|
|
|
if (child_count > 2) {
|
|
|
|
|
node->parameters.resize(child_count - 2);
|
2023-03-29 11:42:00 +03:00
|
|
|
|
2023-04-09 18:49:52 +03:00
|
|
|
for (size_t i = 0; i + 2 < child_count; ++i) {
|
|
|
|
|
node->parameters[i] = parse_node.NthNamedChild(i + 1).GetValue();
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
current_node_ = parse_node.ChildByFieldName("value");
|
2023-04-25 21:21:36 +03:00
|
|
|
node->value = std::make_unique<TypeExpression>();
|
2023-03-28 12:05:20 +03:00
|
|
|
Visit(node->value.get());
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
2023-04-09 18:49:52 +03:00
|
|
|
void BuildVisitor::Visit(VariableDefinitionStatement* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
2023-04-09 18:49:52 +03:00
|
|
|
std::string modifier = parse_node.NthChild(0).GetValue();
|
|
|
|
|
if (modifier == "const") {
|
2023-05-05 16:35:13 +03:00
|
|
|
node->modifier = utils::IsConstModifier::Const;
|
2023-04-09 18:49:52 +03:00
|
|
|
} else if (modifier == "var") {
|
2023-05-05 16:35:13 +03:00
|
|
|
node->modifier = utils::IsConstModifier::Var;
|
2023-05-13 22:40:33 +03:00
|
|
|
} else {
|
|
|
|
|
// error
|
2023-03-29 11:42:00 +03:00
|
|
|
}
|
|
|
|
|
|
2023-04-09 18:49:52 +03:00
|
|
|
current_node_ = parse_node.ChildByFieldName("name");
|
|
|
|
|
Visit(node->name);
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
current_node_ = parse_node.ChildByFieldName("value");
|
|
|
|
|
Visit(node->value);
|
|
|
|
|
|
2023-04-11 13:49:22 +03:00
|
|
|
std::string assignment_modifier = parse_node.NthChild(2).GetValue();
|
|
|
|
|
if (assignment_modifier == "=") {
|
2023-05-05 16:35:13 +03:00
|
|
|
node->assignment_modifier = utils::AssignmentModifier::Assign;
|
2023-04-11 13:49:22 +03:00
|
|
|
} else if (assignment_modifier == "<-") {
|
2023-05-05 16:35:13 +03:00
|
|
|
node->assignment_modifier = utils::AssignmentModifier::Move;
|
2023-05-13 22:40:33 +03:00
|
|
|
} else {
|
|
|
|
|
// error
|
2023-04-11 13:49:22 +03:00
|
|
|
}
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
current_node_ = parse_node;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BuildVisitor::Visit(FunctionDeclaration* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
2023-05-07 22:58:15 +03:00
|
|
|
// ['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;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-13 13:11:12 +03:00
|
|
|
node->name = parse_node.ChildByFieldName("name").GetValue();
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
size_t child_count = parse_node.NamedChildCount();
|
|
|
|
|
|
2023-04-26 01:02:53 +03:00
|
|
|
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<AnnotatedAbstractType>();
|
|
|
|
|
Visit(node->parameters.back().get());
|
|
|
|
|
}
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
2023-03-29 11:42:00 +03:00
|
|
|
|
2023-04-09 18:49:52 +03:00
|
|
|
current_node_ = parse_node.ChildByFieldName("type");
|
2023-04-11 13:49:22 +03:00
|
|
|
node->type = std::make_unique<FunctionType>();
|
2023-04-09 18:49:52 +03:00
|
|
|
Visit(node->type.get());
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
current_node_ = parse_node;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
2023-04-09 18:49:52 +03:00
|
|
|
void BuildVisitor::Visit(FunctionDefinitionStatement* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
2023-04-09 18:49:52 +03:00
|
|
|
current_node_ = parse_node.ChildByFieldName("definition");
|
|
|
|
|
node->definition = std::make_unique<FunctionDefinition>();
|
|
|
|
|
Visit(node->definition.get());
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
current_node_ = parse_node.ChildByFieldName("value");
|
|
|
|
|
Visit(node->value);
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
2023-04-09 18:49:52 +03:00
|
|
|
void BuildVisitor::Visit(TypeDefinitionStatement* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
2023-04-09 18:49:52 +03:00
|
|
|
std::string modifier = parse_node.NthChild(0).GetValue();
|
|
|
|
|
if (modifier == "class") {
|
2023-05-05 16:35:13 +03:00
|
|
|
node->modifier = utils::ClassModifier::Class;
|
2023-04-09 18:49:52 +03:00
|
|
|
} else if (modifier == "struct") {
|
2023-05-05 16:35:13 +03:00
|
|
|
node->modifier = utils::ClassModifier::Struct;
|
2023-04-09 18:49:52 +03:00
|
|
|
}
|
|
|
|
|
|
2023-05-07 22:58:15 +03:00
|
|
|
node->is_in_interface = (parse_node.NthChild(1).GetValue() == "interface");
|
|
|
|
|
|
2023-04-09 18:49:52 +03:00
|
|
|
current_node_ = parse_node.ChildByFieldName("definition");
|
|
|
|
|
node->definition = std::make_unique<TypeDefinition>();
|
|
|
|
|
Visit(node->definition.get());
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
current_node_ = parse_node.ChildByFieldName("value");
|
2023-04-09 18:49:52 +03:00
|
|
|
Visit(node->value);
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
2023-04-09 18:49:52 +03:00
|
|
|
void BuildVisitor::Visit(AbstractTypeDefinitionStatement* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
2023-04-09 18:49:52 +03:00
|
|
|
std::string modifier = parse_node.NthChild(0).GetValue();
|
|
|
|
|
if (modifier == "basic") {
|
2023-05-05 16:35:13 +03:00
|
|
|
node->modifier = utils::AbstractTypeModifier::Basic;
|
2023-04-09 18:49:52 +03:00
|
|
|
} else if (modifier == "abstract") {
|
2023-05-05 16:35:13 +03:00
|
|
|
node->modifier = utils::AbstractTypeModifier::Abstract;
|
2023-03-29 11:42:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node.ChildByFieldName("type");
|
2023-04-09 18:49:52 +03:00
|
|
|
node->type = std::make_unique<AnnotatedType>();
|
2023-03-29 11:42:00 +03:00
|
|
|
Visit(node->type.get());
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
2023-04-09 18:49:52 +03:00
|
|
|
void BuildVisitor::Visit(TypeclassDefinitionStatement* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
2023-04-09 18:49:52 +03:00
|
|
|
current_node_ = parse_node.ChildByFieldName("definition");
|
|
|
|
|
node->definition = std::make_unique<TypeDefinition>();
|
|
|
|
|
Visit(node->definition.get());
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
size_t child_count = parse_node.NamedChildCount();
|
|
|
|
|
|
2023-05-14 11:28:37 +03:00
|
|
|
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<FunctionDeclaration>()});
|
|
|
|
|
Visit(node->requirements.back().second.get());
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-07 22:58:15 +03:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
//
|
|
|
|
|
|
2023-04-29 13:44:34 +03:00
|
|
|
void BuildVisitor::Visit(NamespaceStatement& node) {
|
2023-03-29 11:42:00 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node.NthNamedChild(0);
|
|
|
|
|
|
|
|
|
|
std::string current_node_type = current_node_.GetType();
|
|
|
|
|
|
2023-04-29 13:44:34 +03:00
|
|
|
if (current_node_type == parser::tokens::AliasDefinitionStatement) { // optimize ??
|
2023-04-09 18:49:52 +03:00
|
|
|
node = std::make_unique<AliasDefinitionStatement>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<AliasDefinitionStatement>>(node).get());
|
2023-03-29 11:42:00 +03:00
|
|
|
} else if (current_node_type == parser::tokens::FunctionDeclaration) {
|
|
|
|
|
node = std::make_unique<FunctionDeclaration>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<FunctionDeclaration>>(node).get());
|
2023-04-09 18:49:52 +03:00
|
|
|
} else if (current_node_type == parser::tokens::FunctionDefinitionStatement) {
|
|
|
|
|
node = std::make_unique<FunctionDefinitionStatement>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<FunctionDefinitionStatement>>(node).get());
|
|
|
|
|
} else if (current_node_type == parser::tokens::TypeDefinitionStatement) {
|
|
|
|
|
node = std::make_unique<TypeDefinitionStatement>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<TypeDefinitionStatement>>(node).get());
|
2023-05-07 22:58:15 +03:00
|
|
|
} else if (current_node_type == parser::tokens::PartitionStatement) {
|
|
|
|
|
node = std::make_unique<PartitionStatement>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<PartitionStatement>>(node).get());
|
2023-04-29 13:44:34 +03:00
|
|
|
} else if (current_node_type == parser::tokens::Namespace) {
|
|
|
|
|
node = std::make_unique<Namespace>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<Namespace>>(node).get());
|
|
|
|
|
} else {
|
|
|
|
|
// error
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-07 22:58:15 +03:00
|
|
|
void BuildVisitor::Visit(SourceStatement& node) {
|
2023-04-29 13:44:34 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node.NthNamedChild(0);
|
|
|
|
|
|
|
|
|
|
std::string current_node_type = current_node_.GetType();
|
|
|
|
|
|
2023-05-07 22:58:15 +03:00
|
|
|
if (current_node_type == parser::tokens::ImportStatement) { // optimize ??
|
|
|
|
|
node = std::make_unique<ImportStatement>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<ImportStatement>>(node).get());
|
|
|
|
|
} else if (current_node_type == parser::tokens::AbstractTypeDefinitionStatement) { // optimize ??
|
2023-04-09 18:49:52 +03:00
|
|
|
node = std::make_unique<AbstractTypeDefinitionStatement>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<AbstractTypeDefinitionStatement>>(node).get());
|
|
|
|
|
} else if (current_node_type == parser::tokens::TypeclassDefinitionStatement) {
|
|
|
|
|
node = std::make_unique<TypeclassDefinitionStatement>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<TypeclassDefinitionStatement>>(node).get());
|
2023-04-29 13:44:34 +03:00
|
|
|
} else if (current_node_type == parser::tokens::NamespaceStatement) {
|
|
|
|
|
node = std::make_unique<NamespaceStatement>();
|
|
|
|
|
Visit(*std::get<std::unique_ptr<NamespaceStatement>>(node));
|
|
|
|
|
} else {
|
|
|
|
|
// error
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-28 12:05:20 +03:00
|
|
|
// Definition parts
|
|
|
|
|
|
2023-04-09 18:49:52 +03:00
|
|
|
void BuildVisitor::Visit(FunctionDefinition* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
2023-05-13 13:11:12 +03:00
|
|
|
node->name = parse_node.ChildByFieldName("name").GetValue();
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
size_t child_count = parse_node.NamedChildCount();
|
|
|
|
|
|
|
|
|
|
if (child_count > 1) {
|
2023-04-29 12:33:05 +03:00
|
|
|
node->arguments.resize(child_count - 1);
|
2023-04-09 18:49:52 +03:00
|
|
|
for (size_t i = 0; i + 1 < child_count; ++i) {
|
2023-05-13 13:11:12 +03:00
|
|
|
node->arguments[i] = parse_node.NthNamedChild(i + 1).GetValue();
|
2023-03-29 11:42:00 +03:00
|
|
|
}
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
2023-04-09 18:49:52 +03:00
|
|
|
void BuildVisitor::Visit(TypeDefinition* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node.ChildByFieldName("type");
|
|
|
|
|
node->type = std::make_unique<AnnotatedType>();
|
2023-03-28 12:05:20 +03:00
|
|
|
Visit(node->type.get());
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
size_t child_count = parse_node.NamedChildCount();
|
|
|
|
|
|
|
|
|
|
if (child_count > 1) {
|
2023-04-09 18:49:52 +03:00
|
|
|
for (size_t i = 0; i + 1 < child_count; ++i) {
|
2023-03-29 23:19:54 +03:00
|
|
|
current_node_ = parse_node.NthNamedChild(i + 1);
|
2023-04-12 13:31:39 +03:00
|
|
|
node->parameters.push_back(std::make_unique<AnnotatedAbstractType>());
|
2023-04-09 18:49:52 +03:00
|
|
|
Visit(node->parameters.back().get());
|
2023-03-29 11:42:00 +03:00
|
|
|
}
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
2023-04-12 13:31:39 +03:00
|
|
|
void BuildVisitor::Visit(AnyAnnotatedType* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
2023-03-29 23:19:54 +03:00
|
|
|
node->type = parse_node.ChildByFieldName("type").GetValue();
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
size_t child_count = parse_node.NamedChildCount();
|
|
|
|
|
|
|
|
|
|
if (child_count > 1) {
|
2023-03-31 12:10:12 +03:00
|
|
|
node->typeclasses.resize(child_count - 1);
|
2023-03-29 11:42:00 +03:00
|
|
|
|
2023-04-09 18:49:52 +03:00
|
|
|
for (size_t i = 0; i + 1 < child_count; ++i) {
|
2023-03-29 23:19:54 +03:00
|
|
|
current_node_ = parse_node.NthNamedChild(i + 1);
|
2023-05-02 17:30:57 +03:00
|
|
|
node->typeclasses[i] = std::make_unique<ParametrizedTypeclass>();
|
2023-04-25 21:21:36 +03:00
|
|
|
Visit(node->typeclasses[i].get());
|
2023-03-29 11:42:00 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-28 12:05:20 +03:00
|
|
|
// Flow control -----------------
|
|
|
|
|
|
2023-04-25 21:21:36 +03:00
|
|
|
void BuildVisitor::Visit(TypeConstructorPatternParameter* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-04-25 21:21:36 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
|
|
|
|
size_t child_count = parse_node.NamedChildCount();
|
|
|
|
|
|
|
|
|
|
if (child_count > 1) {
|
2023-05-13 13:11:12 +03:00
|
|
|
node->name.value() = parse_node.ChildByFieldName("name").GetValue();
|
2023-04-25 21:21:36 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node.ChildByFieldName("value"),
|
|
|
|
|
Visit(node->value);
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BuildVisitor::Visit(TypeConstructorPattern* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-04-25 21:21:36 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
2023-04-29 09:33:59 +03:00
|
|
|
current_node_ = parse_node.ChildByFieldName("constructor");
|
2023-05-07 19:52:35 +03:00
|
|
|
node->constructor = std::make_unique<TypeExpression>();
|
2023-04-29 09:33:59 +03:00
|
|
|
Visit(node->constructor.get());
|
2023-04-25 21:21:36 +03:00
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-05-06 13:46:01 +03:00
|
|
|
void BuildVisitor::Visit(Pattern& node) { // <-> ScopedPattern
|
2023-04-25 21:21:36 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node.NthNamedChild(0);
|
|
|
|
|
|
|
|
|
|
std::string current_node_type = current_node_.GetType();
|
|
|
|
|
|
2023-05-13 13:11:12 +03:00
|
|
|
if (current_node_type == parser::tokens::NameIdentifier) { // optimize ??
|
|
|
|
|
node = std::make_unique<NameIdentifier>(current_node_.GetValue());
|
|
|
|
|
// Visit(std::get<std::unique_ptr<NameIdentifier>>(node).get());
|
2023-04-25 21:21:36 +03:00
|
|
|
} else if (current_node_type == parser::tokens::Literal) {
|
|
|
|
|
node = std::make_unique<Literal>();
|
|
|
|
|
Visit(*std::get<std::unique_ptr<Literal>>(node));
|
|
|
|
|
} else if (current_node_type == parser::tokens::TypeConstructorPattern) {
|
|
|
|
|
node = std::make_unique<TypeConstructorPattern>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<TypeConstructorPattern>>(node).get());
|
|
|
|
|
} else {
|
|
|
|
|
// error
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
void BuildVisitor::Visit(MatchCase* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
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) {
|
2023-04-09 18:49:52 +03:00
|
|
|
std::string prefix = parse_node.NthChild(2).GetValue();
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
if (child_count > 2 || prefix == "?") {
|
|
|
|
|
current_node_ = parse_node.ChildByFieldName("condition");
|
|
|
|
|
node->condition.emplace();
|
|
|
|
|
Visit(node->condition.value());
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
if (child_count > 2 || prefix == "->") {
|
|
|
|
|
current_node_ = parse_node.ChildByFieldName("statement");
|
|
|
|
|
node->statement.emplace();
|
|
|
|
|
Visit(node->statement.value());
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
}
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BuildVisitor::Visit(Match* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
2023-05-20 20:18:49 +03:00
|
|
|
node->is_consuming_value = (parse_node.NthChild(1).GetValue() == "<-");
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
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);
|
|
|
|
|
|
2023-04-11 13:49:22 +03:00
|
|
|
for (size_t i = 0; i + 1 < child_count; ++i) {
|
2023-03-29 23:19:54 +03:00
|
|
|
current_node_ = parse_node.NthNamedChild(i + 1);
|
2023-03-29 11:42:00 +03:00
|
|
|
Visit(&node->matches[i]);
|
|
|
|
|
}
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BuildVisitor::Visit(Condition* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
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]);
|
|
|
|
|
}
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BuildVisitor::Visit(DoWhileLoop* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
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;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BuildVisitor::Visit(WhileLoop* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
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;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
void BuildVisitor::Visit(ForLoop* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
2023-05-06 14:04:13 +03:00
|
|
|
if (parse_node.ChildCount() < 7) { // no "var" node
|
2023-05-06 13:46:01 +03:00
|
|
|
node->variable_modifier = utils::IsConstModifier::Const;
|
2023-05-06 14:04:13 +03:00
|
|
|
} else {
|
2023-05-06 13:46:01 +03:00
|
|
|
node->variable_modifier = utils::IsConstModifier::Var;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
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;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BuildVisitor::Visit(LoopLoop* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
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<Match>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<Match>>(node).get());
|
|
|
|
|
} else if (current_node_type == parser::tokens::Condition) {
|
|
|
|
|
node = std::make_unique<Condition>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<Condition>>(node).get());
|
|
|
|
|
} else if (current_node_type == parser::tokens::DoWhileLoop) {
|
|
|
|
|
node = std::make_unique<DoWhileLoop>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<DoWhileLoop>>(node).get());
|
|
|
|
|
} else if (current_node_type == parser::tokens::WhileLoop) {
|
|
|
|
|
node = std::make_unique<WhileLoop>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<WhileLoop>>(node).get());
|
|
|
|
|
} else if (current_node_type == parser::tokens::ForLoop) {
|
|
|
|
|
node = std::make_unique<ForLoop>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<ForLoop>>(node).get());
|
|
|
|
|
} else if (current_node_type == parser::tokens::LoopLoop) {
|
|
|
|
|
node = std::make_unique<LoopLoop>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<LoopLoop>>(node).get());
|
|
|
|
|
} else {
|
|
|
|
|
// error
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Statements, expressions, blocks, etc. -----------------
|
|
|
|
|
|
2023-04-10 01:48:07 +03:00
|
|
|
void BuildVisitor::Visit(BlockStatement& node) {
|
2023-03-29 11:42:00 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
2023-04-10 01:48:07 +03:00
|
|
|
current_node_ = parse_node.NthNamedChild(0);
|
2023-03-29 11:42:00 +03:00
|
|
|
|
2023-04-10 01:48:07 +03:00
|
|
|
std::string current_node_type = current_node_.GetType();
|
|
|
|
|
|
|
|
|
|
if (current_node_type == parser::tokens::Expression) { // optimize ??
|
|
|
|
|
node = std::make_unique<Expression>();
|
|
|
|
|
Visit(*std::get<std::unique_ptr<Expression>>(node));
|
|
|
|
|
} else if (current_node_type == parser::tokens::VariableDefinitionStatement) {
|
|
|
|
|
node = std::make_unique<VariableDefinitionStatement>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<VariableDefinitionStatement>>(node).get());
|
|
|
|
|
} else if (current_node_type == parser::tokens::FlowControl) {
|
|
|
|
|
node = std::make_unique<FlowControl>();
|
|
|
|
|
Visit(*std::get<std::unique_ptr<FlowControl>>(node));
|
|
|
|
|
} else if (current_node_type == parser::tokens::PrefixedExpression) {
|
|
|
|
|
node = std::make_unique<PrefixedExpression>();
|
|
|
|
|
Visit(*std::get<std::unique_ptr<PrefixedExpression>>(node));
|
|
|
|
|
} else {
|
|
|
|
|
// error
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
2023-04-10 01:48:07 +03:00
|
|
|
void BuildVisitor::Visit(Block* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
auto parse_node = current_node_;
|
2023-04-10 01:48:07 +03:00
|
|
|
size_t statement_count = parse_node.NamedChildCount();
|
2023-03-29 11:42:00 +03:00
|
|
|
|
2023-04-10 01:48:07 +03:00
|
|
|
node->statements.resize(statement_count);
|
2023-03-29 11:42:00 +03:00
|
|
|
|
2023-04-10 01:48:07 +03:00
|
|
|
for (size_t i = 0; i < statement_count; ++i) {
|
|
|
|
|
current_node_ = parse_node.NthNamedChild(i);
|
|
|
|
|
Visit(node->statements[i]);
|
2023-03-29 11:42:00 +03:00
|
|
|
}
|
|
|
|
|
|
2023-04-10 01:48:07 +03:00
|
|
|
current_node_ = parse_node;
|
|
|
|
|
}
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
void BuildVisitor::Visit(SubExpressionToken& node) {
|
|
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node.NthNamedChild(0);
|
|
|
|
|
|
|
|
|
|
std::string current_node_type = current_node_.GetType();
|
|
|
|
|
|
2023-04-11 13:49:22 +03:00
|
|
|
if (current_node_type == parser::tokens::NameExpression) {
|
2023-04-09 18:49:52 +03:00
|
|
|
node = std::make_unique<NameExpression>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<NameExpression>>(node).get());
|
2023-03-29 11:42:00 +03:00
|
|
|
} else if (current_node_type == parser::tokens::ScopedStatement) {
|
|
|
|
|
node = std::make_unique<ScopedStatement>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<ScopedStatement>>(node).get());
|
2023-04-21 14:27:55 +03:00
|
|
|
} if (current_node_type == parser::tokens::AccessExpression) {
|
|
|
|
|
node = std::make_unique<AccessExpression>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<AccessExpression>>(node).get());
|
|
|
|
|
} else if (current_node_type == parser::tokens::Literal) {
|
|
|
|
|
node = std::make_unique<Literal>();
|
|
|
|
|
Visit(*std::get<std::unique_ptr<Literal>>(node));
|
2023-03-29 11:42:00 +03:00
|
|
|
} 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<FunctionCallExpression>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<FunctionCallExpression>>(node).get());
|
|
|
|
|
} else if (current_node_type == parser::tokens::BinaryOperatorExpression) {
|
2023-05-17 15:49:15 +03:00
|
|
|
node = std::make_unique<FunctionCallExpression>();
|
|
|
|
|
VisitBinaryOperatorExpression(std::get<std::unique_ptr<FunctionCallExpression>>(node).get());
|
2023-03-29 11:42:00 +03:00
|
|
|
} else if (current_node_type == parser::tokens::SubExpressionToken) {
|
|
|
|
|
node = std::make_unique<SubExpressionToken>();
|
2023-04-02 15:10:32 +03:00
|
|
|
Visit(*std::get<std::unique_ptr<SubExpressionToken>>(node));
|
2023-04-10 01:48:07 +03:00
|
|
|
} else if (current_node_type == parser::tokens::ReferenceExpression) {
|
|
|
|
|
node = std::make_unique<ReferenceExpression>();
|
2023-04-11 13:49:22 +03:00
|
|
|
Visit(std::get<std::unique_ptr<ReferenceExpression>>(node).get());
|
2023-03-29 11:42:00 +03:00
|
|
|
} 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<ReturnExpression>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<ReturnExpression>>(node).get());
|
|
|
|
|
} else if (current_node_type == parser::tokens::LoopControlExpression) {
|
|
|
|
|
node = std::make_unique<LoopControlExpression>();
|
2023-04-02 15:10:32 +03:00
|
|
|
Visit(*std::get<std::unique_ptr<LoopControlExpression>>(node));
|
2023-03-29 11:42:00 +03:00
|
|
|
} else if (current_node_type == parser::tokens::Block) {
|
|
|
|
|
node = std::make_unique<Block>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<Block>>(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<LambdaFunction>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<LambdaFunction>>(node).get());
|
|
|
|
|
} else if (current_node_type == parser::tokens::TypeConstructor) {
|
|
|
|
|
node = std::make_unique<TypeConstructor>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<TypeConstructor>>(node).get());
|
|
|
|
|
} else if (current_node_type == parser::tokens::PrefixedExpression) {
|
|
|
|
|
node = std::make_unique<PrefixedExpression>();
|
2023-04-02 15:10:32 +03:00
|
|
|
Visit(*std::get<std::unique_ptr<PrefixedExpression>>(node));
|
2023-03-29 11:42:00 +03:00
|
|
|
} else if (current_node_type == parser::tokens::SubExpression) {
|
|
|
|
|
node = std::make_unique<SubExpression>();
|
2023-04-02 15:10:32 +03:00
|
|
|
Visit(*std::get<std::unique_ptr<SubExpression>>(node));
|
2023-03-29 11:42:00 +03:00
|
|
|
} 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<FlowControl>();
|
2023-04-02 15:10:32 +03:00
|
|
|
Visit(*std::get<std::unique_ptr<FlowControl>>(node));
|
2023-03-29 11:42:00 +03:00
|
|
|
} else if (current_node_type == parser::tokens::TupleExpression) {
|
|
|
|
|
node = std::make_unique<TupleExpression>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<TupleExpression>>(node).get());
|
|
|
|
|
} else if (current_node_type == parser::tokens::VariantExpression) {
|
|
|
|
|
node = std::make_unique<VariantExpression>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<VariantExpression>>(node).get());
|
2023-04-25 21:21:36 +03:00
|
|
|
} else if (current_node_type == parser::tokens::ArrayExpression) {
|
|
|
|
|
node = std::make_unique<ArrayExpression>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<ArrayExpression>>(node).get());
|
2023-03-29 11:42:00 +03:00
|
|
|
} else if (current_node_type == parser::tokens::Expression) {
|
|
|
|
|
node = std::make_unique<Expression>();
|
2023-04-02 15:10:32 +03:00
|
|
|
Visit(*std::get<std::unique_ptr<Expression>>(node));
|
2023-03-29 11:42:00 +03:00
|
|
|
} else {
|
|
|
|
|
// error
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-10 01:48:07 +03:00
|
|
|
void BuildVisitor::Visit(ScopedStatement* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
2023-04-10 01:48:07 +03:00
|
|
|
current_node_ = parse_node.ChildByFieldName("statement");
|
|
|
|
|
Visit(node->statement);
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Operators
|
|
|
|
|
|
2023-05-17 15:49:15 +03:00
|
|
|
void BuildVisitor::VisitBinaryOperatorExpression(FunctionCallExpression* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
2023-05-17 15:49:15 +03:00
|
|
|
node->is_binary_operator_expression = true;
|
|
|
|
|
node->arguments.resize(2);
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
current_node_ = parse_node.ChildByFieldName("left_expression");
|
2023-05-17 15:49:15 +03:00
|
|
|
Visit(node->arguments[0]);
|
2023-03-29 11:42:00 +03:00
|
|
|
|
2023-05-17 15:49:15 +03:00
|
|
|
node->name = parse_node.ChildByFieldName("operator_name").GetValue();
|
2023-03-29 11:42:00 +03:00
|
|
|
|
2023-05-13 13:11:12 +03:00
|
|
|
{ // remove operator precedence markers
|
2023-05-11 23:14:36 +03:00
|
|
|
size_t operator_size = 0;
|
2023-05-17 15:49:15 +03:00
|
|
|
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);
|
2023-05-11 23:14:36 +03:00
|
|
|
}
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
current_node_ = parse_node.ChildByFieldName("right_expression");
|
2023-05-17 15:49:15 +03:00
|
|
|
Visit(node->arguments[1]);
|
2023-03-29 11:42:00 +03:00
|
|
|
|
2023-05-13 13:11:12 +03:00
|
|
|
// ??
|
2023-05-17 15:49:15 +03:00
|
|
|
for (size_t i = 0; i < node->arguments.size(); ++i) {
|
|
|
|
|
if (std::holds_alternative<std::unique_ptr<FunctionCallExpression>>(node->arguments[i])) {
|
|
|
|
|
FunctionCallExpression* argument_node = std::get<std::unique_ptr<FunctionCallExpression>>(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);
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-05-13 13:11:12 +03:00
|
|
|
}
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
2023-04-10 01:48:07 +03:00
|
|
|
void BuildVisitor::Visit(ReferenceExpression* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-04-10 01:48:07 +03:00
|
|
|
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();
|
2023-05-13 13:11:12 +03:00
|
|
|
if (reference == "^") {
|
2023-05-05 16:35:13 +03:00
|
|
|
node->references[i] = utils::ReferenceModifier::Reference;
|
2023-05-13 13:11:12 +03:00
|
|
|
} else if (reference == "~") {
|
|
|
|
|
node->references[i] = utils::ReferenceModifier::Dereference;
|
2023-05-20 20:18:49 +03:00
|
|
|
} else if (reference == "@") {
|
|
|
|
|
node->references[i] = utils::ReferenceModifier::UniqueReference; // TODO: rename to move ??
|
2023-04-10 01:48:07 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node.ChildByFieldName("expression");
|
2023-04-11 13:49:22 +03:00
|
|
|
node->expression = std::make_unique<ScopedStatement>();
|
2023-04-10 01:48:07 +03:00
|
|
|
Visit(node->expression.get());
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-21 14:27:55 +03:00
|
|
|
void BuildVisitor::Visit(AccessExpression* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-04-21 14:27:55 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node.ChildByFieldName("name");
|
2023-04-26 01:02:53 +03:00
|
|
|
node->name = std::make_unique<NameExpression>();
|
2023-04-21 14:27:55 +03:00
|
|
|
Visit(node->name.get());
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node.ChildByFieldName("id");
|
|
|
|
|
Visit(node->id);
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-10 01:48:07 +03:00
|
|
|
// Other expressions
|
2023-03-28 12:05:20 +03:00
|
|
|
|
|
|
|
|
void BuildVisitor::Visit(FunctionCallExpression* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
2023-04-25 21:21:36 +03:00
|
|
|
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<SubExpressionToken>();
|
|
|
|
|
Visit(*std::get<std::unique_ptr<SubExpressionToken>>(node->prefix.value()));
|
|
|
|
|
++excluded_child_count;
|
|
|
|
|
} else if (current_node_type == parser::tokens::TypeExpression) {
|
|
|
|
|
node->prefix = std::make_unique<TypeExpression>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<TypeExpression>>(node->prefix.value()).get());
|
|
|
|
|
++excluded_child_count;
|
|
|
|
|
} else {
|
|
|
|
|
// no prefix
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-13 13:11:12 +03:00
|
|
|
node->name = parse_node.ChildByFieldName("name").GetValue();
|
2023-04-25 21:21:36 +03:00
|
|
|
++excluded_child_count;
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
size_t child_count = parse_node.NamedChildCount();
|
|
|
|
|
|
2023-05-07 09:25:38 +03:00
|
|
|
if (child_count > excluded_child_count) {
|
2023-05-05 10:17:10 +03:00
|
|
|
bool parameters_ended = false;
|
|
|
|
|
|
2023-04-25 21:21:36 +03:00
|
|
|
for (size_t i = 0; i + excluded_child_count < child_count; ++i) {
|
|
|
|
|
current_node_ = parse_node.NthNamedChild(i + excluded_child_count);
|
2023-05-05 10:17:10 +03:00
|
|
|
|
|
|
|
|
if (current_node_.GetType() != parser::tokens::TypeExpression) {
|
|
|
|
|
parameters_ended = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!parameters_ended) {
|
|
|
|
|
node->parameters.push_back(std::make_unique<TypeExpression>());
|
|
|
|
|
Visit(node->parameters.back().get());
|
|
|
|
|
} else {
|
2023-05-17 15:49:15 +03:00
|
|
|
node->arguments.push_back(std::make_unique<SubExpressionToken>());
|
|
|
|
|
Visit(*std::get<std::unique_ptr<SubExpressionToken>>(node->arguments.back()));
|
2023-05-05 10:17:10 +03:00
|
|
|
}
|
2023-04-25 21:21:36 +03:00
|
|
|
}
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BuildVisitor::Visit(TupleExpression* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
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) {
|
2023-04-11 13:49:22 +03:00
|
|
|
current_node_ = parse_node.NthNamedChild(i);
|
|
|
|
|
Visit(node->expressions[i]);
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BuildVisitor::Visit(VariantExpression* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
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) {
|
2023-04-11 13:49:22 +03:00
|
|
|
current_node_ = parse_node.NthNamedChild(i);
|
|
|
|
|
Visit(node->expressions[i]);
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BuildVisitor::Visit(ReturnExpression* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
2023-05-20 20:18:49 +03:00
|
|
|
node->is_from_definition = (parse_node.NthChild(0).GetValue() == "return"); // "return" to return from definition and "bring" to return from block
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
current_node_ = parse_node.ChildByFieldName("expression");
|
|
|
|
|
Visit(node->expression);
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-25 21:21:36 +03:00
|
|
|
void BuildVisitor::Visit(TypeConstructorParameter* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-04-11 13:49:22 +03:00
|
|
|
auto parse_node = current_node_;
|
2023-04-10 01:48:07 +03:00
|
|
|
|
2023-04-25 21:21:36 +03:00
|
|
|
size_t child_count = parse_node.NamedChildCount();
|
|
|
|
|
|
|
|
|
|
if (child_count > 1) {
|
2023-05-13 13:11:12 +03:00
|
|
|
node->name = parse_node.ChildByFieldName("name").GetValue();
|
2023-04-25 21:21:36 +03:00
|
|
|
|
|
|
|
|
std::string assignment_modifier = current_node_.NextSibling().GetValue();
|
|
|
|
|
if (assignment_modifier == "=") {
|
2023-05-05 16:35:13 +03:00
|
|
|
node->asignment_modifier = utils::AssignmentModifier::Assign;
|
2023-04-25 21:21:36 +03:00
|
|
|
} else if (assignment_modifier == "<-") {
|
2023-05-05 16:35:13 +03:00
|
|
|
node->asignment_modifier = utils::AssignmentModifier::Move;
|
2023-04-25 21:21:36 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node.ChildByFieldName("value");
|
|
|
|
|
Visit(node->value);
|
2023-04-10 01:48:07 +03:00
|
|
|
|
2023-04-25 21:21:36 +03:00
|
|
|
current_node_ = parse_node;
|
|
|
|
|
}
|
2023-03-29 11:42:00 +03:00
|
|
|
|
2023-04-25 21:21:36 +03:00
|
|
|
void BuildVisitor::Visit(TypeConstructor* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-04-25 21:21:36 +03:00
|
|
|
auto parse_node = current_node_;
|
2023-03-29 11:42:00 +03:00
|
|
|
|
2023-05-20 20:18:49 +03:00
|
|
|
node->is_allocated_on_heap = (parse_node.NthChild(1).GetValue() == "@");
|
|
|
|
|
|
2023-04-25 21:21:36 +03:00
|
|
|
current_node_ = parse_node.ChildByFieldName("constructor");
|
|
|
|
|
node->constructor = std::make_unique<TypeExpression>();
|
|
|
|
|
Visit(node->constructor.get());
|
2023-03-29 11:42:00 +03:00
|
|
|
|
2023-04-25 21:21:36 +03:00
|
|
|
size_t child_count = parse_node.NamedChildCount();
|
2023-03-29 11:42:00 +03:00
|
|
|
|
2023-04-25 21:21:36 +03:00
|
|
|
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]);
|
2023-04-11 13:49:22 +03:00
|
|
|
}
|
2023-03-29 11:42:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BuildVisitor::Visit(LambdaFunction* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
|
|
|
|
size_t child_count = parse_node.NamedChildCount();
|
|
|
|
|
|
|
|
|
|
if (child_count > 1) {
|
|
|
|
|
bool parameters_ended = false;
|
|
|
|
|
|
2023-04-11 13:49:22 +03:00
|
|
|
for (size_t i = 0; i + 1 < child_count; ++i) {
|
|
|
|
|
current_node_ = parse_node.NthNamedChild(i);
|
2023-03-29 11:42:00 +03:00
|
|
|
|
2023-04-12 13:31:39 +03:00
|
|
|
if (current_node_.GetType() != parser::tokens::AnnotatedAbstractType) {
|
2023-04-11 13:49:22 +03:00
|
|
|
parameters_ended = true;
|
|
|
|
|
}
|
2023-03-29 11:42:00 +03:00
|
|
|
|
2023-04-11 13:49:22 +03:00
|
|
|
if (!parameters_ended) {
|
2023-04-12 13:31:39 +03:00
|
|
|
node->parameters.push_back(std::make_unique<AnnotatedAbstractType>());
|
2023-04-11 13:49:22 +03:00
|
|
|
Visit(node->parameters.back().get());
|
|
|
|
|
} else {
|
|
|
|
|
node->arguments.emplace_back();
|
2023-05-13 13:11:12 +03:00
|
|
|
node->arguments.back() = current_node_.GetValue();
|
2023-04-11 13:49:22 +03:00
|
|
|
}
|
2023-03-29 11:42:00 +03:00
|
|
|
}
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
current_node_ = parse_node.ChildByFieldName("expression");
|
|
|
|
|
Visit(node->expression);
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
2023-04-11 13:49:22 +03:00
|
|
|
void BuildVisitor::Visit(ArrayExpression* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-04-11 13:49:22 +03:00
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-28 12:05:20 +03:00
|
|
|
// Name
|
|
|
|
|
|
2023-05-07 22:58:15 +03:00
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-11 15:14:02 +03:00
|
|
|
node->path.push_back(parse_node.ChildByFieldName("name").GetValue());
|
2023-05-07 22:58:15 +03:00
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-09 18:49:52 +03:00
|
|
|
void BuildVisitor::Visit(NameExpression* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 23:19:54 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
|
|
|
|
size_t child_count = parse_node.NamedChildCount();
|
|
|
|
|
|
2023-04-25 21:21:36 +03:00
|
|
|
node->names.resize(child_count);
|
2023-03-29 23:19:54 +03:00
|
|
|
for (size_t i = 0; i < child_count; ++i) {
|
2023-05-13 13:11:12 +03:00
|
|
|
node->names[i] = parse_node.NthNamedChild(i).GetValue();
|
2023-03-29 23:19:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BuildVisitor::Visit(TupleName* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
|
|
|
|
size_t names_count = parse_node.NamedChildCount();
|
|
|
|
|
|
2023-03-31 12:10:12 +03:00
|
|
|
node->names.resize(names_count);
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
for (size_t i = 0; i < names_count; ++i) {
|
|
|
|
|
current_node_ = parse_node.NthNamedChild(i);
|
2023-03-31 12:10:12 +03:00
|
|
|
node->names[i] = std::make_unique<AnnotatedName>();
|
2023-04-11 13:49:22 +03:00
|
|
|
Visit(node->names[i]);
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BuildVisitor::Visit(VariantName* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
|
|
|
|
size_t names_count = parse_node.NamedChildCount();
|
|
|
|
|
|
2023-03-31 12:10:12 +03:00
|
|
|
node->names.resize(names_count);
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
for (size_t i = 0; i < names_count; ++i) {
|
|
|
|
|
current_node_ = parse_node.NthNamedChild(i);
|
2023-03-31 12:10:12 +03:00
|
|
|
node->names[i] =std::make_unique<AnnotatedName>();
|
2023-04-11 13:49:22 +03:00
|
|
|
Visit(node->names[i]);
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BuildVisitor::Visit(AnnotatedName* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
|
|
|
|
node->name = parse_node.ChildByFieldName("name").GetValue();
|
|
|
|
|
|
2023-03-31 12:10:12 +03:00
|
|
|
if (parse_node.NamedChildCount() > 1) {
|
2023-03-29 11:42:00 +03:00
|
|
|
current_node_ = parse_node.ChildByFieldName("type");
|
2023-04-25 21:21:36 +03:00
|
|
|
node->type.emplace();
|
2023-04-11 13:49:22 +03:00
|
|
|
Visit(node->type.value());
|
2023-03-29 11:42:00 +03:00
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
|
2023-04-11 13:49:22 +03:00
|
|
|
if (current_node_type == parser::tokens::AnnotatedName) {
|
2023-03-29 11:42:00 +03:00
|
|
|
node = std::make_unique<AnnotatedName>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<AnnotatedName>>(node).get());
|
|
|
|
|
} else if (current_node_type == parser::tokens::TupleName) {
|
|
|
|
|
node = std::make_unique<TupleName>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<TupleName>>(node).get());
|
|
|
|
|
} else if (current_node_type == parser::tokens::VariantName) {
|
|
|
|
|
node = std::make_unique<VariantName>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<VariantName>>(node).get());
|
|
|
|
|
} else {
|
|
|
|
|
// error
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
2023-04-11 13:49:22 +03:00
|
|
|
// Type, typeclass, etc. -----------------
|
|
|
|
|
|
2023-03-28 12:05:20 +03:00
|
|
|
// Type
|
|
|
|
|
|
2023-04-11 13:49:22 +03:00
|
|
|
void BuildVisitor::Visit(FunctionType* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-04-09 18:49:52 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
2023-04-11 13:49:22 +03:00
|
|
|
size_t types_count = parse_node.NamedChildCount();
|
2023-04-09 18:49:52 +03:00
|
|
|
|
2023-04-11 13:49:22 +03:00
|
|
|
node->types.resize(types_count);
|
2023-04-09 18:49:52 +03:00
|
|
|
|
2023-04-11 13:49:22 +03:00
|
|
|
for (size_t i = 0; i < types_count; ++i) {
|
|
|
|
|
current_node_ = parse_node.NthNamedChild(i);
|
|
|
|
|
Visit(node->types[i]);
|
2023-04-09 18:49:52 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BuildVisitor::Visit(TupleType* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 23:19:54 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
2023-05-17 17:57:56 +03:00
|
|
|
size_t current_child = 0;
|
2023-03-29 23:19:54 +03:00
|
|
|
|
2023-05-17 17:57:56 +03:00
|
|
|
current_node_ = parse_node.NthNamedChild(current_child);
|
2023-03-29 23:19:54 +03:00
|
|
|
|
2023-05-17 17:57:56 +03:00
|
|
|
if (parse_node.NthChild(0).GetValue() != "&") {
|
2023-04-11 13:49:22 +03:00
|
|
|
node->type = current_node_.GetValue();
|
2023-03-29 23:19:54 +03:00
|
|
|
|
2023-05-17 17:57:56 +03:00
|
|
|
++current_child;
|
|
|
|
|
current_node_ = parse_node.NthNamedChild(current_child);
|
2023-03-29 23:19:54 +03:00
|
|
|
}
|
|
|
|
|
|
2023-05-17 17:57:56 +03:00
|
|
|
while (current_child < parse_node.NamedChildCount()) {
|
2023-03-29 23:19:54 +03:00
|
|
|
node->entities.emplace_back();
|
|
|
|
|
|
2023-05-13 13:11:12 +03:00
|
|
|
if (current_node_.GetType() == parser::tokens::NameIdentifier) {
|
|
|
|
|
node->entities.back().first = current_node_.GetValue();
|
2023-03-29 23:19:54 +03:00
|
|
|
|
2023-05-17 17:57:56 +03:00
|
|
|
++current_child;
|
|
|
|
|
current_node_ = parse_node.NthNamedChild(current_child);
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
2023-03-29 23:19:54 +03:00
|
|
|
|
2023-04-11 13:49:22 +03:00
|
|
|
node->entities.back().second = std::make_unique<ExtendedScopedAnyType>();
|
|
|
|
|
Visit(node->entities.back().second.get());
|
2023-03-29 23:19:54 +03:00
|
|
|
|
2023-05-17 17:57:56 +03:00
|
|
|
++current_child;
|
|
|
|
|
current_node_ = parse_node.NthNamedChild(current_child);
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
2023-03-29 23:19:54 +03:00
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BuildVisitor::Visit(VariantType* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 23:19:54 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
2023-05-17 17:57:56 +03:00
|
|
|
size_t excluded_child_count = 0;
|
2023-03-29 23:19:54 +03:00
|
|
|
|
2023-05-17 17:57:56 +03:00
|
|
|
size_t child_count = parse_node.NamedChildCount();
|
2023-03-29 23:19:54 +03:00
|
|
|
|
2023-05-17 17:57:56 +03:00
|
|
|
if (parse_node.NthChild(0).GetValue() != "|") {
|
|
|
|
|
node->type = parse_node.NthNamedChild(0).GetValue();
|
2023-03-29 23:19:54 +03:00
|
|
|
|
2023-05-17 17:57:56 +03:00
|
|
|
++excluded_child_count;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
2023-03-29 23:19:54 +03:00
|
|
|
|
|
|
|
|
|
2023-05-17 17:57:56 +03:00
|
|
|
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();
|
2023-03-29 23:19:54 +03:00
|
|
|
|
2023-04-11 13:49:22 +03:00
|
|
|
if (current_node_type == parser::tokens::Constructor) {
|
2023-05-17 17:57:56 +03:00
|
|
|
node->constructors[i] = current_node_.GetValue();
|
2023-03-29 23:19:54 +03:00
|
|
|
} else if (current_node_type == parser::tokens::TupleType) {
|
2023-05-17 17:57:56 +03:00
|
|
|
node->constructors[i] = std::make_unique<TupleType>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<TupleType>>(node->constructors[i]).get());
|
2023-03-29 23:19:54 +03:00
|
|
|
} else {
|
|
|
|
|
// error
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BuildVisitor::Visit(TypeExpression* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 23:19:54 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
2023-04-11 13:49:22 +03:00
|
|
|
size_t excluded_child_count = 0;
|
|
|
|
|
|
2023-03-29 23:19:54 +03:00
|
|
|
size_t child_count = parse_node.NamedChildCount();
|
|
|
|
|
|
2023-04-11 13:49:22 +03:00
|
|
|
current_node_ = parse_node.ChildByFieldName("type");
|
2023-05-02 17:30:57 +03:00
|
|
|
Visit(&node->type);
|
2023-04-11 13:49:22 +03:00
|
|
|
++excluded_child_count;
|
|
|
|
|
|
|
|
|
|
current_node_ = current_node_.NextSibling();
|
2023-03-29 23:19:54 +03:00
|
|
|
|
2023-04-11 13:49:22 +03:00
|
|
|
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) {
|
2023-04-25 21:21:36 +03:00
|
|
|
node->path.resize(child_count - excluded_child_count);
|
2023-04-11 13:49:22 +03:00
|
|
|
|
|
|
|
|
for (size_t i = 0; i + excluded_child_count < child_count; ++i) {
|
2023-03-29 23:19:54 +03:00
|
|
|
current_node_ = parse_node.NthNamedChild(i);
|
2023-05-02 17:30:57 +03:00
|
|
|
Visit(&node->path[i]);
|
2023-03-29 23:19:54 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-11 13:49:22 +03:00
|
|
|
void BuildVisitor::Visit(AnyType& node) {
|
2023-03-29 23:19:54 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node.NthNamedChild(0);
|
|
|
|
|
|
|
|
|
|
std::string current_node_type = current_node_.GetType();
|
|
|
|
|
|
2023-04-26 01:02:53 +03:00
|
|
|
if (current_node_type == parser::tokens::TypeExpression) {
|
2023-04-25 21:21:36 +03:00
|
|
|
node = std::make_unique<TypeExpression>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<TypeExpression>>(node).get());
|
2023-03-29 23:19:54 +03:00
|
|
|
} else if (current_node_type == parser::tokens::TupleType) {
|
|
|
|
|
node = std::make_unique<TupleType>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<TupleType>>(node).get());
|
|
|
|
|
} else if (current_node_type == parser::tokens::VariantType) {
|
|
|
|
|
node = std::make_unique<VariantType>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<VariantType>>(node).get());
|
2023-04-11 13:49:22 +03:00
|
|
|
} else if (current_node_type == parser::tokens::FunctionType) {
|
|
|
|
|
node = std::make_unique<FunctionType>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<FunctionType>>(node).get());
|
2023-03-29 23:19:54 +03:00
|
|
|
} else {
|
|
|
|
|
// error
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-11 13:49:22 +03:00
|
|
|
void BuildVisitor::Visit(ExtendedScopedAnyType* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 23:19:54 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
2023-04-11 13:49:22 +03:00
|
|
|
size_t child_count = parse_node.ChildCount();
|
2023-03-29 23:19:54 +03:00
|
|
|
|
2023-04-11 13:49:22 +03:00
|
|
|
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();
|
2023-05-13 13:11:12 +03:00
|
|
|
if (reference == "^") {
|
2023-05-05 16:35:13 +03:00
|
|
|
node->references[i] = utils::ReferenceModifier::Reference;
|
2023-04-11 13:49:22 +03:00
|
|
|
} else if (reference == "@") {
|
2023-05-05 16:35:13 +03:00
|
|
|
node->references[i] = utils::ReferenceModifier::UniqueReference;
|
2023-04-11 13:49:22 +03:00
|
|
|
}
|
|
|
|
|
}
|
2023-03-29 23:19:54 +03:00
|
|
|
}
|
|
|
|
|
|
2023-04-11 13:49:22 +03:00
|
|
|
current_node_ = parse_node.ChildByFieldName("type");
|
|
|
|
|
Visit(node->type);
|
|
|
|
|
|
2023-03-29 23:19:54 +03:00
|
|
|
current_node_ = parse_node;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-11 13:49:22 +03:00
|
|
|
// Typeclass
|
|
|
|
|
|
|
|
|
|
void BuildVisitor::Visit(ParametrizedTypeclass* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-03-29 23:19:54 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
2023-05-05 11:59:02 +03:00
|
|
|
std::string prefixed_typeclass = parse_node.ChildByFieldName("typeclass").GetValue(); // prefix # removed
|
|
|
|
|
node->typeclass = prefixed_typeclass.substr(1, prefixed_typeclass.size() - 1);
|
2023-03-29 23:19:54 +03:00
|
|
|
|
|
|
|
|
size_t child_count = parse_node.NamedChildCount();
|
|
|
|
|
|
|
|
|
|
if (child_count > 1) {
|
2023-04-11 13:49:22 +03:00
|
|
|
node->parameters.resize(child_count - 1);
|
2023-03-29 23:19:54 +03:00
|
|
|
|
2023-04-11 13:49:22 +03:00
|
|
|
for (size_t i = 0; i + 1 < child_count; ++i) {
|
2023-03-29 23:19:54 +03:00
|
|
|
current_node_ = parse_node.NthNamedChild(i + 1);
|
2023-04-25 21:21:36 +03:00
|
|
|
node->parameters[i] = std::make_unique<TypeExpression>();
|
|
|
|
|
Visit(node->parameters[i].get());
|
2023-03-29 23:19:54 +03:00
|
|
|
}
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
2023-03-29 23:19:54 +03:00
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
2023-04-11 13:49:22 +03:00
|
|
|
// Typeclass & Type -----------------
|
|
|
|
|
|
|
|
|
|
|
2023-04-25 21:21:36 +03:00
|
|
|
void BuildVisitor::Visit(ParametrizedType* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-04-11 13:49:22 +03:00
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
2023-04-25 21:21:36 +03:00
|
|
|
node->type = parse_node.ChildByFieldName("type").GetValue();
|
2023-04-11 13:49:22 +03:00
|
|
|
|
2023-04-25 21:21:36 +03:00
|
|
|
size_t child_count = parse_node.NamedChildCount();
|
2023-04-11 13:49:22 +03:00
|
|
|
|
2023-04-25 21:21:36 +03:00
|
|
|
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<TypeExpression>();
|
|
|
|
|
Visit(node->parameters[i].get());
|
|
|
|
|
}
|
2023-04-11 13:49:22 +03:00
|
|
|
}
|
2023-03-29 23:19:54 +03:00
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Identifiers, constants, etc. -----------------
|
|
|
|
|
|
2023-05-05 11:59:02 +03:00
|
|
|
// void BuildVisitor::Visit(AnyIdentifier* node) { // std::string
|
|
|
|
|
// *node = current_node_.GetValue();
|
|
|
|
|
// }
|
2023-03-29 23:19:54 +03:00
|
|
|
|
2023-03-28 12:05:20 +03:00
|
|
|
void BuildVisitor::Visit(FloatNumberLiteral* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-04-02 15:10:32 +03:00
|
|
|
node->value = std::stod(current_node_.GetValue());
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BuildVisitor::Visit(NumberLiteral* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-04-02 15:10:32 +03:00
|
|
|
node->value = std::stoll(current_node_.GetValue());
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BuildVisitor::Visit(StringLiteral* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-04-11 13:49:22 +03:00
|
|
|
std::string literal = current_node_.GetValue();
|
|
|
|
|
node->value = literal.substr(1, literal.size() - 2);
|
2023-03-28 12:05:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BuildVisitor::Visit(CharLiteral* node) {
|
2023-05-05 11:59:02 +03:00
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
|
2023-04-11 13:49:22 +03:00
|
|
|
std::string literal = current_node_.GetValue();
|
|
|
|
|
node->value = literal.substr(1, literal.size() - 2).back(); // TODO: special symbols, etc.
|
2023-03-29 11:42:00 +03:00
|
|
|
}
|
|
|
|
|
|
2023-05-05 11:59:02 +03:00
|
|
|
void BuildVisitor::Visit(UnitLiteral* node) {
|
|
|
|
|
SetPosition(node->base, current_node_);
|
|
|
|
|
}
|
2023-04-26 01:02:53 +03:00
|
|
|
|
2023-05-08 20:34:36 +03:00
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-29 11:42:00 +03:00
|
|
|
void BuildVisitor::Visit(Literal& node) {
|
|
|
|
|
auto parse_node = current_node_;
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node.NthNamedChild(0);
|
|
|
|
|
|
|
|
|
|
std::string current_node_type = current_node_.GetType();
|
|
|
|
|
|
2023-04-11 13:49:22 +03:00
|
|
|
if (current_node_type == parser::tokens::FloatNumberLiteral) {
|
2023-03-29 11:42:00 +03:00
|
|
|
node = std::make_unique<FloatNumberLiteral>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<FloatNumberLiteral>>(node).get());
|
|
|
|
|
} else if (current_node_type == parser::tokens::NumberLiteral) {
|
|
|
|
|
node = std::make_unique<NumberLiteral>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<NumberLiteral>>(node).get());
|
|
|
|
|
} else if (current_node_type == parser::tokens::StringLiteral) {
|
|
|
|
|
node = std::make_unique<StringLiteral>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<StringLiteral>>(node).get());
|
|
|
|
|
} else if (current_node_type == parser::tokens::CharLiteral) {
|
|
|
|
|
node = std::make_unique<CharLiteral>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<CharLiteral>>(node).get());
|
2023-04-26 01:02:53 +03:00
|
|
|
} else if (current_node_type == parser::tokens::UnitLiteral) {
|
|
|
|
|
node = std::make_unique<UnitLiteral>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<UnitLiteral>>(node).get());
|
2023-05-08 20:34:36 +03:00
|
|
|
} else if (current_node_type == parser::tokens::BoolLiteral) {
|
|
|
|
|
node = std::make_unique<BoolLiteral>();
|
|
|
|
|
Visit(std::get<std::unique_ptr<BoolLiteral>>(node).get());
|
2023-03-29 11:42:00 +03:00
|
|
|
} else {
|
|
|
|
|
// error
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
current_node_ = parse_node;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-28 12:05:20 +03:00
|
|
|
} // namespace interpreter
|