mirror of
https://codeberg.org/ProgramSnail/lang_2023.git
synced 2025-12-06 06:58:45 +00:00
adding types to typeclass tree, part 1
This commit is contained in:
parent
17328b842c
commit
d841e2754b
7 changed files with 260 additions and 167 deletions
|
|
@ -350,19 +350,19 @@ public:
|
|||
return &typeclass_graph_;
|
||||
}
|
||||
|
||||
std::unordered_set<utils::IdType>
|
||||
GetAnnotatedTypeTypeclassesSet(interpreter::tokens::AnnotatedType* node);
|
||||
|
||||
std::vector<utils::IdType>
|
||||
GetAnnotatedTypeTypeclassesVector(interpreter::tokens::AnnotatedType* node);
|
||||
|
||||
std::unordered_map<std::string, TypeclassGraph::FunctionInfo>
|
||||
GetAnnotatedTypeFunctionsMap(interpreter::tokens::AnnotatedType* node,
|
||||
const interpreter::tokens::BaseNode& base_node);
|
||||
|
||||
std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo>>
|
||||
GetAnnotatedTypeFunctionsVector(interpreter::tokens::AnnotatedType* node,
|
||||
const interpreter::tokens::BaseNode& base_node);
|
||||
// std::unordered_set<utils::IdType>
|
||||
// GetAnnotatedTypeTypeclassesSet(interpreter::tokens::AnnotatedType* node);
|
||||
//
|
||||
// std::vector<utils::IdType>
|
||||
// GetAnnotatedTypeTypeclassesVector(interpreter::tokens::AnnotatedType* node);
|
||||
//
|
||||
// std::unordered_map<std::string, TypeclassGraph::FunctionInfo>
|
||||
// GetAnnotatedTypeFunctionsMap(interpreter::tokens::AnnotatedType* node,
|
||||
// const interpreter::tokens::BaseNode& base_node);
|
||||
//
|
||||
// std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo>>
|
||||
// GetAnnotatedTypeFunctionsVector(interpreter::tokens::AnnotatedType* node,
|
||||
// const interpreter::tokens::BaseNode& base_node);
|
||||
|
||||
std::unordered_map<std::string, utils::IdType>* ChooseNamespaces(
|
||||
utils::ClassInternalsModifier modifier,
|
||||
|
|
@ -370,6 +370,9 @@ public:
|
|||
|
||||
std::optional<utils::IdType> AddTypeclassToGraph(utils::IdType typeclass);
|
||||
|
||||
// function declarations & definitions should be added latter
|
||||
std::optional<utils::IdType> AddAnnotatedTypeToGraph(interpreter::tokens::AnnotatedType* node);
|
||||
|
||||
private:
|
||||
void CollectFunctionInfo(
|
||||
utils::IdType current_namespace,
|
||||
|
|
|
|||
|
|
@ -17,9 +17,7 @@ public:
|
|||
|
||||
void VisitSourceFile(SourceFile* source_file) override {
|
||||
Visitor::Visit(source_file);
|
||||
if (!namespace_visitor_.GetTypeclassGraph()->CalculateGraph()) {
|
||||
error_handling::HandleInternalError("Can't calculate typeclass graph", "LinkSymbolsVisitor.VisitSourceFile");
|
||||
}
|
||||
namespace_visitor_.GetTypeclassGraph()->CalculateGraph();
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -39,7 +37,7 @@ private:
|
|||
// // void Visit(VariableDefinitionStatement* node) override;
|
||||
// // void Visit(FunctionDeclaration* node) override;
|
||||
// // void Visit(FunctionDefinitionStatement* node) override;
|
||||
// // void Visit(TypeDefinitionStatement* node) override;
|
||||
void Visit(TypeDefinitionStatement* node) override;
|
||||
// // void Visit(AbstractTypeDefinitionStatement* node) override;
|
||||
void Visit(TypeclassDefinitionStatement* node) override;
|
||||
// // void Visit(PartitionStatement* node) override;
|
||||
|
|
|
|||
|
|
@ -12,57 +12,77 @@
|
|||
|
||||
namespace info {
|
||||
|
||||
// move constructor parameters ??
|
||||
class TypeclassGraph {
|
||||
public:
|
||||
enum class Modifier {
|
||||
Typeclass = 0,
|
||||
Type = 1,
|
||||
};
|
||||
|
||||
struct FunctionInfo {
|
||||
utils::ClassInternalsModifier modifier = utils::ClassInternalsModifier::Static;
|
||||
interpreter::tokens::FunctionDeclaration* declaration = nullptr;
|
||||
std::optional<interpreter::tokens::FunctionDefinitionStatement*> definition;
|
||||
bool is_defined_in_owner = false;
|
||||
};
|
||||
|
||||
struct TypeclassVertex {
|
||||
struct Vertex { // make constructor ??
|
||||
std::string name;
|
||||
interpreter::tokens::TypeclassDefinitionStatement* definition = nullptr;
|
||||
std::unordered_map<std::string, FunctionInfo> functions;
|
||||
std::unordered_set<std::string> dependencies; // TODO: parameters
|
||||
interpreter::tokens::BaseNode* base_node; // for error handling
|
||||
Modifier modifier;
|
||||
};
|
||||
|
||||
std::optional<utils::IdType> AddTypeclass( // move parameters ??
|
||||
utils::IdType AddVertex(
|
||||
const std::string& name,
|
||||
interpreter::tokens::TypeclassDefinitionStatement* definition,
|
||||
const std::vector<std::string>& dependencies, // TODO: parameters
|
||||
const std::vector<std::string>& dependencies,
|
||||
const std::vector<std::pair<std::string, std::pair<utils::ClassInternalsModifier, interpreter::tokens::FunctionDeclaration*>>>& function_declarations,
|
||||
const std::vector<std::pair<std::string, interpreter::tokens::FunctionDefinitionStatement*>>& function_definitions);
|
||||
const std::vector<std::pair<std::string, interpreter::tokens::FunctionDefinitionStatement*>>& function_definitions,
|
||||
interpreter::tokens::BaseNode* base_node,
|
||||
Modifier modifier);
|
||||
|
||||
std::optional<utils::IdType> FindFunctionTypeclass(const std::string& name);
|
||||
|
||||
bool IsFunctionInTypeclass(const std::string& name, utils::IdType typeclass_id) {
|
||||
return typeclasses_[typeclass_id].functions.count(name) != 0;
|
||||
bool IsFunctionInVertex(const std::string& name, utils::IdType vertex_id) {
|
||||
return verticles_[vertex_id].functions.count(name) != 0;
|
||||
}
|
||||
|
||||
// if vertex_id == std::nullopt, info can be not complete
|
||||
std::optional<FunctionInfo*> GetFunctionInfo(const std::string& name,
|
||||
std::optional<utils::IdType> typeclass_id);
|
||||
std::optional<utils::IdType> vertex_id);
|
||||
|
||||
const TypeclassVertex& GetTypeclass(utils::IdType typeclass_id) { // check, if calculated ??
|
||||
return typeclasses_.at(typeclass_id);
|
||||
const Vertex& GetVertex(utils::IdType id) {
|
||||
return verticles_.at(id);
|
||||
}
|
||||
|
||||
std::optional<Vertex*> GetTypeVertex(utils::IdType id) {
|
||||
if (verticles_.at(id).modifier == Modifier::Type) {
|
||||
return &verticles_[id];
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// cache ??
|
||||
std::vector<utils::IdType> GetTypeclassDependencies(utils::IdType id);
|
||||
std::unordered_set<utils::IdType> GetDependenciesSet(utils::IdType id);
|
||||
std::vector<utils::IdType> GetDependenciesVector(utils::IdType id);
|
||||
|
||||
// cache ??
|
||||
std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo*>> GetTypeclassFunctions(utils::IdType id);
|
||||
const std::unordered_map<std::string, FunctionInfo>& GetVertexFunctions(utils::IdType id) {
|
||||
return verticles_.at(id).functions;
|
||||
}
|
||||
|
||||
bool IsCalculated() {
|
||||
return is_calculated_;
|
||||
}
|
||||
|
||||
bool CalculateGraph();
|
||||
// can exit by typecheck error
|
||||
void CalculateGraph();
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, utils::IdType> method_to_typeclass_;
|
||||
std::unordered_map<std::string, utils::IdType> method_to_vertex_;
|
||||
std::unordered_map<std::string, utils::IdType> name_to_typeclass_;
|
||||
std::vector<TypeclassVertex> typeclasses_;
|
||||
std::vector<Vertex> verticles_;
|
||||
|
||||
bool is_calculated_ = true;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@ void FindSymbolsVisitor::Visit(AliasDefinitionStatement* 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) {
|
||||
|
|
@ -69,6 +71,8 @@ void FindSymbolsVisitor::Visit(FunctionDeclaration* node) {
|
|||
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) {
|
||||
|
|
@ -84,6 +88,9 @@ void FindSymbolsVisitor::Visit(FunctionDefinitionStatement* node) {
|
|||
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) {
|
||||
|
|
@ -113,6 +120,9 @@ void FindSymbolsVisitor::Visit(TypeDefinitionStatement* node) {
|
|||
info.type = std::move(any_type_info);
|
||||
|
||||
node->type_id_ = namespace_visitor_.AddType(type, std::move(info), node->base);
|
||||
|
||||
// definition visited earlier
|
||||
Visitor::Visit(node->value); // to visit all tree
|
||||
}
|
||||
|
||||
void FindSymbolsVisitor::Visit(AbstractTypeDefinitionStatement* node) {
|
||||
|
|
@ -153,10 +163,14 @@ void FindSymbolsVisitor::Visit(TypeclassDefinitionStatement* 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
|
||||
|
|
@ -171,8 +185,19 @@ void FindSymbolsVisitor::Visit(AnyAnnotatedType* node) {
|
|||
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_graph_id = namespace_visitor_.GetGlobalInfo()->AddAnnotatedTypeToGraph(node); // definitions and declarations should be added latter
|
||||
|
||||
if (!maybe_graph_id.has_value()) {
|
||||
error_handling::HandleInternalError("Can't add annotated type to typeclass graph",
|
||||
"FindSymbolsVisitor.AnyAnnotatedType");
|
||||
}
|
||||
|
||||
current_info_ = std::move(info);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -460,79 +460,79 @@ std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindNamespaceIn(
|
|||
|
||||
//
|
||||
|
||||
// cache ??
|
||||
std::unordered_set<utils::IdType>
|
||||
GlobalInfo::GetAnnotatedTypeTypeclassesSet(interpreter::tokens::AnnotatedType* node) {
|
||||
|
||||
std::unordered_set<utils::IdType> typeclasses;
|
||||
|
||||
for (auto& typeclass : node->typeclasses) {
|
||||
utils::IdType graph_id = typeclasses_[typeclass->typeclass_id_].graph_id_;
|
||||
|
||||
std::vector<utils::IdType> dependencies = typeclass_graph_.GetTypeclassDependencies(graph_id);
|
||||
for (auto& dependency : dependencies) {
|
||||
typeclasses.insert(dependency);
|
||||
}
|
||||
|
||||
typeclasses.insert(graph_id);
|
||||
}
|
||||
return typeclasses;
|
||||
}
|
||||
|
||||
std::vector<utils::IdType>
|
||||
GlobalInfo::GetAnnotatedTypeTypeclassesVector(interpreter::tokens::AnnotatedType* node) {
|
||||
|
||||
std::unordered_set<utils::IdType> typeclasses_set = GetAnnotatedTypeTypeclassesSet(node);
|
||||
|
||||
std::vector<utils::IdType> typeclasses_vector;
|
||||
typeclasses_vector.reserve(typeclasses_vector.size());
|
||||
for (auto& typeclass : typeclasses_set) {
|
||||
typeclasses_vector.push_back(typeclass);
|
||||
}
|
||||
return typeclasses_vector;
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, TypeclassGraph::FunctionInfo> // TODO: optimize, cache
|
||||
GlobalInfo::GetAnnotatedTypeFunctionsMap(interpreter::tokens::AnnotatedType* node,
|
||||
const interpreter::tokens::BaseNode& base_node) {
|
||||
|
||||
std::unordered_map<std::string, TypeclassGraph::FunctionInfo> functions;
|
||||
|
||||
for (auto& typeclass : node->typeclasses) {
|
||||
utils::IdType graph_id = typeclasses_[typeclass->typeclass_id_].graph_id_;
|
||||
|
||||
auto requirements = typeclass_graph_.GetTypeclassFunctions(graph_id);
|
||||
for (auto& requirement : requirements) {
|
||||
auto requirement_iter = functions.find(requirement.first);
|
||||
if (requirement_iter == functions.end()) {
|
||||
functions[requirement.first] = *requirement.second;
|
||||
} else {
|
||||
if (requirement_iter->second.definition.has_value()) {
|
||||
if (requirement.second->definition.has_value()) {
|
||||
error_handling::HandleTypecheckError("Function defined more then in one type requirement", base_node);
|
||||
}
|
||||
} else {
|
||||
requirement_iter->second.definition = requirement.second->definition;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return functions;
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo>> // TODO: optimize, cache
|
||||
GlobalInfo::GetAnnotatedTypeFunctionsVector(interpreter::tokens::AnnotatedType* node,
|
||||
const interpreter::tokens::BaseNode& base_node) {
|
||||
|
||||
auto functions_set = GetAnnotatedTypeFunctionsMap(node, base_node);
|
||||
|
||||
std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo>> functions_vector;
|
||||
functions_vector.reserve(functions_vector.size());
|
||||
for (auto& typeclass : functions_set) {
|
||||
functions_vector.push_back(typeclass);
|
||||
}
|
||||
return functions_vector;
|
||||
}
|
||||
// // cache ??
|
||||
// std::unordered_set<utils::IdType>
|
||||
// GlobalInfo::GetAnnotatedTypeTypeclassesSet(interpreter::tokens::AnnotatedType* node) {
|
||||
//
|
||||
// std::unordered_set<utils::IdType> typeclasses;
|
||||
//
|
||||
// for (auto& typeclass : node->typeclasses) {
|
||||
// utils::IdType graph_id = typeclasses_[typeclass->typeclass_id_].graph_id_;
|
||||
//
|
||||
// std::vector<utils::IdType> dependencies = typeclass_graph_.GetTypeclassDependencies(graph_id);
|
||||
// for (auto& dependency : dependencies) {
|
||||
// typeclasses.insert(dependency);
|
||||
// }
|
||||
//
|
||||
// typeclasses.insert(graph_id);
|
||||
// }
|
||||
// return typeclasses;
|
||||
// }
|
||||
//
|
||||
// std::vector<utils::IdType>
|
||||
// GlobalInfo::GetAnnotatedTypeTypeclassesVector(interpreter::tokens::AnnotatedType* node) {
|
||||
//
|
||||
// std::unordered_set<utils::IdType> typeclasses_set = GetAnnotatedTypeTypeclassesSet(node);
|
||||
//
|
||||
// std::vector<utils::IdType> typeclasses_vector;
|
||||
// typeclasses_vector.reserve(typeclasses_vector.size());
|
||||
// for (auto& typeclass : typeclasses_set) {
|
||||
// typeclasses_vector.push_back(typeclass);
|
||||
// }
|
||||
// return typeclasses_vector;
|
||||
// }
|
||||
//
|
||||
// std::unordered_map<std::string, TypeclassGraph::FunctionInfo> // TODO: optimize, cache
|
||||
// GlobalInfo::GetAnnotatedTypeFunctionsMap(interpreter::tokens::AnnotatedType* node,
|
||||
// const interpreter::tokens::BaseNode& base_node) {
|
||||
//
|
||||
// std::unordered_map<std::string, TypeclassGraph::FunctionInfo> functions;
|
||||
//
|
||||
// for (auto& typeclass : node->typeclasses) {
|
||||
// utils::IdType graph_id = typeclasses_[typeclass->typeclass_id_].graph_id_;
|
||||
//
|
||||
// auto requirements = typeclass_graph_.GetTypeclassFunctions(graph_id);
|
||||
// for (auto& requirement : requirements) {
|
||||
// auto requirement_iter = functions.find(requirement.first);
|
||||
// if (requirement_iter == functions.end()) {
|
||||
// functions[requirement.first] = *requirement.second;
|
||||
// } else {
|
||||
// if (requirement_iter->second.definition.has_value()) {
|
||||
// if (requirement.second->definition.has_value()) {
|
||||
// error_handling::HandleTypecheckError("Function defined more then in one type requirement", base_node);
|
||||
// }
|
||||
// } else {
|
||||
// requirement_iter->second.definition = requirement.second->definition;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return functions;
|
||||
// }
|
||||
//
|
||||
// std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo>> // TODO: optimize, cache
|
||||
// GlobalInfo::GetAnnotatedTypeFunctionsVector(interpreter::tokens::AnnotatedType* node,
|
||||
// const interpreter::tokens::BaseNode& base_node) {
|
||||
//
|
||||
// auto functions_set = GetAnnotatedTypeFunctionsMap(node, base_node);
|
||||
//
|
||||
// std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo>> functions_vector;
|
||||
// functions_vector.reserve(functions_vector.size());
|
||||
// for (auto& typeclass : functions_set) {
|
||||
// functions_vector.push_back(typeclass);
|
||||
// }
|
||||
// return functions_vector;
|
||||
// }
|
||||
|
||||
std::unordered_map<std::string, utils::IdType>*
|
||||
GlobalInfo::ChooseNamespaces(utils::ClassInternalsModifier modifier,
|
||||
|
|
@ -558,6 +558,7 @@ std::optional<utils::IdType> GlobalInfo::AddTypeclassToGraph(utils::IdType typec
|
|||
definition::Namespace* parent_namespace = &GetNamespaceInfo(typeclass_info->parent_namespace);
|
||||
|
||||
std::string name = typeclass_info->node->definition->type->type;
|
||||
interpreter::tokens::BaseNode* base_node = &typeclass_info->node->base;
|
||||
std::vector<std::string> dependencies;
|
||||
std::vector<std::pair<std::string, std::pair<utils::ClassInternalsModifier, interpreter::tokens::FunctionDeclaration*>>> function_declarations;
|
||||
std::vector<std::pair<std::string, interpreter::tokens::FunctionDefinitionStatement*>> function_definitions;
|
||||
|
|
@ -566,7 +567,7 @@ std::optional<utils::IdType> GlobalInfo::AddTypeclassToGraph(utils::IdType typec
|
|||
std::string dependency = dependency_node->typeclass;
|
||||
if (dependency_node->parameters.size() > 0) {
|
||||
error_handling::HandleInternalError("Paramtrized typeclass requirements are not implemented yet",
|
||||
"TypeclassGraph.AddTypeclassByNode");
|
||||
"GlobalInfo.AddTypeclassToGraph");
|
||||
}
|
||||
dependencies.push_back(dependency);
|
||||
}
|
||||
|
|
@ -595,11 +596,34 @@ std::optional<utils::IdType> GlobalInfo::AddTypeclassToGraph(utils::IdType typec
|
|||
function_definitions);
|
||||
}
|
||||
|
||||
return typeclass_graph_.AddTypeclass(name,
|
||||
typeclass_info->node,
|
||||
return typeclass_graph_.AddVertex(name,
|
||||
dependencies,
|
||||
function_declarations,
|
||||
function_definitions);
|
||||
function_definitions,
|
||||
base_node,
|
||||
TypeclassGraph::Modifier::Typeclass);
|
||||
}
|
||||
|
||||
std::optional<utils::IdType> GlobalInfo::AddAnnotatedTypeToGraph(interpreter::tokens::AnnotatedType* node) {
|
||||
std::string name = node->type;
|
||||
interpreter::tokens::BaseNode* base_node = &node->base;
|
||||
std::vector<std::string> dependencies;
|
||||
|
||||
for (auto& dependency_node : node->typeclasses) {
|
||||
std::string dependency = dependency_node->typeclass;
|
||||
if (dependency_node->parameters.size() > 0) {
|
||||
error_handling::HandleInternalError("Paramtrized typeclass requirements are not implemented yet",
|
||||
"GlobalInfo.AddAnnotatedTypeToGraph");
|
||||
}
|
||||
dependencies.push_back(dependency);
|
||||
}
|
||||
|
||||
return typeclass_graph_.AddVertex(name,
|
||||
dependencies,
|
||||
{},
|
||||
{},
|
||||
base_node,
|
||||
TypeclassGraph::Modifier::Type);
|
||||
}
|
||||
|
||||
void GlobalInfo::CollectFunctionInfo(
|
||||
|
|
|
|||
|
|
@ -47,6 +47,13 @@ void LinkSymbolsVisitor::Visit(Namespace* node) {
|
|||
|
||||
// Definitions -----------------
|
||||
|
||||
void LinkSymbolsVisitor::Visit(TypeDefinitionStatement* node) {
|
||||
Visitor::Visit(node->definition.get());
|
||||
Visitor::Visit(node->value);
|
||||
|
||||
// TODO: add type declarations / definitions
|
||||
}
|
||||
|
||||
void LinkSymbolsVisitor::Visit(TypeclassDefinitionStatement* node) {
|
||||
Visitor::Visit(node->definition.get());
|
||||
for (auto& function_requirement : node->requirements) {
|
||||
|
|
|
|||
|
|
@ -1,31 +1,41 @@
|
|||
// for clangd
|
||||
#include "../include/typeclass_graph.hpp"
|
||||
#include "../include/error_handling.hpp"
|
||||
|
||||
namespace info {
|
||||
|
||||
std::optional<utils::IdType> TypeclassGraph::AddTypeclass(
|
||||
utils::IdType TypeclassGraph::AddVertex(
|
||||
const std::string& name,
|
||||
interpreter::tokens::TypeclassDefinitionStatement* definition,
|
||||
const std::vector<std::string>& dependencies, // TODO: parameters
|
||||
const std::vector<std::pair<std::string, std::pair<utils::ClassInternalsModifier, interpreter::tokens::FunctionDeclaration*>>>& function_declarations,
|
||||
const std::vector<std::pair<std::string, interpreter::tokens::FunctionDefinitionStatement*>>& function_definitions) {
|
||||
const std::vector<std::pair<std::string, interpreter::tokens::FunctionDefinitionStatement*>>& function_definitions,
|
||||
interpreter::tokens::BaseNode* base_node,
|
||||
Modifier modifier) {
|
||||
|
||||
if (name_to_typeclass_.count(name) != 0) {
|
||||
error_handling::HandleTypecheckError("Typeclass \"" + name + "\" already defined (other type / typeclass can't have this name)", *base_node);
|
||||
}
|
||||
|
||||
if (modifier == Modifier::Typeclass) {
|
||||
for (auto& method : function_declarations) {
|
||||
if (method_to_typeclass_.count(method.first) != 0) {
|
||||
return std::nullopt;
|
||||
if (method_to_vertex_.count(method.first) != 0) {
|
||||
error_handling::HandleTypecheckError("Typeclass \"" + name + "\" method \"" + method.first + "\" already declaret in another typeclass", *base_node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
is_calculated_ = false;
|
||||
|
||||
utils::IdType id = typeclasses_.size();
|
||||
utils::IdType id = verticles_.size();
|
||||
|
||||
typeclasses_.emplace_back();
|
||||
TypeclassVertex& typeclass = typeclasses_.back();
|
||||
typeclass.name = name;
|
||||
typeclass.definition = definition;
|
||||
verticles_.emplace_back();
|
||||
Vertex& vertex = verticles_.back();
|
||||
vertex.name = name;
|
||||
vertex.base_node = base_node;
|
||||
vertex.modifier = modifier;
|
||||
|
||||
for (auto& dependency : dependencies) {
|
||||
typeclass.dependencies.insert(dependency);
|
||||
vertex.dependencies.insert(dependency);
|
||||
}
|
||||
|
||||
for (auto& method : function_declarations) {
|
||||
|
|
@ -33,31 +43,37 @@ std::optional<utils::IdType> TypeclassGraph::AddTypeclass(
|
|||
function_info.modifier = method.second.first;
|
||||
function_info.declaration = method.second.second;
|
||||
|
||||
typeclass.functions[method.first] = function_info;
|
||||
vertex.functions[method.first] = function_info;
|
||||
|
||||
method_to_typeclass_[method.first] = id;
|
||||
if (modifier == Modifier::Typeclass) {
|
||||
method_to_vertex_[method.first] = id;
|
||||
}
|
||||
}
|
||||
if (modifier == Modifier::Typeclass) {
|
||||
name_to_typeclass_[name] = id;
|
||||
}
|
||||
|
||||
for (auto& method : function_definitions) {
|
||||
typeclass.functions[method.first].definition = method.second;
|
||||
FunctionInfo& function_info = vertex.functions[method.first];
|
||||
function_info.definition = method.second;
|
||||
function_info.is_defined_in_owner = true;
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
std::optional<utils::IdType> TypeclassGraph::FindFunctionTypeclass(const std::string& name) {
|
||||
auto function_iter = method_to_typeclass_.find(name);
|
||||
if (function_iter == method_to_typeclass_.end()) {
|
||||
auto function_iter = method_to_vertex_.find(name);
|
||||
if (function_iter == method_to_vertex_.end()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return function_iter->second;
|
||||
}
|
||||
|
||||
std::optional<TypeclassGraph::FunctionInfo*> TypeclassGraph::GetFunctionInfo(const std::string& name,
|
||||
std::optional<utils::IdType> typeclass_id) {
|
||||
if (typeclass_id.has_value()) {
|
||||
return &typeclasses_[typeclass_id.value()].functions[name];
|
||||
std::optional<utils::IdType> vertex_id) {
|
||||
if (vertex_id.has_value()) {
|
||||
return &verticles_[vertex_id.value()].functions[name];
|
||||
}
|
||||
|
||||
auto maybe_function_typeclass_id = FindFunctionTypeclass(name);
|
||||
|
|
@ -66,47 +82,45 @@ std::optional<TypeclassGraph::FunctionInfo*> TypeclassGraph::GetFunctionInfo(con
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
return &typeclasses_[maybe_function_typeclass_id.value()].functions[name];
|
||||
return &verticles_[maybe_function_typeclass_id.value()].functions[name];
|
||||
}
|
||||
|
||||
// cache ??
|
||||
std::vector<utils::IdType> TypeclassGraph::GetTypeclassDependencies(utils::IdType id) {
|
||||
std::unordered_set<utils::IdType> TypeclassGraph::GetDependenciesSet(utils::IdType id) {
|
||||
std::unordered_set<utils::IdType> dependencies;
|
||||
|
||||
dependencies.reserve(verticles_.at(id).dependencies.size());
|
||||
for (auto& dependency : verticles_[id].dependencies) {
|
||||
dependencies.insert(name_to_typeclass_[dependency]);
|
||||
}
|
||||
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
std::vector<utils::IdType> TypeclassGraph::GetDependenciesVector(utils::IdType id) {
|
||||
std::vector<utils::IdType> dependencies;
|
||||
|
||||
dependencies.reserve(typeclasses_.at(id).dependencies.size());
|
||||
for (auto& dependency : typeclasses_[id].dependencies) {
|
||||
dependencies.reserve(verticles_.at(id).dependencies.size());
|
||||
for (auto& dependency : verticles_[id].dependencies) {
|
||||
dependencies.push_back(name_to_typeclass_[dependency]);
|
||||
}
|
||||
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
// cache ??
|
||||
std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo*>> TypeclassGraph::GetTypeclassFunctions(utils::IdType id) {
|
||||
std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo*>> functions;
|
||||
|
||||
functions.reserve(typeclasses_.at(id).functions.size());
|
||||
for (auto& function : typeclasses_[id].functions) {
|
||||
functions.push_back({function.first, &function.second});
|
||||
}
|
||||
|
||||
return functions;
|
||||
}
|
||||
|
||||
bool TypeclassGraph::CalculateGraph() {
|
||||
void TypeclassGraph::CalculateGraph() {
|
||||
if (is_calculated_) {
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::vector<size_t>> edges(typeclasses_.size());
|
||||
std::vector<std::vector<size_t>> edges(verticles_.size());
|
||||
|
||||
for (size_t i = 0; i < typeclasses_.size(); ++i) {
|
||||
edges[i].reserve(typeclasses_[i].dependencies.size());
|
||||
for (auto& dependency :typeclasses_[i].dependencies) {
|
||||
for (size_t i = 0; i < verticles_.size(); ++i) {
|
||||
edges[i].reserve(verticles_[i].dependencies.size());
|
||||
for (auto& dependency : verticles_[i].dependencies) {
|
||||
auto dependency_iter = name_to_typeclass_.find(dependency);
|
||||
|
||||
if (dependency_iter == name_to_typeclass_.end()) {
|
||||
return false;
|
||||
error_handling::HandleTypecheckError("Dependency typeclass \"" + dependency + "\" not found", *verticles_[i].base_node);
|
||||
}
|
||||
|
||||
edges[i].push_back(dependency_iter->second);
|
||||
|
|
@ -117,26 +131,28 @@ bool TypeclassGraph::CalculateGraph() {
|
|||
std::reverse(sorted_verticles.begin(), sorted_verticles.end());
|
||||
|
||||
for (auto& id : sorted_verticles) {
|
||||
for (auto& dependency : typeclasses_[id].dependencies) {
|
||||
for (auto& method : typeclasses_[name_to_typeclass_[dependency]].functions) {
|
||||
auto function_iter = typeclasses_[id].functions.find(method.first);
|
||||
if (function_iter == typeclasses_[id].functions.end()) {
|
||||
typeclasses_[id].functions[method.first] = method.second;
|
||||
for (auto& dependency : verticles_[id].dependencies) {
|
||||
for (auto& method : verticles_[name_to_typeclass_[dependency]].functions) {
|
||||
auto function_iter = verticles_[id].functions.find(method.first);
|
||||
if (function_iter == verticles_[id].functions.end()) {
|
||||
verticles_[id].functions[method.first] = method.second;
|
||||
} else {
|
||||
if (!function_iter->second.definition.has_value()) {
|
||||
function_iter->second.definition = method.second.definition;
|
||||
} else {
|
||||
if (!function_iter->second.is_defined_in_owner) {
|
||||
error_handling::HandleTypecheckError("Method \"" + method.first + "\" defined in more then one dependency of type / typeclass \"" + verticles_[id].name + "\"", *verticles_[id].base_node);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto& inherited_dependency : typeclasses_[name_to_typeclass_[dependency]].dependencies) {
|
||||
typeclasses_[id].dependencies.insert(inherited_dependency);
|
||||
}
|
||||
for (auto& inherited_dependency : verticles_[method_to_vertex_[dependency]].dependencies) {
|
||||
verticles_[id].dependencies.insert(inherited_dependency);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
is_calculated_ = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace info
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue