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

@ -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);
}
}