mirror of
https://codeberg.org/ProgramSnail/lang_2023.git
synced 2026-01-25 13:07:13 +00:00
abstract types typecheck, fixes
This commit is contained in:
parent
9aeba7b0de
commit
c433448952
9 changed files with 143 additions and 94 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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 -----------------
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue