mirror of
https://codeberg.org/ProgramSnail/lang_2023.git
synced 2025-12-05 22:48:42 +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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include <iostream>
|
||||
|
||||
// for clangd
|
||||
#include "../include/error_handling.hpp"
|
||||
#include "../include/find_symbols_visitor.hpp"
|
||||
|
||||
namespace interpreter {
|
||||
|
|
@ -44,11 +45,6 @@ void FindSymbolsVisitor::Visit(AliasDefinitionStatement* node) {
|
|||
}
|
||||
|
||||
void FindSymbolsVisitor::Visit(FunctionDeclaration* node) {
|
||||
info::definition::Namespace* current_namespace = namespace_visitor_.GetCurrentNamespace();
|
||||
if (current_namespace->node.has_value() && current_namespace->node.value()->link_typeclass_id_.has_value()) {
|
||||
error_handling::HandleTypecheckError("Can't declare typeclass methods not as requirements", node->base);
|
||||
}
|
||||
|
||||
info::definition::FunctionDeclaration info;
|
||||
|
||||
info.parameters.resize(node->parameters.size());
|
||||
|
|
@ -131,7 +127,7 @@ void FindSymbolsVisitor::Visit(TypeclassDefinitionStatement* node) {
|
|||
|
||||
auto definition = node->definition.get();
|
||||
|
||||
std::string& type_name = definition->type.get()->type;
|
||||
std::string& typeclass_name = definition->type.get()->type;
|
||||
|
||||
info.parameters.resize(definition->parameters.size());
|
||||
for (size_t i = 0; i < definition->parameters.size(); ++i) {
|
||||
|
|
@ -141,7 +137,7 @@ void FindSymbolsVisitor::Visit(TypeclassDefinitionStatement* node) {
|
|||
}
|
||||
|
||||
for (size_t i = 0; i < node->requirements.size(); ++i) {
|
||||
namespace_visitor_.AddEnterNamespace(type_name, node->requirements[i].first, std::nullopt, node->base);
|
||||
namespace_visitor_.AddEnterNamespace(typeclass_name, node->requirements[i].first, std::nullopt, node->base);
|
||||
Visit(node->requirements[i].second.get());
|
||||
namespace_visitor_.ExitNamespace();
|
||||
}
|
||||
|
|
@ -149,7 +145,7 @@ void FindSymbolsVisitor::Visit(TypeclassDefinitionStatement* node) {
|
|||
info.node = node;
|
||||
info.parent_namespace = namespace_visitor_.GetCurrentNamespaceId();
|
||||
|
||||
node->typeclass_id_ = namespace_visitor_.AddTypeclass(type_name, std::move(info), node->base);
|
||||
node->typeclass_id_ = namespace_visitor_.AddTypeclass(typeclass_name, std::move(info), node->base);
|
||||
}
|
||||
|
||||
void FindSymbolsVisitor::Visit(PartitionStatement* node) {
|
||||
|
|
@ -168,6 +164,8 @@ void FindSymbolsVisitor::Visit(AnyAnnotatedType* node) {
|
|||
info.typeclass_nodes[i] = node->typeclasses[i].get();
|
||||
}
|
||||
|
||||
info.node = node;
|
||||
|
||||
current_info_ = std::move(info);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ void GlobalInfo::NamespaceVisitor::AddEnterNamespace(const std::string& name,
|
|||
std::optional<interpreter::tokens::Namespace*> node,
|
||||
const interpreter::tokens::BaseNode& base_node) {
|
||||
if (type::ToInternalType(name).has_value()) {
|
||||
error_handling::HandleTypecheckError("Can't define basic type namespace", base_node);
|
||||
error_handling::HandleNamesError("Can't define basic type namespace", base_node);
|
||||
}
|
||||
|
||||
auto current_namespaces = ChooseNamespaces(modifier, namespace_stack_.back());
|
||||
|
|
@ -36,12 +36,16 @@ void GlobalInfo::NamespaceVisitor::AddEnterNamespace(const std::string& name,
|
|||
global_info_.namespaces_.emplace_back();
|
||||
|
||||
global_info_.namespaces_.back().modifier = modifier;
|
||||
global_info_.namespaces_.back().node = node;
|
||||
} else {
|
||||
id = namespace_iter->second;
|
||||
}
|
||||
|
||||
definition::Namespace* namespace_info = &global_info_.namespaces_[id];
|
||||
|
||||
if (!namespace_info->any_node.has_value()) { // ??
|
||||
namespace_info->any_node = node;
|
||||
}
|
||||
|
||||
namespace_info->parent_namespace = namespace_stack_.back();
|
||||
|
||||
namespace_info->type_name = name;
|
||||
|
|
@ -99,12 +103,12 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddFunctionDeclaration(
|
|||
} else {
|
||||
id = function_id_iter->second;
|
||||
if (global_info_.functions_[id].argument_count != function_declaration_info.argument_types.size()) {
|
||||
error_handling::HandleTypecheckError("Function declaration: not same argument count in function definition and declaration", base_node);
|
||||
error_handling::HandleNamesError("Function declaration: not same argument count in function definition and declaration", base_node);
|
||||
}
|
||||
}
|
||||
|
||||
if (global_info_.functions_[id].declaration.has_value()) {
|
||||
error_handling::HandleTypecheckError("Second function declaration", base_node);
|
||||
error_handling::HandleNamesError("Second function declaration", base_node);
|
||||
}
|
||||
global_info_.functions_[id].declaration = std::move(function_declaration_info);
|
||||
|
||||
|
|
@ -126,12 +130,12 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddFunctionDefinition(
|
|||
} else {
|
||||
id = function_id_iter->second;
|
||||
if (global_info_.functions_[id].argument_count != function_definition_info.argument_names.size() + 1) {
|
||||
error_handling::HandleTypecheckError("Function definition: not same argument count in function definition and declaration", base_node);
|
||||
error_handling::HandleNamesError("Function definition: not same argument count in function definition and declaration", base_node);
|
||||
}
|
||||
}
|
||||
|
||||
if (global_info_.functions_[id].definition.has_value()) {
|
||||
error_handling::HandleTypecheckError("Second function definition", base_node);
|
||||
error_handling::HandleNamesError("Second function definition", base_node);
|
||||
}
|
||||
global_info_.functions_[id].definition = std::move(function_definition_info);
|
||||
|
||||
|
|
@ -144,7 +148,7 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddType(const std::string& type,
|
|||
definition::Type&& type_info,
|
||||
const interpreter::tokens::BaseNode& base_node) {
|
||||
if (type::ToInternalType(type).has_value()) {
|
||||
error_handling::HandleTypecheckError("Can't redefine basic type", base_node);
|
||||
error_handling::HandleNamesError("Can't redefine basic type", base_node);
|
||||
}
|
||||
|
||||
utils::IdType id = 0;
|
||||
|
|
@ -156,8 +160,8 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddType(const std::string& type,
|
|||
global_info_.namespaces_[namespace_stack_.back()].types[type] = id;
|
||||
global_info_.types_.push_back(std::move(type_info));
|
||||
} else {
|
||||
error_handling::HandleTypecheckError("More then one type with the same name in namespace", base_node);
|
||||
} // TODO: typecheck error??
|
||||
error_handling::HandleNamesError("More then one type with the same name in namespace", base_node);
|
||||
}
|
||||
|
||||
definition::Type& moved_type_info = global_info_.types_.back();
|
||||
|
||||
|
|
@ -207,12 +211,11 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddAbstractType(const std::string& a
|
|||
definition::AbstractType&& abstract_type_info,
|
||||
const interpreter::tokens::BaseNode& base_node) {
|
||||
if (type::ToInternalType(abstract_type).has_value()) {
|
||||
error_handling::HandleTypecheckError("Can't redefine basic type as abstract type", base_node);
|
||||
error_handling::HandleNamesError("Can't redefine basic type as abstract type", base_node);
|
||||
}
|
||||
|
||||
if (FindAbstractType(abstract_type).has_value()) {
|
||||
error_handling::HandleTypecheckError("More then one abstract type with the same name in namespace",
|
||||
base_node);
|
||||
error_handling::HandleNamesError("More then one abstract type with the same name in namespace", base_node);
|
||||
}
|
||||
|
||||
utils::IdType id = global_info_.abstract_types_.size();
|
||||
|
|
@ -227,23 +230,17 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddTypeclass(const std::string& type
|
|||
definition::Typeclass&& typeclass_info,
|
||||
const interpreter::tokens::BaseNode& base_node) {
|
||||
if (type::ToInternalType(typeclass).has_value()) {
|
||||
error_handling::HandleTypecheckError("Can't redefine basic type as typeclass", base_node);
|
||||
error_handling::HandleNamesError("Can't redefine basic type as typeclass", base_node);
|
||||
}
|
||||
|
||||
if (FindTypeclass(typeclass).has_value()) {
|
||||
error_handling::HandleTypecheckError("More then one typeclass with the same name in namespace", base_node);
|
||||
error_handling::HandleNamesError("More then one typeclass with the same name", base_node);
|
||||
}
|
||||
|
||||
utils::IdType id = global_info_.typeclasses_.size();
|
||||
global_info_.name_to_typeclass_[typeclass] = id;
|
||||
global_info_.typeclasses_.push_back(std::move(typeclass_info));
|
||||
|
||||
definition::Typeclass& moved_typeclass_info = global_info_.typeclasses_.back();
|
||||
|
||||
// global_info_.typeclass_graph_.AddTypeclassByNode(moved_typeclass_info.node); // TODO
|
||||
error_handling::HandleInternalError("Typeclasses are not implemented properly yet",
|
||||
"GlobalInfo.NamespaceVisitor.AddTypeclass");
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
|
|
@ -251,13 +248,13 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddConstructor(const std::string& co
|
|||
definition::Constructor&& constructor_info,
|
||||
const interpreter::tokens::BaseNode& base_node) {
|
||||
if (type::ToInternalType(constructor).has_value()) {
|
||||
error_handling::HandleTypecheckError("Can't redefine basic type as constructor", base_node);
|
||||
error_handling::HandleNamesError("Can't redefine basic type as constructor", base_node);
|
||||
}
|
||||
|
||||
auto constructor_id_iter = global_info_.namespaces_[namespace_stack_.back()].constructors.find(constructor);
|
||||
|
||||
if (constructor_id_iter != global_info_.namespaces_[namespace_stack_.back()].constructors.end()) {
|
||||
error_handling::HandleTypecheckError("More then one constructor with the same name in namespace", base_node);
|
||||
error_handling::HandleNamesError("More then one constructor with the same name in namespace", base_node);
|
||||
}
|
||||
|
||||
utils::IdType id = global_info_.constructors_.size();
|
||||
|
|
@ -316,8 +313,6 @@ std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindMethodId(
|
|||
const std::string& type,
|
||||
const std::string& name,
|
||||
utils::IsConstModifier modifier) {
|
||||
// TODO: remove overhead
|
||||
|
||||
return GlobalInfo::NamespaceVisitor::FindSomething<utils::IdType>(path,
|
||||
[type, name, modifier, this] (utils::IdType current_namespace) -> std::optional<utils::IdType> {
|
||||
|
||||
|
|
@ -471,13 +466,12 @@ 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;
|
||||
std::vector<TypeclassGraph::ParametrizedTypeclass> 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, interpreter::tokens::FunctionDefinitionStatement*>> function_definitions;
|
||||
|
||||
for (auto& dependency_node : typeclass_info->node->definition->type->typeclasses) {
|
||||
TypeclassGraph::ParametrizedTypeclass dependency;
|
||||
dependency.typeclass = dependency_node->typeclass;
|
||||
std::string dependency = dependency_node->typeclass;
|
||||
if (dependency_node->parameters.size() > 0) {
|
||||
error_handling::HandleInternalError("Paramtrized typeclass requirements are not implemented yet",
|
||||
"TypeclassGraph.AddTypeclassByNode");
|
||||
|
|
@ -494,23 +488,21 @@ std::optional<utils::IdType> GlobalInfo::AddTypeclassToGraph(utils::IdType typec
|
|||
}
|
||||
|
||||
auto const_namespace_iter = parent_namespace->const_namespaces.find(name);
|
||||
if (namespace_iter != parent_namespace->const_namespaces.end()) {
|
||||
CollectFunctionInfo(namespace_iter->second,
|
||||
if (const_namespace_iter != parent_namespace->const_namespaces.end()) {
|
||||
CollectFunctionInfo(const_namespace_iter->second,
|
||||
utils::ClassInternalsModifier::Const,
|
||||
function_declarations,
|
||||
function_definitions);
|
||||
}
|
||||
|
||||
auto var_namespace_iter = parent_namespace->var_namespaces.find(name);
|
||||
if (namespace_iter != parent_namespace->var_namespaces.end()) {
|
||||
CollectFunctionInfo(namespace_iter->second,
|
||||
if (var_namespace_iter != parent_namespace->var_namespaces.end()) {
|
||||
CollectFunctionInfo(var_namespace_iter->second,
|
||||
utils::ClassInternalsModifier::Var,
|
||||
function_declarations,
|
||||
function_definitions);
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
||||
return typeclass_graph_.AddTypeclass(name,
|
||||
typeclass_info->node,
|
||||
dependencies,
|
||||
|
|
|
|||
|
|
@ -15,12 +15,12 @@ void LinkSymbolsVisitor::Visit(Namespace* node) {
|
|||
std::optional<utils::IdType> maybe_type = namespace_visitor_.FindLocalTypeId(node->type);
|
||||
|
||||
std::optional<utils::IdType> maybe_typeclass;
|
||||
if (namespace_visitor_.GetCurrentPath().size() == 0) {
|
||||
if (namespace_visitor_.IsInGlobalNamespace()) {
|
||||
maybe_typeclass = namespace_visitor_.FindTypeclassId(node->type);
|
||||
}
|
||||
|
||||
if (maybe_type.has_value() && maybe_typeclass.has_value()) {
|
||||
error_handling::HandleTypecheckError("Ambigious namespace name (typeclass or type)", node->base);
|
||||
error_handling::HandleNamesError("Ambigious namespace name (typeclass or type)", node->base);
|
||||
}
|
||||
|
||||
if (maybe_type.has_value()) {
|
||||
|
|
@ -39,21 +39,26 @@ void LinkSymbolsVisitor::Visit(Namespace* node) {
|
|||
|
||||
// Definitions -----------------
|
||||
|
||||
// TODO: add to typeclass graph, etc. (+ check)
|
||||
void LinkSymbolsVisitor::Visit(TypeclassDefinitionStatement* node) {
|
||||
Visitor::Visit(node->definition.get());
|
||||
for (auto& function_requirement : node->requirements) {
|
||||
namespace_visitor_.EnterNamespace(node->definition->type->type, function_requirement.first);
|
||||
Visitor::Visit(function_requirement.second.get());
|
||||
namespace_visitor_.ExitNamespace();
|
||||
}
|
||||
|
||||
namespace_visitor_.GetGlobalInfo()->AddTypeclassToGraph(node->typeclass_id_);
|
||||
auto maybe_graph_id = namespace_visitor_.GetGlobalInfo()->AddTypeclassToGraph(node->typeclass_id_);
|
||||
if (!maybe_graph_id.has_value()) {
|
||||
error_handling::HandleNamesError("Can't add typeclass to graph", node->base);
|
||||
}
|
||||
namespace_visitor_.GetGlobalInfo()->GetTypeclassInfo(node->typeclass_id_).graph_id_ = maybe_graph_id.value();
|
||||
}
|
||||
|
||||
// Type, typeclass, etc. -----------------
|
||||
|
||||
// Type
|
||||
|
||||
void LinkSymbolsVisitor::Visit(TypeExpression* node) { // TODO: check
|
||||
void LinkSymbolsVisitor::Visit(TypeExpression* node) {
|
||||
std::vector<std::string> path;
|
||||
path.reserve(node->path.size());
|
||||
|
||||
|
|
@ -67,11 +72,11 @@ void LinkSymbolsVisitor::Visit(TypeExpression* node) { // TODO: check
|
|||
// internal type
|
||||
if (info::type::ToInternalType(node->type.type).has_value()) {
|
||||
if (!node->path.empty()) {
|
||||
error_handling::HandleTypecheckError("Internal type is not in namespace", node->base);
|
||||
error_handling::HandleNamesError("Internal type is not in namespace", node->base);
|
||||
}
|
||||
|
||||
if (!node->type.parameters.empty()) {
|
||||
error_handling::HandleTypecheckError("Can't parametrize internal type", node->base);
|
||||
error_handling::HandleNamesError("Can't parametrize internal type", node->base);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -93,7 +98,7 @@ void LinkSymbolsVisitor::Visit(TypeExpression* node) { // TODO: check
|
|||
utils::IdType constructor_type_id = namespace_visitor_.GetGlobalInfo()->GetConstructorInfo(node->constructor_id_.value()).type_id;
|
||||
|
||||
if (node->type_id_.has_value() && node->type_id_.value() != constructor_type_id) {
|
||||
error_handling::HandleTypecheckError("Contructor and type with same name have different types", node->base);
|
||||
error_handling::HandleNamesError("Contructor and type with same name have different types", node->base);
|
||||
}
|
||||
|
||||
node->type_id_ = constructor_type_id;
|
||||
|
|
@ -122,13 +127,17 @@ void LinkSymbolsVisitor::Visit(TypeExpression* node) { // TODO: check
|
|||
|
||||
// Typeclass
|
||||
|
||||
void LinkSymbolsVisitor::Visit(ParametrizedTypeclass* node) { // TODO: check
|
||||
void LinkSymbolsVisitor::Visit(ParametrizedTypeclass* node) {
|
||||
std::optional<utils::IdType> maybe_typeclass = namespace_visitor_.FindTypeclassId(node->typeclass);
|
||||
|
||||
if (maybe_typeclass.has_value()) {
|
||||
node->typeclass_id_ = maybe_typeclass.value();
|
||||
} else {
|
||||
error_handling::HandleTypecheckError("Typeclass not found", node->base);
|
||||
error_handling::HandleNamesError("Typeclass not found", node->base);
|
||||
}
|
||||
|
||||
if (node->parameters.size() > 0) {
|
||||
error_handling::HandleNamesError("Parametrized typeclasses not implemented yet", node->base);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,10 +32,12 @@ void TypeCheckVisitor::Visit(NamespaceSources* node) {
|
|||
node->base.type_ = current_type_;
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(Namespace* node) { // TODO: two var namespces for class: const and var
|
||||
if (node->link_typeclass_id_.has_value()) { // TODO: think about typeclass
|
||||
void TypeCheckVisitor::Visit(Namespace* node) {
|
||||
if (node->link_typeclass_id_.has_value()) {
|
||||
utils::IdType graph_id = namespace_visitor_.GetGlobalInfo()->GetTypeclassInfo(node->link_typeclass_id_.value()).graph_id_;
|
||||
|
||||
std::vector<utils::IdType> requirements {node->link_typeclass_id_.value()};
|
||||
std::vector<utils::IdType> requirements = namespace_visitor_.GetTypeclassGraph()->GetTypeclassDependencies(graph_id);
|
||||
requirements.push_back(graph_id);
|
||||
utils::IdType abstract_type = context_manager_.AddValue(
|
||||
info::type::AbstractType(utils::AbstractTypeModifier::Abstract, node->type, requirements),
|
||||
ClassInternalsModifierToValueType(node->modifier));
|
||||
|
|
@ -95,7 +97,6 @@ void TypeCheckVisitor::Visit(Namespace* node) { // TODO: two var namespces for c
|
|||
void TypeCheckVisitor::Visit(ImportStatement* node) {}
|
||||
|
||||
// TODO
|
||||
// + TODO: let bindings for abstract types
|
||||
void TypeCheckVisitor::Visit(AliasDefinitionStatement* node) {
|
||||
error_handling::HandleInternalError("Unimplemented",
|
||||
"TypeCheckVisitor.AliasDefinitionStatement");
|
||||
|
|
@ -128,12 +129,12 @@ void TypeCheckVisitor::Visit(FunctionDeclaration* node) {
|
|||
|
||||
context_manager_.EnterContext();
|
||||
for (auto& parameter : node->parameters) { // declaration correctness check // TODO: needed??
|
||||
std::vector<utils::IdType> requirements;
|
||||
// TODO:
|
||||
std::vector<utils::IdType> requirements =
|
||||
namespace_visitor_.GetGlobalInfo()->GetAnnotatedTypeTypeclasses(parameter.get());
|
||||
current_type_ = context_manager_.AddValue(
|
||||
info::type::AbstractType(utils::AbstractTypeModifier::Abstract,
|
||||
parameter->type,
|
||||
requirements), // TODO: typeclasses-requirements
|
||||
requirements),
|
||||
utils::ValueType::Tmp);
|
||||
context_manager_.DefineLocalType(parameter->type, current_type_);
|
||||
}
|
||||
|
|
@ -161,15 +162,11 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) {
|
|||
info::definition::FunctionDeclaration& declaration = function_info.declaration.value();
|
||||
|
||||
for (auto parameter : declaration.parameters) {
|
||||
std::vector<utils::IdType> requirements;
|
||||
requirements.reserve(parameter.typeclass_nodes.size());
|
||||
for (ParametrizedTypeclass* typeclass : parameter.typeclass_nodes) {
|
||||
requirements.push_back(typeclass->typeclass_id_);
|
||||
}
|
||||
// TODO: add recursive typeclasses from typeclass tree
|
||||
std::vector<utils::IdType> requirements =
|
||||
namespace_visitor_.GetGlobalInfo()->GetAnnotatedTypeTypeclasses(parameter.node);
|
||||
current_type_ = context_manager_.AddValue(info::type::AbstractType(utils::AbstractTypeModifier::Abstract,
|
||||
parameter.type,
|
||||
requirements),
|
||||
parameter.type,
|
||||
requirements),
|
||||
utils::ValueType::Tmp);
|
||||
if (!context_manager_.DefineLocalType(parameter.type, current_type_)) {
|
||||
error_handling::HandleTypecheckError("Can't define function parameter type: abstract type redefinition", node->base);
|
||||
|
|
@ -210,13 +207,8 @@ void TypeCheckVisitor::Visit(TypeDefinitionStatement* node) {
|
|||
void TypeCheckVisitor::Visit(AbstractTypeDefinitionStatement* node) {
|
||||
is_in_statement_ = true;
|
||||
|
||||
std::vector<utils::IdType> requirements;
|
||||
requirements.reserve(node->type->typeclasses.size());
|
||||
for (auto& typeclass : node->type->typeclasses) {
|
||||
requirements.push_back(typeclass->typeclass_id_);
|
||||
}
|
||||
// TODO: add recursive typeclasses from typeclass tree
|
||||
|
||||
std::vector<utils::IdType> requirements =
|
||||
namespace_visitor_.GetGlobalInfo()->GetAnnotatedTypeTypeclasses(node->type.get());
|
||||
current_type_ = context_manager_.AddValue(info::type::AbstractType(node->modifier, node->type->type, requirements),
|
||||
utils::ValueType::Tmp);
|
||||
if (!context_manager_.DefineLocalType(node->type->type, current_type_)) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue