better global_info API, better const/var/static handling, const typeclass requirements, fixes

This commit is contained in:
ProgramSnail 2023-05-14 11:28:37 +03:00
parent 047ead6fa3
commit 4f54bb4bd7
15 changed files with 381 additions and 213 deletions

View file

@ -98,7 +98,7 @@ struct Namespace {
utils::IdType parent_namespace; utils::IdType parent_namespace;
std::optional<utils::IsConstModifier> modifier; // modifier => variable namespace utils::ClassInternalsModifier modifier;
std::string type_name; std::string type_name;
}; };

View file

@ -23,35 +23,35 @@ inline void PrintPosition(std::ostream& out,
inline void HandleParsingError(const std::string& message, inline void HandleParsingError(const std::string& message,
std::pair<size_t, size_t> start_position, std::pair<size_t, size_t> start_position,
std::pair<size_t, size_t> end_position) { std::pair<size_t, size_t> end_position) {
std::cout << "\x1b[1;31mParsing Error:\x1b[0m " << message << " at "; std::cerr << "\x1b[1;31mParsing Error:\x1b[0m " << message << " at ";
PrintPosition(std::cout, start_position, end_position); PrintPosition(std::cerr, start_position, end_position);
std::cout << ".\n"; std::cerr << ".\n";
exit(1); exit(1);
} }
inline void HandleGeneralError(const std::string& message) { inline void HandleGeneralError(const std::string& message) {
std::cout << "\x1b[1;31mGeneral Error:\x1b[0m " << message << ".\n"; std::cerr << "\x1b[1;31mGeneral Error:\x1b[0m " << message << ".\n";
exit(1); exit(1);
} }
inline void HandleInternalError(const std::string& message, const std::string& place) { inline void HandleInternalError(const std::string& message, const std::string& place) {
std::cout << "\x1b[1;31mInternal Error:\x1b[0m " << message << " at " << place << ".\n"; std::cerr << "\x1b[1;31mInternal Error:\x1b[0m " << message << " at " << place << ".\n";
exit(1); exit(1);
} }
inline void HandleTypecheckError(const std::string& message, inline void HandleTypecheckError(const std::string& message,
const interpreter::tokens::BaseNode& node) { const interpreter::tokens::BaseNode& node) {
std::cout << "\x1b[1;31mTypecheck Error:\x1b[0m " << message << " at "; std::cerr << "\x1b[1;31mTypecheck Error:\x1b[0m " << message << " at ";
PrintPosition(std::cout, node.start_position, node.end_position); PrintPosition(std::cerr, node.start_position, node.end_position);
std::cout << ".\n"; std::cerr << ".\n";
exit(1); exit(1);
} }
inline void HandleRuntimeError(const std::string& message, inline void HandleRuntimeError(const std::string& message,
const interpreter::tokens::BaseNode& node) { const interpreter::tokens::BaseNode& node) {
std::cout << "\x1b[1;31mRuntime Error:\x1b[0m " << message << " at "; std::cerr << "\x1b[1;31mRuntime Error:\x1b[0m " << message << " at ";
PrintPosition(std::cout, node.start_position, node.end_position); PrintPosition(std::cerr, node.start_position, node.end_position);
std::cout << ".\n"; std::cerr << ".\n";
exit(1); exit(1);
} }

View file

@ -1,6 +1,5 @@
#pragma once #pragma once
#include <asm-generic/errno.h>
#include <string> #include <string>
#include <functional> #include <functional>
#include <unordered_map> #include <unordered_map>
@ -8,6 +7,7 @@
// for clangd // for clangd
#include "definitions.hpp" #include "definitions.hpp"
#include "interpreter_tree.hpp" #include "interpreter_tree.hpp"
#include "typeclass_graph.hpp"
#include "utils.hpp" #include "utils.hpp"
namespace info { namespace info {
@ -40,11 +40,11 @@ public:
void AddImport(definition::Import&& import_info, const std::optional<std::string>& name = std::nullopt); void AddImport(definition::Import&& import_info, const std::optional<std::string>& name = std::nullopt);
void AddEnterNamespace(const std::string& name, void AddEnterNamespace(const std::string& name,
std::optional<utils::IsConstModifier> modifier, utils::ClassInternalsModifier modifier,
const interpreter::tokens::BaseNode& base_node); const interpreter::tokens::BaseNode& base_node);
void EnterNamespace(const std::string& name, void EnterNamespace(const std::string& name,
std::optional<utils::IsConstModifier> modifier); utils::ClassInternalsModifier modifier);
void ExitNamespace(); void ExitNamespace();
@ -77,28 +77,117 @@ public:
utils::IdType AddPartition(const std::vector<std::string>& path, // including name utils::IdType AddPartition(const std::vector<std::string>& path, // including name
interpreter::tokens::PartitionStatement* node); interpreter::tokens::PartitionStatement* node);
std::optional<utils::IdType> FindNamespace(const std::optional<std::vector<std::string>>& path); std::optional<utils::IdType> FindNamespaceId(const std::optional<std::vector<std::string>>& path);
std::optional<utils::IdType> FindFunction(const std::optional<std::vector<std::string>>& path, std::optional<utils::IdType> FindFunctionId(const std::optional<std::vector<std::string>>& path,
const std::string& name); const std::string& name);
std::optional<utils::IdType> FindMethod(const std::optional<std::vector<std::string>>& path, std::optional<utils::IdType> FindMethodId(const std::optional<std::vector<std::string>>& path,
const std::string& type, const std::string& type,
const std::string& name, const std::string& name,
utils::IsConstModifier modifier); utils::IsConstModifier modifier);
std::optional<utils::IdType> FindType(const std::optional<std::vector<std::string>>& path, std::optional<utils::IdType> FindTypeId(const std::optional<std::vector<std::string>>& path,
const std::string& type); const std::string& type);
std::optional<utils::IdType> FindLocalType(const std::string& type); std::optional<utils::IdType> FindLocalTypeId(const std::string& type);
std::optional<utils::IdType> FindAbstractType(const std::string& abstract_type); std::optional<utils::IdType> FindAbstractTypeId(const std::string& abstract_type);
std::optional<utils::IdType> FindTypeclass(const std::string& typeclass); std::optional<utils::IdType> FindTypeclassId(const std::string& typeclass);
std::optional<utils::IdType> FindConstructor(const std::optional<std::vector<std::string>>& path, std::optional<utils::IdType> FindConstructorId(const std::optional<std::vector<std::string>>& path,
const std::string& constructor); const std::string& constructor);
std::optional<definition::Namespace*> FindNamespace(const std::optional<std::vector<std::string>>& path) {
std::optional<utils::IdType> id = FindNamespaceId(path);
if (!id.has_value()) {
return std::nullopt;
}
return &global_info_.GetNamespaceInfo(id.value());
}
std::optional<definition::Function*> FindFunction(const std::optional<std::vector<std::string>>& path,
const std::string& name) {
std::optional<utils::IdType> id = FindFunctionId(path, name);
if (!id.has_value()) {
return std::nullopt;
}
return &global_info_.GetFunctionInfo(id.value());
}
std::optional<definition::Function*> FindMethod(const std::optional<std::vector<std::string>>& path,
const std::string& type,
const std::string& name,
utils::IsConstModifier modifier) {
std::optional<utils::IdType> id = FindFunctionId(path, name);
if (!id.has_value()) {
return std::nullopt;
}
return &global_info_.GetFunctionInfo(id.value());
}
std::optional<definition::Type*> FindAnyType(const std::optional<std::vector<std::string>>& path,
const std::string& type) {
std::optional<utils::IdType> id = FindTypeId(path, type);
if (!id.has_value()) {
return std::nullopt;
}
return &global_info_.GetAnyTypeInfo(id.value());
}
template<typename T>
std::optional<T*> FindType(const std::optional<std::vector<std::string>>& path,
const std::string& type) {
std::optional<utils::IdType> id = FindTypeId(path, type);
if (!id.has_value()) {
return std::nullopt;
}
return global_info_.GetTypeInfo<T>(id.value());
}
std::optional<definition::Type*> FindAnyLocalType(const std::string& type) {
std::optional<utils::IdType> id = FindLocalTypeId(type);
if (!id.has_value()) {
return std::nullopt;
}
return &global_info_.GetAnyTypeInfo(id.value());
}
template<typename T>
std::optional<T*> FindLocalType(const std::string& type) {
std::optional<utils::IdType> id = FindLocalTypeId(type);
if (!id.has_value()) {
return std::nullopt;
}
return global_info_.GetTypeInfo<T>(id.value());
}
std::optional<definition::AbstractType*> FindAbstractType(const std::string& abstract_type) {
std::optional<utils::IdType> id = FindAbstractTypeId(abstract_type);
if (!id.has_value()) {
return std::nullopt;
}
return &global_info_.GetAbstractTypeInfo(id.value());
}
std::optional<definition::Typeclass*> FindTypeclass(const std::string& typeclass) {
std::optional<utils::IdType> id = FindTypeclassId(typeclass);
if (!id.has_value()) {
return std::nullopt;
}
return &global_info_.GetTypeclassInfo(id.value());
}
std::optional<definition::Constructor*> FindConstructor(const std::optional<std::vector<std::string>>& path,
const std::string& constructor) {
std::optional<utils::IdType> id = FindConstructorId(path, constructor);
if (!id.has_value()) {
return std::nullopt;
}
return &global_info_.GetConstructorInfo(id.value());
}
NamespaceVisitor CreateVisitor() { NamespaceVisitor CreateVisitor() {
return global_info_.CreateVisitor(); return global_info_.CreateVisitor();
} }
@ -107,6 +196,10 @@ public:
return &global_info_; return &global_info_;
} }
TypeclassGraph* GetTypeclassGraph() {
return global_info_.GetTypeclassGraph();
}
const std::vector<std::string>& GetCurrentPath() { const std::vector<std::string>& GetCurrentPath() {
return current_path_; return current_path_;
} }
@ -128,7 +221,7 @@ public:
const std::vector<std::string>& path); const std::vector<std::string>& path);
std::unordered_map<std::string, utils::IdType>* std::unordered_map<std::string, utils::IdType>*
ChooseNamespaces(std::optional<utils::IsConstModifier> modifier, ChooseNamespaces(utils::ClassInternalsModifier modifier,
utils::IdType namespace_id); utils::IdType namespace_id);
private: private:
GlobalInfo& global_info_; GlobalInfo& global_info_;
@ -145,6 +238,10 @@ public:
return functions_.at(id); return functions_.at(id);
} }
definition::Type& GetAnyTypeInfo(utils::IdType id) {
return types_.at(id);
}
template<typename T> template<typename T>
std::optional<T*> GetTypeInfo(utils::IdType id) { std::optional<T*> GetTypeInfo(utils::IdType id) {
if (!std::holds_alternative<T>(types_.at(id).type)) { if (!std::holds_alternative<T>(types_.at(id).type)) {
@ -153,8 +250,8 @@ public:
return &std::get<T>(types_[id].type); return &std::get<T>(types_[id].type);
} }
definition::Type& GetAnyTypeInfo(utils::IdType id) { definition::AbstractType& GetAbstractTypeInfo(utils::IdType id) {
return types_.at(id); return abstract_types_.at(id);
} }
definition::Typeclass& GetTypeclassInfo(utils::IdType id) { definition::Typeclass& GetTypeclassInfo(utils::IdType id) {
@ -190,6 +287,10 @@ public:
return ans; return ans;
} }
TypeclassGraph* GetTypeclassGraph() {
return &typeclass_graph_;
}
private: private:
const utils::IdType GlobalNamespaceId = 0; const utils::IdType GlobalNamespaceId = 0;
@ -209,6 +310,8 @@ private:
std::vector<definition::Import> imports_; std::vector<definition::Import> imports_;
std::unordered_map<std::string, definition::Import> usages_; std::unordered_map<std::string, definition::Import> usages_;
TypeclassGraph typeclass_graph_;
}; };
} // namespace info } // namespace info

View file

@ -240,7 +240,6 @@ struct ParametrizedTypeclass;
struct ParametrizedType; struct ParametrizedType;
// Comments [IGNORE] -----------------
// Identifiers, constants, etc. ----------------- // Identifiers, constants, etc. -----------------
using Pattern = std::variant< using Pattern = std::variant<
@ -272,7 +271,7 @@ struct NamespaceSources {
struct Namespace { struct Namespace {
BaseNode base; BaseNode base;
std::optional<utils::IsConstModifier> modifier; // modifier => variable namespace utils::ClassInternalsModifier modifier;
TypeIdentifier type; TypeIdentifier type;
NamespaceSources scope; NamespaceSources scope;
@ -355,8 +354,8 @@ struct TypeclassDefinitionStatement {
BaseNode base; BaseNode base;
std::unique_ptr<TypeDefinition> definition; std::unique_ptr<TypeDefinition> definition;
std::vector<std::unique_ptr<FunctionDeclaration>> method_requirements; std::vector<std::pair<utils::ClassInternalsModifier,
std::vector<std::unique_ptr<FunctionDeclaration>> function_requirements; std::unique_ptr<FunctionDeclaration>>> requirements;
utils::IdType typeclass_id_; utils::IdType typeclass_id_;
}; };

View file

@ -2,9 +2,6 @@
#include <algorithm> #include <algorithm>
#include <string> #include <string>
#pragma once
#include <unordered_map> #include <unordered_map>
// for calngd // for calngd
@ -22,7 +19,12 @@ public:
struct ParametrizedTypeclass { struct ParametrizedTypeclass {
std::string typeclass; std::string typeclass;
// TODO: parameters std::vector<std::string> parameters; // only abstract types from owner
};
struct AnnotatedType {
std::string name;
std::vector<ParametrizedTypeclass> requirements;
}; };
struct TypeclassVertex { struct TypeclassVertex {
@ -31,16 +33,48 @@ public:
std::unordered_map<std::string, MethodInfo> methods; std::unordered_map<std::string, MethodInfo> methods;
std::vector<ParametrizedTypeclass> dependencies; std::vector<ParametrizedTypeclass> dependencies;
// TODO: std::vector<std::pair<std::string, std::vector<ParametrizedTypeclass>>> parameters; std::vector<AnnotatedType> parameters;
}; };
std::optional<utils::IdType> AddTypeclass( // // TODO: write + rewrite
// std::optional<utils::IdType> AddTypeclassByNode(interpreter::tokens::TypeclassDefinitionStatement* node) {
// std::string name = node->definition->type->type;
// std::vector<ParametrizedTypeclass> dependencies;
// // std::vector<std::pair<std::string, interpreter::tokens::FunctionDeclaration*>> function_declarations;
// // std::vector<std::pair<std::string, interpreter::tokens::FunctionDefinition*>> function_definitions;
// // std::vector<AnnotatedType> parameters;
//
// for (auto& dependency_node : node->definition->type->typeclasses) {
// ParametrizedTypeclass dependency;
// dependency.typeclass = dependency_node->typeclass;
// for (auto& dependency_parameter_node : dependency_node->parameters) { // TODO: all types, etc.
// dependency.parameters.push_back(dependency_parameter_node->type.type);
// if (dependency_parameter_node->type_id_.has_value()) { // TODO: more checks
// error_handling::HandleInternalError("Typeclasses with non-abstract parameters unimplemented",
// "TypeclassGraph.AddTypeclassByDefinition");
// }
// }
// dependencies.push_back(dependency);
// }
//
// // TODO
//
// return AddTypeclass(name,
// node,
// dependencies,
// function_declarations,
// function_definitions,
// parameters);
// }
std::optional<utils::IdType> AddTypeclass( // move parameters ??
const std::string& name, const std::string& name,
interpreter::tokens::TypeclassDefinitionStatement* definition, interpreter::tokens::TypeclassDefinitionStatement* definition,
const std::vector<ParametrizedTypeclass>& dependencies, const std::vector<ParametrizedTypeclass>& dependencies,
const std::vector<std::pair<std::string, interpreter::tokens::FunctionDeclaration*>>& method_declarations, const std::vector<std::pair<std::string, interpreter::tokens::FunctionDeclaration*>>& function_declarations,
const std::vector<std::pair<std::string, interpreter::tokens::FunctionDefinition*>>& method_definitions) { const std::vector<std::pair<std::string, interpreter::tokens::FunctionDefinition*>>& function_definitions,
for (auto& method : method_declarations) { const std::vector<AnnotatedType>& parameters) {
for (auto& method : function_declarations) {
if (method_to_typeclass_.count(method.first) != 0) { if (method_to_typeclass_.count(method.first) != 0) {
return std::nullopt; return std::nullopt;
} }
@ -53,14 +87,15 @@ public:
typeclass.name = name; typeclass.name = name;
typeclass.definition = definition; typeclass.definition = definition;
typeclass.dependencies = dependencies; typeclass.dependencies = dependencies;
typeclass.parameters = parameters;
for (auto& method : method_declarations) { for (auto& method : function_declarations) {
method_to_typeclass_[method.first] = typeclasses_.size(); method_to_typeclass_[method.first] = typeclasses_.size();
typeclass.methods[method.first].declaration = method.second; typeclass.methods[method.first].declaration = method.second;
} }
name_to_typeclass_[name] = typeclasses_.size() - 1; name_to_typeclass_[name] = typeclasses_.size() - 1;
for (auto& method : method_definitions) { for (auto& method : function_definitions) {
typeclass.methods[method.first].definition = method.second; typeclass.methods[method.first].definition = method.second;
} }

View file

@ -18,6 +18,7 @@ const size_t MaxOperatorPrecedence = 4;
enum class ReferenceModifier { Reference = 0, UniqueReference = 1, Dereference = 2 }; enum class ReferenceModifier { Reference = 0, UniqueReference = 1, Dereference = 2 };
enum class IsConstModifier { Const = 0, Var = 1 }; enum class IsConstModifier { Const = 0, Var = 1 };
enum class ClassInternalsModifier { Static = 0, Const = 1, Var = 2};
enum class ClassModifier { Struct = 0, Class = 1 }; enum class ClassModifier { Struct = 0, Class = 1 };
enum class AssignmentModifier { Assign = 0, Move = 1 }; enum class AssignmentModifier { Assign = 0, Move = 1 };
enum class AliasModifier { Alias = 0, Type = 1, Let = 2 }; enum class AliasModifier { Alias = 0, Type = 1, Let = 2 };
@ -33,8 +34,21 @@ inline ValueType IsConstModifierToValueType(IsConstModifier modifier) {
case IsConstModifier::Var: case IsConstModifier::Var:
return ValueType::Var; return ValueType::Var;
} }
// unreachable
exit(1); exit(1); // unreachable
}
inline ValueType ClassInternalsModifierToValueType(ClassInternalsModifier modifier) {
switch (modifier) {
case ClassInternalsModifier::Const:
return ValueType::Const;
case ClassInternalsModifier::Var:
return ValueType::Var;
case ClassInternalsModifier::Static:
throw std::bad_cast(); // ??
}
exit(1); // unreachable
} }
template<typename T> template<typename T>
@ -214,32 +228,32 @@ private:
std::vector<size_t> ranks_; std::vector<size_t> ranks_;
}; };
// static void BackVisitDfs(size_t id, static void BackVisitDfs(size_t id,
// std::vector<size_t>& verticles, std::vector<size_t>& verticles,
// std::vector<size_t>& marks, std::vector<size_t>& marks,
// const std::vector<std::vector<size_t>>& edges, const std::vector<std::vector<size_t>>& edges,
// size_t mark) { size_t mark) {
// if (marks[id] != 0) { if (marks[id] != 0) {
// return; return;
// } }
//
// marks[id] = mark; marks[id] = mark;
// verticles.push_back(id); verticles.push_back(id);
//
// for (size_t i = 0; i < edges[id].size(); ++i) { for (size_t i = 0; i < edges[id].size(); ++i) {
// BackVisitDfs(id, verticles, marks, edges, mark); BackVisitDfs(id, verticles, marks, edges, mark);
// } }
// } }
//
// static std::vector<size_t> BackTopSort(const std::vector<std::vector<size_t>>& edges_) { static std::vector<size_t> BackTopSort(const std::vector<std::vector<size_t>>& edges_) {
// std::vector<size_t> sorted_verticles; std::vector<size_t> sorted_verticles;
// std::vector<size_t> marks(edges_.size(), 0); std::vector<size_t> marks(edges_.size(), 0);
//
// for (size_t i = 0; i < marks.size(); ++i) { for (size_t i = 0; i < marks.size(); ++i) {
// BackVisitDfs(i, sorted_verticles, marks, edges_, 1); BackVisitDfs(i, sorted_verticles, marks, edges_, 1);
// } }
//
// return sorted_verticles; return sorted_verticles;
// } }
} // namespace utils } // namespace utils

@ -1 +1 @@
Subproject commit 3610504b4ce142fe30f47851709fef6bc2fc53f1 Subproject commit 630eced5368dca21af5eb2b6bea7f90651ce5e30

View file

@ -58,12 +58,14 @@ void BuildVisitor::Visit(Namespace* node) {
if (child_count > 3) { // "namespace", ["var"/"const",] type, scope if (child_count > 3) { // "namespace", ["var"/"const",] type, scope
std::string modifier = parse_node.NthChild(1).GetValue(); std::string modifier = parse_node.NthChild(1).GetValue();
if (modifier == "const") { if (modifier == "const") {
node->modifier = utils::IsConstModifier::Const; node->modifier = utils::ClassInternalsModifier::Const;
} else if (modifier == "var") { } else if (modifier == "var") {
node->modifier = utils::IsConstModifier::Var; node->modifier = utils::ClassInternalsModifier::Var;
} else { } else {
error_handling::HandleInternalError("Can't parse namespace modifier", "BuildVisitor.Namespace"); error_handling::HandleInternalError("Can't parse namespace modifier", "BuildVisitor.Namespace");
} }
} else {
node->modifier = utils::ClassInternalsModifier::Static;
} }
node->type = parse_node.ChildByFieldName("type").GetValue(); node->type = parse_node.ChildByFieldName("type").GetValue();
@ -273,15 +275,26 @@ void BuildVisitor::Visit(TypeclassDefinitionStatement* node) {
size_t child_count = parse_node.NamedChildCount(); size_t child_count = parse_node.NamedChildCount();
if (child_count > 1) {
node->requirements.reserve(child_count - 1);
for (size_t i = 0; i + 1 < child_count; ++i) { for (size_t i = 0; i + 1 < child_count; ++i) {
current_node_ = parse_node.NthNamedChild(i + 1); current_node_ = parse_node.NthNamedChild(i + 1);
if (current_node_.PreviousSibling().GetValue() != "var") {
node->function_requirements.push_back(std::make_unique<FunctionDeclaration>()); std::string modifier_name = current_node_.PreviousSibling().GetValue();
Visit(node->function_requirements.back().get()); utils::ClassInternalsModifier modifier;
if (modifier_name == "const") {
modifier = utils::ClassInternalsModifier::Const;
} else if (modifier_name == "var") {
modifier = utils::ClassInternalsModifier::Var;
} else { } else {
node->method_requirements.push_back(std::make_unique<FunctionDeclaration>()); modifier = utils::ClassInternalsModifier::Static;
Visit(node->method_requirements.back().get());
} }
node->requirements.push_back({modifier,
std::make_unique<FunctionDeclaration>()});
Visit(node->requirements.back().second.get());
}
} }
current_node_ = parse_node; current_node_ = parse_node;

View file

@ -135,17 +135,11 @@ void FindSymbolsVisitor::Visit(TypeclassDefinitionStatement* node) {
current_info_.reset(); current_info_.reset();
} }
namespace_visitor_.AddEnterNamespace(type_name, std::nullopt, node->base); for (size_t i = 0; i < node->requirements.size(); ++i) {
for (size_t i = 0; i < node->function_requirements.size(); ++i) { namespace_visitor_.AddEnterNamespace(type_name, node->requirements[i].first, node->base);
Visit(node->function_requirements[i].get()); Visit(node->requirements[i].second.get());
}
namespace_visitor_.ExitNamespace(); namespace_visitor_.ExitNamespace();
namespace_visitor_.AddEnterNamespace(type_name, utils::IsConstModifier::Var, node->base);
for (size_t i = 0; i < node->method_requirements.size(); ++i) {
Visit(node->method_requirements[i].get());
} }
namespace_visitor_.ExitNamespace();
info.node = node; info.node = node;

