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_;
|
return &typeclass_graph_;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unordered_set<utils::IdType>
|
// std::unordered_set<utils::IdType>
|
||||||
GetAnnotatedTypeTypeclassesSet(interpreter::tokens::AnnotatedType* node);
|
// GetAnnotatedTypeTypeclassesSet(interpreter::tokens::AnnotatedType* node);
|
||||||
|
//
|
||||||
std::vector<utils::IdType>
|
// std::vector<utils::IdType>
|
||||||
GetAnnotatedTypeTypeclassesVector(interpreter::tokens::AnnotatedType* node);
|
// GetAnnotatedTypeTypeclassesVector(interpreter::tokens::AnnotatedType* node);
|
||||||
|
//
|
||||||
std::unordered_map<std::string, TypeclassGraph::FunctionInfo>
|
// std::unordered_map<std::string, TypeclassGraph::FunctionInfo>
|
||||||
GetAnnotatedTypeFunctionsMap(interpreter::tokens::AnnotatedType* node,
|
// GetAnnotatedTypeFunctionsMap(interpreter::tokens::AnnotatedType* node,
|
||||||
const interpreter::tokens::BaseNode& base_node);
|
// const interpreter::tokens::BaseNode& base_node);
|
||||||
|
//
|
||||||
std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo>>
|
// std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo>>
|
||||||
GetAnnotatedTypeFunctionsVector(interpreter::tokens::AnnotatedType* node,
|
// GetAnnotatedTypeFunctionsVector(interpreter::tokens::AnnotatedType* node,
|
||||||
const interpreter::tokens::BaseNode& base_node);
|
// const interpreter::tokens::BaseNode& base_node);
|
||||||
|
|
||||||
std::unordered_map<std::string, utils::IdType>* ChooseNamespaces(
|
std::unordered_map<std::string, utils::IdType>* ChooseNamespaces(
|
||||||
utils::ClassInternalsModifier modifier,
|
utils::ClassInternalsModifier modifier,
|
||||||
|
|
@ -370,6 +370,9 @@ public:
|
||||||
|
|
||||||
std::optional<utils::IdType> AddTypeclassToGraph(utils::IdType typeclass);
|
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:
|
private:
|
||||||
void CollectFunctionInfo(
|
void CollectFunctionInfo(
|
||||||
utils::IdType current_namespace,
|
utils::IdType current_namespace,
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,7 @@ public:
|
||||||
|
|
||||||
void VisitSourceFile(SourceFile* source_file) override {
|
void VisitSourceFile(SourceFile* source_file) override {
|
||||||
Visitor::Visit(source_file);
|
Visitor::Visit(source_file);
|
||||||
if (!namespace_visitor_.GetTypeclassGraph()->CalculateGraph()) {
|
namespace_visitor_.GetTypeclassGraph()->CalculateGraph();
|
||||||
error_handling::HandleInternalError("Can't calculate typeclass graph", "LinkSymbolsVisitor.VisitSourceFile");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -39,7 +37,7 @@ private:
|
||||||
// // void Visit(VariableDefinitionStatement* node) override;
|
// // void Visit(VariableDefinitionStatement* node) override;
|
||||||
// // void Visit(FunctionDeclaration* node) override;
|
// // void Visit(FunctionDeclaration* node) override;
|
||||||
// // void Visit(FunctionDefinitionStatement* node) override;
|
// // void Visit(FunctionDefinitionStatement* node) override;
|
||||||
// // void Visit(TypeDefinitionStatement* node) override;
|
void Visit(TypeDefinitionStatement* node) override;
|
||||||
// // void Visit(AbstractTypeDefinitionStatement* node) override;
|
// // void Visit(AbstractTypeDefinitionStatement* node) override;
|
||||||
void Visit(TypeclassDefinitionStatement* node) override;
|
void Visit(TypeclassDefinitionStatement* node) override;
|
||||||
// // void Visit(PartitionStatement* node) override;
|
// // void Visit(PartitionStatement* node) override;
|
||||||
|
|
|
||||||
|
|
@ -12,57 +12,77 @@
|
||||||
|
|
||||||
namespace info {
|
namespace info {
|
||||||
|
|
||||||
|
// move constructor parameters ??
|
||||||
class TypeclassGraph {
|
class TypeclassGraph {
|
||||||
public:
|
public:
|
||||||
|
enum class Modifier {
|
||||||
|
Typeclass = 0,
|
||||||
|
Type = 1,
|
||||||
|
};
|
||||||
|
|
||||||
struct FunctionInfo {
|
struct FunctionInfo {
|
||||||
utils::ClassInternalsModifier modifier = utils::ClassInternalsModifier::Static;
|
utils::ClassInternalsModifier modifier = utils::ClassInternalsModifier::Static;
|
||||||
interpreter::tokens::FunctionDeclaration* declaration = nullptr;
|
interpreter::tokens::FunctionDeclaration* declaration = nullptr;
|
||||||
std::optional<interpreter::tokens::FunctionDefinitionStatement*> definition;
|
std::optional<interpreter::tokens::FunctionDefinitionStatement*> definition;
|
||||||
|
bool is_defined_in_owner = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TypeclassVertex {
|
struct Vertex { // make constructor ??
|
||||||
std::string name;
|
std::string name;
|
||||||
interpreter::tokens::TypeclassDefinitionStatement* definition = nullptr;
|
|
||||||
std::unordered_map<std::string, FunctionInfo> functions;
|
std::unordered_map<std::string, FunctionInfo> functions;
|
||||||
std::unordered_set<std::string> dependencies; // TODO: parameters
|
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,
|
const std::string& name,
|
||||||
interpreter::tokens::TypeclassDefinitionStatement* definition,
|
const std::vector<std::string>& dependencies,
|
||||||
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, 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);
|
std::optional<utils::IdType> FindFunctionTypeclass(const std::string& name);
|
||||||
|
|
||||||
bool IsFunctionInTypeclass(const std::string& name, utils::IdType typeclass_id) {
|
bool IsFunctionInVertex(const std::string& name, utils::IdType vertex_id) {
|
||||||
return typeclasses_[typeclass_id].functions.count(name) != 0;
|
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<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 ??
|
const Vertex& GetVertex(utils::IdType id) {
|
||||||
return typeclasses_.at(typeclass_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 ??
|
// 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 ??
|
const std::unordered_map<std::string, FunctionInfo>& GetVertexFunctions(utils::IdType id) {
|
||||||
std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo*>> GetTypeclassFunctions(utils::IdType id);
|
return verticles_.at(id).functions;
|
||||||
|
}
|
||||||
|
|
||||||
bool IsCalculated() {
|
bool IsCalculated() {
|
||||||
return is_calculated_;
|
return is_calculated_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CalculateGraph();
|
// can exit by typecheck error
|
||||||
|
void CalculateGraph();
|
||||||
|
|
||||||
private:
|
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::unordered_map<std::string, utils::IdType> name_to_typeclass_;
|
||||||
std::vector<TypeclassVertex> typeclasses_;
|
std::vector<Vertex> verticles_;
|
||||||
|
|
||||||
bool is_calculated_ = true;
|
bool is_calculated_ = true;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,8 @@ void FindSymbolsVisitor::Visit(AliasDefinitionStatement* node) {
|
||||||
info.type = std::move(alias_info);
|
info.type = std::move(alias_info);
|
||||||
|
|
||||||
node->type_id_ = namespace_visitor_.AddType(node->type, std::move(info), node->base);
|
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) {
|
void FindSymbolsVisitor::Visit(FunctionDeclaration* node) {
|
||||||
|
|
@ -69,6 +71,8 @@ void FindSymbolsVisitor::Visit(FunctionDeclaration* node) {
|
||||||
info.node = node;
|
info.node = node;
|
||||||
|
|
||||||
node->function_id_ = namespace_visitor_.AddFunctionDeclaration(node->name, std::move(info), node->base);
|
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) {
|
void FindSymbolsVisitor::Visit(FunctionDefinitionStatement* node) {
|
||||||
|
|
@ -84,6 +88,9 @@ void FindSymbolsVisitor::Visit(FunctionDefinitionStatement* node) {
|
||||||
info.node = node;
|
info.node = node;
|
||||||
|
|
||||||
node->function_id_ = namespace_visitor_.AddFunctionDefinition(definition->name, std::move(info), node->base);
|
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) {
|
void FindSymbolsVisitor::Visit(TypeDefinitionStatement* node) {
|
||||||
|
|
@ -113,6 +120,9 @@ void FindSymbolsVisitor::Visit(TypeDefinitionStatement* node) {
|
||||||
info.type = std::move(any_type_info);
|
info.type = std::move(any_type_info);
|
||||||
|
|
||||||
node->type_id_ = namespace_visitor_.AddType(type, std::move(info), node->base);
|
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) {
|
void FindSymbolsVisitor::Visit(AbstractTypeDefinitionStatement* node) {
|
||||||
|
|
@ -153,10 +163,14 @@ void FindSymbolsVisitor::Visit(TypeclassDefinitionStatement* node) {
|
||||||
info.parent_namespace = namespace_visitor_.GetCurrentNamespaceId();
|
info.parent_namespace = namespace_visitor_.GetCurrentNamespaceId();
|
||||||
|
|
||||||
node->typeclass_id_ = namespace_visitor_.AddTypeclass(typeclass_name, std::move(info), node->base);
|
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) {
|
void FindSymbolsVisitor::Visit(PartitionStatement* node) {
|
||||||
node->executable_id_ = namespace_visitor_.AddPartition(node->name.path, node, node->base);
|
node->executable_id_ = namespace_visitor_.AddPartition(node->name.path, node, node->base);
|
||||||
|
|
||||||
|
Visitor::Visit(node->value); // to visit all tree
|
||||||
}
|
}
|
||||||
|
|
||||||
// Definition parts
|
// Definition parts
|
||||||
|
|
@ -171,8 +185,19 @@ void FindSymbolsVisitor::Visit(AnyAnnotatedType* node) {
|
||||||
info.typeclass_nodes[i] = node->typeclasses[i].get();
|
info.typeclass_nodes[i] = node->typeclasses[i].get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto& typeclass : node->typeclasses) {
|
||||||
|
Visitor::Visit(typeclass.get()); // to visit all tree
|
||||||
|
}
|
||||||
|
|
||||||
info.node = node;
|
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);
|
current_info_ = std::move(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -460,79 +460,79 @@ std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindNamespaceIn(
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
// cache ??
|
// // cache ??
|
||||||
std::unordered_set<utils::IdType>
|
// std::unordered_set<utils::IdType>
|
||||||
GlobalInfo::GetAnnotatedTypeTypeclassesSet(interpreter::tokens::AnnotatedType* node) {
|
// GlobalInfo::GetAnnotatedTypeTypeclassesSet(interpreter::tokens::AnnotatedType* node) {
|
||||||
|
//
|
||||||
std::unordered_set<utils::IdType> typeclasses;
|
// std::unordered_set<utils::IdType> typeclasses;
|
||||||
|
//
|
||||||
for (auto& typeclass : node->typeclasses) {
|
// for (auto& typeclass : node->typeclasses) {
|
||||||
utils::IdType graph_id = typeclasses_[typeclass->typeclass_id_].graph_id_;
|
// utils::IdType graph_id = typeclasses_[typeclass->typeclass_id_].graph_id_;
|
||||||
|
//
|
||||||
std::vector<utils::IdType> dependencies = typeclass_graph_.GetTypeclassDependencies(graph_id);
|
// std::vector<utils::IdType> dependencies = typeclass_graph_.GetTypeclassDependencies(graph_id);
|
||||||
for (auto& dependency : dependencies) {
|
// for (auto& dependency : dependencies) {
|
||||||
typeclasses.insert(dependency);
|
// typeclasses.insert(dependency);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
typeclasses.insert(graph_id);
|
// typeclasses.insert(graph_id);
|
||||||
}
|
// }
|
||||||
return typeclasses;
|
// return typeclasses;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
std::vector<utils::IdType>
|
// std::vector<utils::IdType>
|
||||||
GlobalInfo::GetAnnotatedTypeTypeclassesVector(interpreter::tokens::AnnotatedType* node) {
|
// GlobalInfo::GetAnnotatedTypeTypeclassesVector(interpreter::tokens::AnnotatedType* node) {
|
||||||
|
//
|
||||||
std::unordered_set<utils::IdType> typeclasses_set = GetAnnotatedTypeTypeclassesSet(node);
|
// std::unordered_set<utils::IdType> typeclasses_set = GetAnnotatedTypeTypeclassesSet(node);
|
||||||
|
//
|
||||||
std::vector<utils::IdType> typeclasses_vector;
|
// std::vector<utils::IdType> typeclasses_vector;
|
||||||
typeclasses_vector.reserve(typeclasses_vector.size());
|
// typeclasses_vector.reserve(typeclasses_vector.size());
|
||||||
for (auto& typeclass : typeclasses_set) {
|
// for (auto& typeclass : typeclasses_set) {
|
||||||
typeclasses_vector.push_back(typeclass);
|
// typeclasses_vector.push_back(typeclass);
|
||||||
}
|
// }
|
||||||
return typeclasses_vector;
|
// return typeclasses_vector;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
std::unordered_map<std::string, TypeclassGraph::FunctionInfo> // TODO: optimize, cache
|
// std::unordered_map<std::string, TypeclassGraph::FunctionInfo> // TODO: optimize, cache
|
||||||
GlobalInfo::GetAnnotatedTypeFunctionsMap(interpreter::tokens::AnnotatedType* node,
|
// GlobalInfo::GetAnnotatedTypeFunctionsMap(interpreter::tokens::AnnotatedType* node,
|
||||||
const interpreter::tokens::BaseNode& base_node) {
|
// const interpreter::tokens::BaseNode& base_node) {
|
||||||
|
//
|
||||||
std::unordered_map<std::string, TypeclassGraph::FunctionInfo> functions;
|
// std::unordered_map<std::string, TypeclassGraph::FunctionInfo> functions;
|
||||||
|
//
|
||||||
for (auto& typeclass : node->typeclasses) {
|
// for (auto& typeclass : node->typeclasses) {
|
||||||
utils::IdType graph_id = typeclasses_[typeclass->typeclass_id_].graph_id_;
|
// utils::IdType graph_id = typeclasses_[typeclass->typeclass_id_].graph_id_;
|
||||||
|
//
|
||||||
auto requirements = typeclass_graph_.GetTypeclassFunctions(graph_id);
|
// auto requirements = typeclass_graph_.GetTypeclassFunctions(graph_id);
|
||||||
for (auto& requirement : requirements) {
|
// for (auto& requirement : requirements) {
|
||||||
auto requirement_iter = functions.find(requirement.first);
|
// auto requirement_iter = functions.find(requirement.first);
|
||||||
if (requirement_iter == functions.end()) {
|
// if (requirement_iter == functions.end()) {
|
||||||
functions[requirement.first] = *requirement.second;
|
// functions[requirement.first] = *requirement.second;
|
||||||
} else {
|
// } else {
|
||||||
if (requirement_iter->second.definition.has_value()) {
|
// if (requirement_iter->second.definition.has_value()) {
|
||||||
if (requirement.second->definition.has_value()) {
|
// if (requirement.second->definition.has_value()) {
|
||||||
error_handling::HandleTypecheckError("Function defined more then in one type requirement", base_node);
|
// error_handling::HandleTypecheckError("Function defined more then in one type requirement", base_node);
|
||||||
}
|
// }
|
||||||
} else {
|
// } else {
|
||||||
requirement_iter->second.definition = requirement.second->definition;
|
// requirement_iter->second.definition = requirement.second->definition;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
return functions;
|
// return functions;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo>> // TODO: optimize, cache
|
// std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo>> // TODO: optimize, cache
|
||||||
GlobalInfo::GetAnnotatedTypeFunctionsVector(interpreter::tokens::AnnotatedType* node,
|
// GlobalInfo::GetAnnotatedTypeFunctionsVector(interpreter::tokens::AnnotatedType* node,
|
||||||
const interpreter::tokens::BaseNode& base_node) {
|
// const interpreter::tokens::BaseNode& base_node) {
|
||||||
|
//
|
||||||
auto functions_set = GetAnnotatedTypeFunctionsMap(node, base_node);
|
// auto functions_set = GetAnnotatedTypeFunctionsMap(node, base_node);
|
||||||
|
//
|
||||||
std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo>> functions_vector;
|
// std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo>> functions_vector;
|
||||||
functions_vector.reserve(functions_vector.size());
|
// functions_vector.reserve(functions_vector.size());
|
||||||
for (auto& typeclass : functions_set) {
|
// for (auto& typeclass : functions_set) {
|
||||||
functions_vector.push_back(typeclass);
|
// functions_vector.push_back(typeclass);
|
||||||
}
|
// }
|
||||||
return functions_vector;
|
// return functions_vector;
|
||||||
}
|
// }
|
||||||
|
|
||||||
std::unordered_map<std::string, utils::IdType>*
|
std::unordered_map<std::string, utils::IdType>*
|
||||||
GlobalInfo::ChooseNamespaces(utils::ClassInternalsModifier modifier,
|
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);
|
definition::Namespace* parent_namespace = &GetNamespaceInfo(typeclass_info->parent_namespace);
|
||||||
|
|
||||||
std::string name = typeclass_info->node->definition->type->type;
|
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::string> dependencies;
|
||||||
std::vector<std::pair<std::string, std::pair<utils::ClassInternalsModifier, interpreter::tokens::FunctionDeclaration*>>> function_declarations;
|
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;
|
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;
|
std::string dependency = dependency_node->typeclass;
|
||||||
if (dependency_node->parameters.size() > 0) {
|
if (dependency_node->parameters.size() > 0) {
|
||||||
error_handling::HandleInternalError("Paramtrized typeclass requirements are not implemented yet",
|
error_handling::HandleInternalError("Paramtrized typeclass requirements are not implemented yet",
|
||||||
"TypeclassGraph.AddTypeclassByNode");
|
"GlobalInfo.AddTypeclassToGraph");
|
||||||
}
|
}
|
||||||
dependencies.push_back(dependency);
|
dependencies.push_back(dependency);
|
||||||
}
|
}
|
||||||
|
|
@ -595,11 +596,34 @@ std::optional<utils::IdType> GlobalInfo::AddTypeclassToGraph(utils::IdType typec
|
||||||
function_definitions);
|
function_definitions);
|
||||||
}
|
}
|
||||||
|
|
||||||
return typeclass_graph_.AddTypeclass(name,
|
return typeclass_graph_.AddVertex(name,
|
||||||
typeclass_info->node,
|
|
||||||
dependencies,
|
dependencies,
|
||||||
function_declarations,
|
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(
|
void GlobalInfo::CollectFunctionInfo(
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,13 @@ void LinkSymbolsVisitor::Visit(Namespace* node) {
|
||||||
|
|
||||||
// Definitions -----------------
|
// 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) {
|
void LinkSymbolsVisitor::Visit(TypeclassDefinitionStatement* node) {
|
||||||
Visitor::Visit(node->definition.get());
|
Visitor::Visit(node->definition.get());
|
||||||
for (auto& function_requirement : node->requirements) {
|
for (auto& function_requirement : node->requirements) {
|
||||||
|
|
|
||||||
|
|
@ -1,31 +1,41 @@
|
||||||
// for clangd
|
// for clangd
|
||||||
#include "../include/typeclass_graph.hpp"
|
#include "../include/typeclass_graph.hpp"
|
||||||
|
#include "../include/error_handling.hpp"
|
||||||
|
|
||||||
namespace info {
|
namespace info {
|
||||||
|
|
||||||
std::optional<utils::IdType> TypeclassGraph::AddTypeclass(
|
utils::IdType TypeclassGraph::AddVertex(
|
||||||
const std::string& name,
|
const std::string& name,
|
||||||
interpreter::tokens::TypeclassDefinitionStatement* definition,
|
|
||||||
const std::vector<std::string>& dependencies, // TODO: parameters
|
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, 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) {
|
for (auto& method : function_declarations) {
|
||||||
if (method_to_typeclass_.count(method.first) != 0) {
|
if (method_to_vertex_.count(method.first) != 0) {
|
||||||
return std::nullopt;
|
error_handling::HandleTypecheckError("Typeclass \"" + name + "\" method \"" + method.first + "\" already declaret in another typeclass", *base_node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is_calculated_ = false;
|
is_calculated_ = false;
|
||||||
|
|
||||||
utils::IdType id = typeclasses_.size();
|
utils::IdType id = verticles_.size();
|
||||||
|
|
||||||
typeclasses_.emplace_back();
|
verticles_.emplace_back();
|
||||||
TypeclassVertex& typeclass = typeclasses_.back();
|
Vertex& vertex = verticles_.back();
|
||||||
typeclass.name = name;
|
vertex.name = name;
|
||||||
typeclass.definition = definition;
|
vertex.base_node = base_node;
|
||||||
|
vertex.modifier = modifier;
|
||||||
|
|
||||||
for (auto& dependency : dependencies) {
|
for (auto& dependency : dependencies) {
|
||||||
typeclass.dependencies.insert(dependency);
|
vertex.dependencies.insert(dependency);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& method : function_declarations) {
|
for (auto& method : function_declarations) {
|
||||||
|
|
@ -33,31 +43,37 @@ std::optional<utils::IdType> TypeclassGraph::AddTypeclass(
|
||||||
function_info.modifier = method.second.first;
|
function_info.modifier = method.second.first;
|
||||||
function_info.declaration = method.second.second;
|
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;
|
name_to_typeclass_[name] = id;
|
||||||
|
}
|
||||||
|
|
||||||
for (auto& method : function_definitions) {
|
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;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<utils::IdType> TypeclassGraph::FindFunctionTypeclass(const std::string& name) {
|
std::optional<utils::IdType> TypeclassGraph::FindFunctionTypeclass(const std::string& name) {
|
||||||
auto function_iter = method_to_typeclass_.find(name);
|
auto function_iter = method_to_vertex_.find(name);
|
||||||
if (function_iter == method_to_typeclass_.end()) {
|
if (function_iter == method_to_vertex_.end()) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
return function_iter->second;
|
return function_iter->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<TypeclassGraph::FunctionInfo*> TypeclassGraph::GetFunctionInfo(const std::string& name,
|
std::optional<TypeclassGraph::FunctionInfo*> TypeclassGraph::GetFunctionInfo(const std::string& name,
|
||||||
std::optional<utils::IdType> typeclass_id) {
|
std::optional<utils::IdType> vertex_id) {
|
||||||
if (typeclass_id.has_value()) {
|
if (vertex_id.has_value()) {
|
||||||
return &typeclasses_[typeclass_id.value()].functions[name];
|
return &verticles_[vertex_id.value()].functions[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
auto maybe_function_typeclass_id = FindFunctionTypeclass(name);
|
auto maybe_function_typeclass_id = FindFunctionTypeclass(name);
|
||||||
|
|
@ -66,47 +82,45 @@ std::optional<TypeclassGraph::FunctionInfo*> TypeclassGraph::GetFunctionInfo(con
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
return &typeclasses_[maybe_function_typeclass_id.value()].functions[name];
|
return &verticles_[maybe_function_typeclass_id.value()].functions[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
// cache ??
|
std::unordered_set<utils::IdType> TypeclassGraph::GetDependenciesSet(utils::IdType id) {
|
||||||
std::vector<utils::IdType> TypeclassGraph::GetTypeclassDependencies(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;
|
std::vector<utils::IdType> dependencies;
|
||||||
|
|
||||||
dependencies.reserve(typeclasses_.at(id).dependencies.size());
|
dependencies.reserve(verticles_.at(id).dependencies.size());
|
||||||
for (auto& dependency : typeclasses_[id].dependencies) {
|
for (auto& dependency : verticles_[id].dependencies) {
|
||||||
dependencies.push_back(name_to_typeclass_[dependency]);
|
dependencies.push_back(name_to_typeclass_[dependency]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return dependencies;
|
return dependencies;
|
||||||
}
|
}
|
||||||
|
|
||||||
// cache ??
|
void TypeclassGraph::CalculateGraph() {
|
||||||
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() {
|
|
||||||
if (is_calculated_) {
|
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) {
|
for (size_t i = 0; i < verticles_.size(); ++i) {
|
||||||
edges[i].reserve(typeclasses_[i].dependencies.size());
|
edges[i].reserve(verticles_[i].dependencies.size());
|
||||||
for (auto& dependency :typeclasses_[i].dependencies) {
|
for (auto& dependency : verticles_[i].dependencies) {
|
||||||
auto dependency_iter = name_to_typeclass_.find(dependency);
|
auto dependency_iter = name_to_typeclass_.find(dependency);
|
||||||
|
|
||||||
if (dependency_iter == name_to_typeclass_.end()) {
|
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);
|
edges[i].push_back(dependency_iter->second);
|
||||||
|
|
@ -117,26 +131,28 @@ bool TypeclassGraph::CalculateGraph() {
|
||||||
std::reverse(sorted_verticles.begin(), sorted_verticles.end());
|
std::reverse(sorted_verticles.begin(), sorted_verticles.end());
|
||||||
|
|
||||||
for (auto& id : sorted_verticles) {
|
for (auto& id : sorted_verticles) {
|
||||||
for (auto& dependency : typeclasses_[id].dependencies) {
|
for (auto& dependency : verticles_[id].dependencies) {
|
||||||
for (auto& method : typeclasses_[name_to_typeclass_[dependency]].functions) {
|
for (auto& method : verticles_[name_to_typeclass_[dependency]].functions) {
|
||||||
auto function_iter = typeclasses_[id].functions.find(method.first);
|
auto function_iter = verticles_[id].functions.find(method.first);
|
||||||
if (function_iter == typeclasses_[id].functions.end()) {
|
if (function_iter == verticles_[id].functions.end()) {
|
||||||
typeclasses_[id].functions[method.first] = method.second;
|
verticles_[id].functions[method.first] = method.second;
|
||||||
} else {
|
} else {
|
||||||
if (!function_iter->second.definition.has_value()) {
|
if (!function_iter->second.definition.has_value()) {
|
||||||
function_iter->second.definition = method.second.definition;
|
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;
|
is_calculated_ = true;
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace info
|
} // namespace info
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue