mirror of
https://codeberg.org/ProgramSnail/lang_2023.git
synced 2025-12-05 22:48:42 +00:00
218 lines
7 KiB
C++
218 lines
7 KiB
C++
#include <iostream>
|
|
|
|
// for clangd
|
|
#include "../include/error_handling.hpp"
|
|
#include "../include/find_symbols_visitor.hpp"
|
|
|
|
namespace interpreter {
|
|
|
|
// Sources -----------------
|
|
|
|
// Namespaces, partitions -----------------
|
|
|
|
void FindSymbolsVisitor::Visit(Namespace* node) {
|
|
if (namespace_visitor_.GetCurrentNamespace()->modifier != utils::ClassInternalsModifier::Static) {
|
|
// other type of error??
|
|
error_handling::HandleParsingError("Can't use const /var namespace inside const / var namespace",
|
|
node->base.start_position,
|
|
node->base.end_position);
|
|
}
|
|
|
|
namespace_visitor_.AddEnterNamespace(node->type, node->modifier, node, node->base);
|
|
|
|
Visitor::Visit(&node->scope);
|
|
|
|
namespace_visitor_.ExitNamespace();
|
|
}
|
|
|
|
// Definitions -----------------
|
|
|
|
// TODO: add imported symbols to symbol table (global info)
|
|
void FindSymbolsVisitor::Visit(ImportStatement* node) {
|
|
info::definition::Import info;
|
|
info.module_name = node->module_name;
|
|
info.symbols = node->symbols;
|
|
namespace_visitor_.AddImport(std::move(info), node->name);
|
|
}
|
|
|
|
void FindSymbolsVisitor::Visit(AliasDefinitionStatement* node) {
|
|
info::definition::Type info;
|
|
|
|
info::definition::AliasType alias_info;
|
|
|
|
alias_info.modifier = node->modifier;
|
|
|
|
alias_info.parameters = node->parameters;
|
|
alias_info.value.node = node->value.get();
|
|
alias_info.node = node;
|
|
|
|
info.type = std::move(alias_info);
|
|
|
|
node->type_id_ = namespace_visitor_.AddType(node->type, std::move(info), node->base);
|
|
|
|
Visitor::Visit(node->value.get()); // to visit all tree
|
|
}
|
|
|
|
void FindSymbolsVisitor::Visit(FunctionDeclaration* node) {
|
|
info::definition::FunctionDeclaration info;
|
|
|
|
info.parameters.resize(node->parameters.size());
|
|
for (size_t i = 0; i < node->parameters.size(); ++i) {
|
|
Visit(node->parameters[i].get());
|
|
info.parameters[i] = std::move(std::any_cast<info::definition::Parameter>(current_info_));
|
|
current_info_.reset();
|
|
}
|
|
|
|
info.argument_types.resize(node->type->types.size());
|
|
for (size_t i = 0; i < node->type->types.size(); ++i) {
|
|
info.argument_types[i] = &node->type->types[i];
|
|
}
|
|
|
|
info.node = node;
|
|
|
|
node->function_id_ = namespace_visitor_.AddFunctionDeclaration(node->name, std::move(info), node->base);
|
|
|
|
Visitor::Visit(node->type.get()); // to visit all tree
|
|
}
|
|
|
|
void FindSymbolsVisitor::Visit(FunctionDefinitionStatement* node) {
|
|
info::definition::FunctionDefinition info;
|
|
|
|
auto definition = node->definition.get();
|
|
|
|
info.argument_names.resize(definition->arguments.size());
|
|
for (size_t i = 0; i < definition->arguments.size(); ++i) {
|
|
info.argument_names[i] = definition->arguments[i];
|
|
}
|
|
|
|
info.node = node;
|
|
|
|
node->function_id_ = namespace_visitor_.AddFunctionDefinition(definition->name, std::move(info), node->base);
|
|
|
|
Visitor::Visit(definition); // to visit all tree
|
|
Visitor::Visit(node->value); // to visit all tree
|
|
}
|
|
|
|
void FindSymbolsVisitor::Visit(TypeDefinitionStatement* node) {
|
|
info::definition::Type info;
|
|
|
|
auto definition = node->definition.get();
|
|
|
|
info::definition::AnyType any_type_info;
|
|
|
|
Visit(definition->type.get());
|
|
any_type_info.type = std::move(std::any_cast<info::definition::Parameter>(current_info_));
|
|
current_info_.reset();
|
|
|
|
any_type_info.parameters.resize(definition->parameters.size());
|
|
for (size_t i = 0; i < definition->parameters.size(); ++i) {
|
|
Visit(definition->parameters[i].get());
|
|
any_type_info.parameters[i] = std::move(std::any_cast<info::definition::Parameter>(current_info_));
|
|
current_info_.reset();
|
|
}
|
|
|
|
any_type_info.node = node;
|
|
any_type_info.parent_namespace = namespace_visitor_.GetCurrentNamespaceId();
|
|
any_type_info.modifier = node->modifier;
|
|
|
|
std::string type = any_type_info.type.type;
|
|
|
|
info.type = std::move(any_type_info);
|
|
|
|
node->type_id_ = namespace_visitor_.AddType(type, std::move(info), node->base);
|
|
|
|
auto maybe_graph_type_vertex = namespace_visitor_.GetTypeclassGraph()->GetTypeVertex(node->definition->type->graph_id_);
|
|
|
|
if (!maybe_graph_type_vertex.has_value()) {
|
|
error_handling::HandleInternalError("Type vertex in TypeclassGraph is not type vertex",
|
|
"FindSymbolsVisitor.FunctionDefinitionStatement",
|
|
&node->base);
|
|
}
|
|
|
|
maybe_graph_type_vertex.value()->type_id = node->type_id_;
|
|
|
|
// definition visited earlier
|
|
Visitor::Visit(node->value); // to visit all tree
|
|
}
|
|
|
|
void FindSymbolsVisitor::Visit(AbstractTypeDefinitionStatement* node) {
|
|
info::definition::AbstractType info;
|
|
|
|
Visit(node->type.get());
|
|
info.type = std::move(std::any_cast<info::definition::Parameter>(current_info_));
|
|
current_info_.reset();
|
|
|
|
info.modifier = node->modifier;
|
|
info.node = node;
|
|
|
|
std::string type = info.type.type;
|
|
|
|
node->type_id_ = namespace_visitor_.AddAbstractType(type, std::move(info), node->base);
|
|
}
|
|
|
|
void FindSymbolsVisitor::Visit(TypeclassDefinitionStatement* node) {
|
|
info::definition::Typeclass info;
|
|
|
|
auto definition = node->definition.get();
|
|
|
|
std::string& typeclass_name = definition->type.get()->type;
|
|
|
|
info.parameters.resize(definition->parameters.size());
|
|
for (size_t i = 0; i < definition->parameters.size(); ++i) {
|
|
Visit(definition->parameters[i].get());
|
|
info.parameters[i] = std::move(std::any_cast<info::definition::Parameter>(current_info_));
|
|
current_info_.reset();
|
|
}
|
|
|
|
for (size_t i = 0; i < node->requirements.size(); ++i) {
|
|
namespace_visitor_.AddEnterNamespace(typeclass_name, node->requirements[i].first, std::nullopt, node->base);
|
|
Visit(node->requirements[i].second.get());
|
|
namespace_visitor_.ExitNamespace();
|
|
}
|
|
|
|
info.node = node;
|
|
info.parent_namespace = namespace_visitor_.GetCurrentNamespaceId();
|
|
|
|
node->typeclass_id_ = namespace_visitor_.AddTypeclass(typeclass_name, std::move(info), node->base);
|
|
|
|
// no need to visit definition->type, because it is typeclass
|
|
}
|
|
|
|
void FindSymbolsVisitor::Visit(PartitionStatement* node) {
|
|
node->executable_id_ = namespace_visitor_.AddPartition(node->name.path, node, node->base);
|
|
|
|
Visitor::Visit(node->value); // to visit all tree
|
|
}
|
|
|
|
// Definition parts
|
|
|
|
void FindSymbolsVisitor::Visit(AnyAnnotatedType* node) {
|
|
info::definition::Parameter info;
|
|
|
|
info.type = node->type;
|
|
|
|
info.typeclass_nodes.resize(node->typeclasses.size());
|
|
for (size_t i = 0; i < node->typeclasses.size(); ++i) {
|
|
info.typeclass_nodes[i] = node->typeclasses[i].get();
|
|
}
|
|
|
|
for (auto& typeclass : node->typeclasses) {
|
|
Visitor::Visit(typeclass.get()); // to visit all tree
|
|
}
|
|
|
|
info.node = node;
|
|
|
|
auto maybe_typeclass_graph_id = namespace_visitor_.GetGlobalInfo()->AddAnnotatedTypeToGraph(node); // definitions and declarations should be added latter
|
|
|
|
if (!maybe_typeclass_graph_id.has_value()) {
|
|
error_handling::HandleInternalError("Can't add annotated type to typeclass graph",
|
|
"FindSymbolsVisitor.AnyAnnotatedType",
|
|
&node->base);
|
|
}
|
|
|
|
node->graph_id_ = maybe_typeclass_graph_id.value();
|
|
|
|
current_info_ = std::move(info);
|
|
}
|
|
|
|
} // namespace interpreter
|