View file

@ -18,7 +18,7 @@ void GlobalInfo::NamespaceVisitor::AddImport(definition::Import&& import_info,
} }
void GlobalInfo::NamespaceVisitor::AddEnterNamespace(const std::string& name, void GlobalInfo::NamespaceVisitor::AddEnterNamespace(const std::string& name,
std::optional<utils::IsConstModifier> modifier, utils::ClassInternalsModifier modifier,
const interpreter::tokens::BaseNode& base_node) { const interpreter::tokens::BaseNode& base_node) {
if (type::ToInternalType(name).has_value()) { if (type::ToInternalType(name).has_value()) {
error_handling::HandleTypecheckError("Can't define basic type namespace", base_node); error_handling::HandleTypecheckError("Can't define basic type namespace", base_node);
@ -38,7 +38,7 @@ void GlobalInfo::NamespaceVisitor::AddEnterNamespace(const std::string& name,
} }
definition::Namespace* namespace_info = &global_info_.namespaces_[id]; definition::Namespace* namespace_info = &global_info_.namespaces_[id];
if (modifier.has_value()) { if (modifier != utils::ClassInternalsModifier::Static) {
namespace_info->modifier = modifier; namespace_info->modifier = modifier;
} }
@ -51,7 +51,7 @@ void GlobalInfo::NamespaceVisitor::AddEnterNamespace(const std::string& name,
} }
void GlobalInfo::NamespaceVisitor::EnterNamespace(const std::string& name, void GlobalInfo::NamespaceVisitor::EnterNamespace(const std::string& name,
std::optional<utils::IsConstModifier> modifier) { utils::ClassInternalsModifier modifier) {
for (ssize_t i = (ssize_t)namespace_stack_.size() - 1; i >= 0; --i) { for (ssize_t i = (ssize_t)namespace_stack_.size() - 1; i >= 0; --i) {
auto current_namespaces = ChooseNamespaces(modifier, i); auto current_namespaces = ChooseNamespaces(modifier, i);
auto namespace_iter = current_namespaces->find(name); auto namespace_iter = current_namespaces->find(name);
@ -222,6 +222,7 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddAbstractType(const std::string& a
return id; return id;
} }
// TODO: which info needed ??
utils::IdType GlobalInfo::NamespaceVisitor::AddTypeclass(const std::string& typeclass, utils::IdType GlobalInfo::NamespaceVisitor::AddTypeclass(const std::string& typeclass,
definition::Typeclass&& typeclass_info, definition::Typeclass&& typeclass_info,
const interpreter::tokens::BaseNode& base_node) { const interpreter::tokens::BaseNode& base_node) {
@ -237,6 +238,12 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddTypeclass(const std::string& type
global_info_.name_to_typeclass_[typeclass] = id; global_info_.name_to_typeclass_[typeclass] = id;
global_info_.typeclasses_.push_back(std::move(typeclass_info)); 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; return id;
} }
@ -282,14 +289,14 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddPartition(const std::vector<std::
return id; return id;
} }
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindNamespace(const std::optional<std::vector<std::string>>& path) { std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindNamespaceId(const std::optional<std::vector<std::string>>& path) {
return FindSomething<utils::IdType>(path, return FindSomething<utils::IdType>(path,
[] (utils::IdType current_namespace) -> std::optional<utils::IdType> { [] (utils::IdType current_namespace) -> std::optional<utils::IdType> {
return current_namespace; return current_namespace;
}); });
} }
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindFunction( std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindFunctionId(
const std::optional<std::vector<std::string>>& path, const std::optional<std::vector<std::string>>& path,
const std::string& name) { const std::string& name) {
return FindSomething<utils::IdType>(path, return FindSomething<utils::IdType>(path,
@ -304,7 +311,7 @@ std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindFunction(
}); });
} }
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindMethod( std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindMethodId(
const std::optional<std::vector<std::string>>& path, const std::optional<std::vector<std::string>>& path,
const std::string& type, const std::string& type,
const std::string& name, const std::string& name,
@ -335,7 +342,7 @@ std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindMethod(
}); });
} }
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindType( std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindTypeId(
const std::optional<std::vector<std::string>>& path, const std::optional<std::vector<std::string>>& path,
const std::string& type) { const std::string& type) {
return FindSomething<utils::IdType>(path, return FindSomething<utils::IdType>(path,
@ -350,7 +357,7 @@ std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindType(
}); });
} }
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindLocalType(const std::string& type) { std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindLocalTypeId(const std::string& type) {
auto type_id_iter = global_info_.namespaces_[namespace_stack_.back()].types.find(type); auto type_id_iter = global_info_.namespaces_[namespace_stack_.back()].types.find(type);
if (type_id_iter != global_info_.namespaces_[namespace_stack_.back()].types.end()) { if (type_id_iter != global_info_.namespaces_[namespace_stack_.back()].types.end()) {
@ -360,7 +367,7 @@ std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindLocalType(const s
return std::nullopt; return std::nullopt;
} }
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindAbstractType(const std::string& abstract_type) { std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindAbstractTypeId(const std::string& abstract_type) {
auto abstract_type_id_iter = global_info_.name_to_abstract_type_.find(abstract_type); auto abstract_type_id_iter = global_info_.name_to_abstract_type_.find(abstract_type);
if (abstract_type_id_iter != global_info_.name_to_abstract_type_.end()) { if (abstract_type_id_iter != global_info_.name_to_abstract_type_.end()) {
@ -370,7 +377,7 @@ std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindAbstractType(cons
return std::nullopt; return std::nullopt;
} }
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindTypeclass(const std::string& typeclass) { std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindTypeclassId(const std::string& typeclass) {
auto typeclass_id_iter = global_info_.name_to_typeclass_.find(typeclass); auto typeclass_id_iter = global_info_.name_to_typeclass_.find(typeclass);
if (typeclass_id_iter != global_info_.name_to_typeclass_.end()) { if (typeclass_id_iter != global_info_.name_to_typeclass_.end()) {
@ -380,7 +387,7 @@ std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindTypeclass(const s
return std::nullopt; return std::nullopt;
} }
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindConstructor( std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindConstructorId(
const std::optional<std::vector<std::string>>& path, const std::optional<std::vector<std::string>>& path,
const std::string& constructor) { const std::string& constructor) {
return FindSomething<utils::IdType>(path, return FindSomething<utils::IdType>(path,
@ -439,17 +446,19 @@ std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindNamespaceIn(
} }
std::unordered_map<std::string, utils::IdType>* std::unordered_map<std::string, utils::IdType>*
GlobalInfo::NamespaceVisitor::ChooseNamespaces(std::optional<utils::IsConstModifier> modifier, GlobalInfo::NamespaceVisitor::ChooseNamespaces(utils::ClassInternalsModifier modifier,
utils::IdType namespace_id) { utils::IdType namespace_id) {
std::unordered_map<std::string, utils::IdType>* current_namespaces = nullptr; std::unordered_map<std::string, utils::IdType>* current_namespaces = nullptr;
if (modifier.has_value()) { switch (modifier) {
if (modifier.value() == utils::IsConstModifier::Const) { case utils::ClassInternalsModifier::Const:
current_namespaces = &global_info_.namespaces_[namespace_id].const_namespaces; current_namespaces = &global_info_.namespaces_[namespace_id].const_namespaces;
} else { break;
case utils::ClassInternalsModifier::Var:
current_namespaces = &global_info_.namespaces_[namespace_id].var_namespaces; current_namespaces = &global_info_.namespaces_[namespace_id].var_namespaces;
} break;
} else { case utils::ClassInternalsModifier::Static:
current_namespaces = &global_info_.namespaces_[namespace_id].namespaces; current_namespaces = &global_info_.namespaces_[namespace_id].namespaces;
break;
} }
return current_namespaces; return current_namespaces;

View file

@ -12,11 +12,11 @@ namespace interpreter {
void LinkSymbolsVisitor::Visit(Namespace* node) { void LinkSymbolsVisitor::Visit(Namespace* node) {
// Visitor::Visit(&node->type); // not needed // Visitor::Visit(&node->type); // not needed
std::optional<utils::IdType> maybe_type = namespace_visitor_.FindLocalType(node->type); std::optional<utils::IdType> maybe_type = namespace_visitor_.FindLocalTypeId(node->type);
std::optional<utils::IdType> maybe_typeclass; std::optional<utils::IdType> maybe_typeclass;
if (namespace_visitor_.GetCurrentPath().size() == 0) { if (namespace_visitor_.GetCurrentPath().size() == 0) {
maybe_typeclass = namespace_visitor_.FindTypeclass(node->type); maybe_typeclass = namespace_visitor_.FindTypeclassId(node->type);
} }
if (maybe_type.has_value() && maybe_typeclass.has_value()) { if (maybe_type.has_value() && maybe_typeclass.has_value()) {
@ -49,8 +49,8 @@ void LinkSymbolsVisitor::Visit(TypeExpression* node) { // TODO: check
path.push_back(path_type.type); path.push_back(path_type.type);
} }
node->type_id_ = namespace_visitor_.FindType(path, node->type.type); node->type_id_ = namespace_visitor_.FindTypeId(path, node->type.type);
node->constructor_id_ = namespace_visitor_.FindConstructor(path, node->type.type); node->constructor_id_ = namespace_visitor_.FindConstructorId(path, node->type.type);
// internal type // internal type
if (info::type::ToInternalType(node->type.type).has_value()) { if (info::type::ToInternalType(node->type.type).has_value()) {
@ -91,9 +91,9 @@ void LinkSymbolsVisitor::Visit(TypeExpression* node) { // TODO: check
node->type.type_id_ = node->type_id_.value(); node->type.type_id_ = node->type_id_.value();
} }
std::optional<utils::IdType> maybe_type_namespace = namespace_visitor_.FindNamespace(path); std::optional<info::definition::Namespace*> maybe_type_namespace = namespace_visitor_.FindNamespace(path);
if (maybe_type_namespace.has_value()) { if (maybe_type_namespace.has_value()) {
info::definition::Namespace* type_namespace = &namespace_visitor_.GetGlobalInfo()->GetNamespaceInfo(maybe_type_namespace.value()); info::definition::Namespace* type_namespace = maybe_type_namespace.value();
for (ssize_t i = (ssize_t)node->path.size(); i >= 0; --i) { for (ssize_t i = (ssize_t)node->path.size(); i >= 0; --i) {
info::definition::Namespace* parent_namespace = &namespace_visitor_.GetGlobalInfo()->GetNamespaceInfo(type_namespace->parent_namespace); info::definition::Namespace* parent_namespace = &namespace_visitor_.GetGlobalInfo()->GetNamespaceInfo(type_namespace->parent_namespace);
@ -111,7 +111,7 @@ void LinkSymbolsVisitor::Visit(TypeExpression* node) { // TODO: check
// Typeclass // Typeclass
void LinkSymbolsVisitor::Visit(ParametrizedTypeclass* node) { // TODO: check void LinkSymbolsVisitor::Visit(ParametrizedTypeclass* node) { // TODO: check
std::optional<utils::IdType> maybe_typeclass = namespace_visitor_.FindTypeclass(node->typeclass); std::optional<utils::IdType> maybe_typeclass = namespace_visitor_.FindTypeclassId(node->typeclass);
if (maybe_typeclass.has_value()) { if (maybe_typeclass.has_value()) {
node->typeclass_id_ = maybe_typeclass.value(); node->typeclass_id_ = maybe_typeclass.value();

View file

@ -25,15 +25,15 @@ void PrintVisitor::Visit(NamespaceSources* node) {
void PrintVisitor::Visit(Namespace* node) { void PrintVisitor::Visit(Namespace* node) {
out_ << "[Namespace] "; out_ << "[Namespace] ";
if (node->modifier.has_value()) { switch (node->modifier) {
switch (node->modifier.value()) { case utils::ClassInternalsModifier::Const:
case utils::IsConstModifier::Const:
out_ << "const "; out_ << "const ";
break; break;
case utils::IsConstModifier::Var: case utils::ClassInternalsModifier::Var:
out_ << "var "; out_ << "var ";
break; break;
} case utils::ClassInternalsModifier::Static:
break;
} }
Visit(&node->type); Visit(&node->type);
out_ << "{\n"; out_ << "{\n";
@ -157,20 +157,22 @@ void PrintVisitor::Visit(AbstractTypeDefinitionStatement* node) {
void PrintVisitor::Visit(TypeclassDefinitionStatement* node) { void PrintVisitor::Visit(TypeclassDefinitionStatement* node) {
out_ << "[Typeclass] ("; out_ << "[Typeclass] (";
Visit(node->definition.get()); Visit(node->definition.get());
if (!node->function_requirements.empty()) { if (!node->requirements.empty()) {
out_ << ") : (\n"; out_ << ") : (\n";
} }
for (auto& requirement : node->function_requirements) { for (auto& requirement : node->requirements) {
out_ << "& "; out_ << "& ";
Visit(requirement.get()); switch (requirement.first) {
out_ << "\n"; case utils::ClassInternalsModifier::Const:
out_ << "const ";
break;
case utils::ClassInternalsModifier::Var:
out_ << "var ";
break;
case utils::ClassInternalsModifier::Static:
break;
} }
if (!node->method_requirements.empty()) { Visit(requirement.second.get());
out_ << ") : (\n";
}
for (auto& requirement : node->method_requirements) {
out_ << "& var ";
Visit(requirement.get());
out_ << "\n"; out_ << "\n";
} }
out_ << ")\n"; out_ << ")\n";

View file

@ -38,9 +38,9 @@ void TypeCheckVisitor::Visit(Namespace* node) { // TODO: two var namespces for c
std::vector<utils::IdType> requirements {node->link_typeclass_id_.value()}; std::vector<utils::IdType> requirements {node->link_typeclass_id_.value()};
utils::IdType abstract_type = context_manager_.AddValue( utils::IdType abstract_type = context_manager_.AddValue(
info::type::AbstractType(utils::AbstractTypeModifier::Abstract, node->type, requirements), info::type::AbstractType(utils::AbstractTypeModifier::Abstract, node->type, requirements),
IsConstModifierToValueType(node->modifier.value())); ClassInternalsModifierToValueType(node->modifier));
if (node->modifier.has_value()) { if (node->modifier != utils::ClassInternalsModifier::Static) {
context_manager_.EnterVariableContext(utils::ClassInternalVarName, context_manager_.EnterVariableContext(utils::ClassInternalVarName,
abstract_type); abstract_type);
} else { } else {
@ -48,7 +48,7 @@ void TypeCheckVisitor::Visit(Namespace* node) { // TODO: two var namespces for c
} }
context_manager_.DefineLocalType(node->type, abstract_type); context_manager_.DefineLocalType(node->type, abstract_type);
} else if (node->link_type_id_.has_value()) { } else if (node->link_type_id_.has_value()) {
if (node->modifier.has_value()) { if (node->modifier != utils::ClassInternalsModifier::Static) {
auto maybe_type_info = namespace_visitor_.GetGlobalInfo()->GetTypeInfo<info::definition::AnyType>(node->link_type_id_.value()); auto maybe_type_info = namespace_visitor_.GetGlobalInfo()->GetTypeInfo<info::definition::AnyType>(node->link_type_id_.value());
if (!maybe_type_info.has_value()) { if (!maybe_type_info.has_value()) {
@ -64,7 +64,7 @@ void TypeCheckVisitor::Visit(Namespace* node) { // TODO: two var namespces for c
current_type_, current_type_,
maybe_type_info.value()->modifier, maybe_type_info.value()->modifier,
context_manager_.GetValueManager()), context_manager_.GetValueManager()),
IsConstModifierToValueType(node->modifier.value()))); ClassInternalsModifierToValueType(node->modifier)));
} else { } else {
context_manager_.EnterContext(); context_manager_.EnterContext();
} }
@ -599,7 +599,7 @@ void TypeCheckVisitor::Visit(LoopControlExpression& node) { // enum
// TODO: better structure // TODO: better structure
void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) { void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) {
// TODO: Check, that type is not abstract ?? // TODO: Check, that type is not abstract ??
auto maybe_operator_id = namespace_visitor_.FindFunction(std::nullopt, node->operator_name); auto maybe_operator_id = namespace_visitor_.FindFunctionId(std::nullopt, node->operator_name);
info::definition::Function* operator_info = nullptr; info::definition::Function* operator_info = nullptr;
node->is_method_ = false; node->is_method_ = false;
@ -621,13 +621,13 @@ void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) {
std::string left_type_name = maybe_left_type_info.value()->type.type; std::string left_type_name = maybe_left_type_info.value()->type.type;
auto maybe_const_operator_id = namespace_visitor_.FindMethod(std::nullopt, auto maybe_const_operator_id = namespace_visitor_.FindMethodId(std::nullopt,
left_type_name, left_type_name,
node->operator_name, node->operator_name,
utils::IsConstModifier::Const); utils::IsConstModifier::Const);
if (left_value_type != utils::ValueType::Const) { if (left_value_type != utils::ValueType::Const) {
maybe_operator_id = namespace_visitor_.FindMethod(std::nullopt, maybe_operator_id = namespace_visitor_.FindMethodId(std::nullopt,
left_type_name, left_type_name,
node->operator_name, node->operator_name,
utils::IsConstModifier::Var); utils::IsConstModifier::Var);
@ -795,14 +795,14 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
} }
path.push_back(type_expression.type.type); path.push_back(type_expression.type.type);
maybe_function_id = namespace_visitor_.FindFunction(path, node->name); maybe_function_id = namespace_visitor_.FindFunctionId(path, node->name);
CollectTypeExpressionContext(*std::get<std::unique_ptr<TypeExpression>>(node->prefix.value()), context); CollectTypeExpressionContext(*std::get<std::unique_ptr<TypeExpression>>(node->prefix.value()), context);
} else { } else {
// error // error
} }
} else { } else {
maybe_function_id = namespace_visitor_.FindFunction(std::nullopt, node->name); maybe_function_id = namespace_visitor_.FindFunctionId(std::nullopt, node->name);
} }
if (!maybe_function_id.has_value()) { if (!maybe_function_id.has_value()) {

View file

@ -43,15 +43,15 @@ void TypedPrintVisitor::Visit(Namespace* node) {
} }
out_ << "] "; out_ << "] ";
if (node->modifier.has_value()) { switch (node->modifier) {
switch (node->modifier.value()) { case utils::ClassInternalsModifier::Const:
case utils::IsConstModifier::Const:
out_ << "const "; out_ << "const ";
break; break;
case utils::IsConstModifier::Var: case utils::ClassInternalsModifier::Var:
out_ << "var "; out_ << "var ";
break; break;
} case utils::ClassInternalsModifier::Static:
break;
} }
Visit(&node->type); Visit(&node->type);
out_ << "{\n"; out_ << "{\n";
@ -218,20 +218,22 @@ void TypedPrintVisitor::Visit(TypeclassDefinitionStatement* node) {
out_ << "] ("; out_ << "] (";
Visit(node->definition.get()); Visit(node->definition.get());
if (!node->function_requirements.empty()) { if (!node->requirements.empty()) {
out_ << ") : (\n"; out_ << ") : (\n";
} }
for (auto& requirement : node->function_requirements) { for (auto& requirement : node->requirements) {
out_ << "& "; out_ << "& ";
Visit(requirement.get()); switch (requirement.first) {
out_ << "\n"; case utils::ClassInternalsModifier::Const:
out_ << "const ";
break;
case utils::ClassInternalsModifier::Var:
out_ << "var ";
break;
case utils::ClassInternalsModifier::Static:
break;
} }
if (!node->method_requirements.empty()) { Visit(requirement.second.get());
out_ << ") : (\n";
}
for (auto& requirement : node->method_requirements) {
out_ << "& var ";
Visit(requirement.get());
out_ << "\n"; out_ << "\n";
} }
out_ << ")\n"; out_ << ")\n";

View file

@ -357,11 +357,8 @@ void Visitor::Visit(AbstractTypeDefinitionStatement* node) {
void Visitor::Visit(TypeclassDefinitionStatement* node) { void Visitor::Visit(TypeclassDefinitionStatement* node) {
Visit(node->definition.get()); Visit(node->definition.get());
for (auto& function_requirement : node->function_requirements) { for (auto& function_requirement : node->requirements) {
Visit(function_requirement.get()); Visit(function_requirement.second.get());
}
for (auto& method_requirement : node->method_requirements) {
Visit(method_requirement.get());
} }
} }