abstract types typecheck, fixes

This commit is contained in:
ProgramSnail 2023-05-16 12:43:55 +03:00
parent 9aeba7b0de
commit c433448952
9 changed files with 143 additions and 94 deletions

View file

@ -26,6 +26,8 @@ struct TypeUsage {
struct Parameter {
std::string type;
std::vector<interpreter::tokens::ParametrizedTypeclass*> typeclass_nodes;
interpreter::tokens::AnyAnnotatedType* node = nullptr;
};
struct AbstractType {
@ -82,15 +84,16 @@ struct Typeclass {
interpreter::tokens::TypeclassDefinitionStatement* node;
utils::IdType parent_namespace;
utils::IdType graph_id_; // TODO: make safe??
};
struct Import {
std::string module_name;
std::vector<std::string> symbols; // size = 0 => all symbols imported
std::vector<std::string> symbols; // size == 0 => all symbols imported
};
struct Namespace {
std::unordered_map<std::string, utils::IdType> types;
std::unordered_map<std::string, utils::IdType> functions;
std::unordered_map<std::string, utils::IdType> constructors;
@ -103,7 +106,8 @@ struct Namespace {
utils::ClassInternalsModifier modifier = utils::ClassInternalsModifier::Static;
std::string type_name;
std::optional<interpreter::tokens::Namespace*> node;
// all nodes have same info
std::optional<interpreter::tokens::Namespace*> any_node;
};
} // namespace info::definition

View file

@ -55,4 +55,17 @@ inline void HandleRuntimeError(const std::string& message,
exit(1);
}
inline void HandleNamesError(const std::string& message,
const interpreter::tokens::BaseNode& node) {
std::cerr << "\x1b[1;31mNames Error:\x1b[0m " << message << " at ";
PrintPosition(std::cerr, node.start_position, node.end_position);
std::cerr << ".\n";
exit(1);
}
template<typename T>
inline void DebugPrint(const T& value) {
std::cerr << "\x1b[1;33mDebug:\x1b[0m " << value << '\n';
}
} // namespace error_handling

View file

@ -3,6 +3,7 @@
#include <string>
#include <functional>
#include <unordered_map>
#include <unordered_set>
// for clangd
#include "definitions.hpp"
@ -12,7 +13,6 @@
namespace info {
// TODO: better test / executable partitions support (tree, etc.)
// TODO: add classes / structs and functions module interface
class GlobalInfo {
friend class NamespaceVisitor;
@ -300,6 +300,29 @@ public:
return &typeclass_graph_;
}
// cache ??
std::vector<utils::IdType> GetAnnotatedTypeTypeclasses(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);
}
std::vector<utils::IdType> collected_typeclasses;
collected_typeclasses.reserve(typeclasses.size());
for (auto& typeclass : typeclasses) {
collected_typeclasses.push_back(typeclass);
}
return collected_typeclasses;
}
std::optional<utils::IdType> AddTypeclassToGraph(utils::IdType typeclass);
private:

View file

@ -3,6 +3,7 @@
#include <ostream>
// for clangd
#include "error_handling.hpp"
#include "visitor.hpp"
#include "global_info.hpp"
@ -14,6 +15,13 @@ public:
explicit LinkSymbolsVisitor(info::GlobalInfo& global_info)
: namespace_visitor_(global_info.CreateVisitor()) {}
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");
}
}
private:
// Sources -----------------

View file

@ -3,13 +3,11 @@
#include <algorithm>
#include <string>
#include <unordered_map>
#include <unordered_set>
// for clangd
#include "error_handling.hpp"
#include "global_info.hpp"
#include "utils.hpp"
#include "interpreter_tree.hpp"
#include "definitions.hpp"
namespace info {
@ -21,23 +19,17 @@ public:
std::optional<interpreter::tokens::FunctionDefinitionStatement*> definition;
};
struct ParametrizedTypeclass {
std::string typeclass;
// TODO: parameters
};
struct TypeclassVertex {
std::string name;
interpreter::tokens::TypeclassDefinitionStatement* definition = nullptr;
std::unordered_map<std::string, FunctionInfo> functions;
std::vector<ParametrizedTypeclass> dependencies;
// TODO: parameters
std::unordered_set<std::string> dependencies; // TODO: parameters
};
std::optional<utils::IdType> AddTypeclass( // move parameters ??
const std::string& name,
interpreter::tokens::TypeclassDefinitionStatement* definition,
const std::vector<ParametrizedTypeclass>& 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, interpreter::tokens::FunctionDefinitionStatement*>>& function_definitions) {
for (auto& method : function_declarations) {
@ -52,7 +44,10 @@ public:
TypeclassVertex& typeclass = typeclasses_.back();
typeclass.name = name;
typeclass.definition = definition;
typeclass.dependencies = dependencies;
for (auto& dependency : dependencies) {
typeclass.dependencies.insert(dependency);
}
for (auto& method : function_declarations) {
FunctionInfo function_info;
@ -84,6 +79,18 @@ public:
return typeclasses_.at(id);
}
// cache ??
const std::vector<utils::IdType> GetTypeclassDependencies(utils::IdType id) {
std::vector<utils::IdType> dependencies;
dependencies.reserve(typeclasses_.at(id).dependencies.size());
for (auto& dependency : typeclasses_[id].dependencies) {
dependencies.push_back(name_to_typeclass_[dependency]);
}
return dependencies;
}
bool IsCalculated() {
return is_calculated_;
}
@ -96,15 +103,15 @@ public:
std::vector<std::vector<size_t>> edges(typeclasses_.size());
for (size_t i = 0; i < typeclasses_.size(); ++i) {
edges[i].resize(typeclasses_[i].dependencies.size());
for (size_t j = 0; j < edges[i].size(); ++j) {
auto dependency_iter = name_to_typeclass_.find(typeclasses_[i].dependencies[j].typeclass);
edges[i].reserve(typeclasses_[i].dependencies.size());
for (auto& dependency :typeclasses_[i].dependencies) {
auto dependency_iter = name_to_typeclass_.find(dependency);
if (dependency_iter == name_to_typeclass_.end()) {
return false;
}
edges[i][j] = dependency_iter->second;
edges[i].push_back(dependency_iter->second);
}
}
@ -113,7 +120,7 @@ public:
for (auto& id : sorted_verticles) {
for (auto& dependency : typeclasses_[id].dependencies) {
for (auto& method : typeclasses_[name_to_typeclass_[dependency.typeclass]].functions) {
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;
@ -123,6 +130,9 @@ public:
}
}
}
for (auto& inherited_dependency : typeclasses_[name_to_typeclass_[dependency]].dependencies) {
typeclasses_[id].dependencies.insert(inherited_dependency);
}
}
}