check, that type satisfy typeclass requirements made in type_check_visitor

This commit is contained in:
ProgramSnail 2023-05-16 16:16:14 +03:00
parent 090f638e45
commit ce0ca2a5cb
4 changed files with 118 additions and 40 deletions

View file

@ -25,7 +25,8 @@ void GlobalInfo::NamespaceVisitor::AddEnterNamespace(const std::string& name,
error_handling::HandleNamesError("Can't define basic type namespace", base_node);
}
auto current_namespaces = ChooseNamespaces(modifier, namespace_stack_.back());
auto current_namespaces =
global_info_.ChooseNamespaces(modifier, &global_info_.namespaces_[namespace_stack_.back()]);
utils::IdType id = 0;
@ -57,7 +58,8 @@ void GlobalInfo::NamespaceVisitor::AddEnterNamespace(const std::string& name,
void GlobalInfo::NamespaceVisitor::EnterNamespace(const std::string& name,
utils::ClassInternalsModifier modifier) {
for (ssize_t i = (ssize_t)namespace_stack_.size() - 1; i >= 0; --i) {
auto current_namespaces = ChooseNamespaces(modifier, i);
auto current_namespaces =
global_info_.ChooseNamespaces(modifier, &global_info_.namespaces_[i]);
auto namespace_iter = current_namespaces->find(name);
if (namespace_iter != current_namespaces->end()) {
namespace_stack_.push_back(namespace_iter->second);
@ -440,27 +442,88 @@ std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindNamespaceIn(
return next_namespace;
}
//
// 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, utils::ClassInternalsModifier>
GlobalInfo::GetAnnotatedTypeFunctionsMap(interpreter::tokens::AnnotatedType* node) {
std::unordered_map<std::string, utils::ClassInternalsModifier> 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) {
functions[requirement.first] = requirement.second;
}
}
return functions;
}
std::vector<std::pair<std::string, utils::ClassInternalsModifier>>
GlobalInfo::GetAnnotatedTypeFunctionsVector(interpreter::tokens::AnnotatedType* node) {
std::unordered_map<std::string, utils::ClassInternalsModifier> functions_set = GetAnnotatedTypeFunctionsMap(node);
std::vector<std::pair<std::string, utils::ClassInternalsModifier>> 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::NamespaceVisitor::ChooseNamespaces(utils::ClassInternalsModifier modifier,
utils::IdType namespace_id) {
GlobalInfo::ChooseNamespaces(utils::ClassInternalsModifier modifier,
definition::Namespace* current_namespace) {
std::unordered_map<std::string, utils::IdType>* current_namespaces = nullptr;
switch (modifier) {
case utils::ClassInternalsModifier::Const:
current_namespaces = &global_info_.namespaces_[namespace_id].const_namespaces;
current_namespaces = &current_namespace->const_namespaces;
break;
case utils::ClassInternalsModifier::Var:
current_namespaces = &global_info_.namespaces_[namespace_id].var_namespaces;
current_namespaces = &current_namespace->var_namespaces;
break;
case utils::ClassInternalsModifier::Static:
current_namespaces = &global_info_.namespaces_[namespace_id].namespaces;
current_namespaces = &current_namespace->namespaces;
break;
}
return current_namespaces;
}
//
std::optional<utils::IdType> GlobalInfo::AddTypeclassToGraph(utils::IdType typeclass) {
definition::Typeclass* typeclass_info = &GetTypeclassInfo(typeclass);
definition::Namespace* parent_namespace = &GetNamespaceInfo(typeclass_info->parent_namespace);