diff --git a/include/definitions.hpp b/include/definitions.hpp index 8b2fb76..bdf1b3b 100644 --- a/include/definitions.hpp +++ b/include/definitions.hpp @@ -45,7 +45,7 @@ struct AnyType { }; struct Type { - std::variant type; + std::variant type; }; struct Constructor { @@ -85,7 +85,6 @@ struct Namespace { enum Modifier { Const, Var }; std::unordered_map types; - std::unordered_map typeclasses; std::unordered_map functions; std::unordered_map constructors; std::unordered_map namespaces; diff --git a/include/global_info.hpp b/include/global_info.hpp index f672a4e..b33dc79 100644 --- a/include/global_info.hpp +++ b/include/global_info.hpp @@ -6,7 +6,6 @@ // for clangd #include "definitions.hpp" -#include "type_manager.hpp" #include "utils.hpp" namespace info { @@ -38,6 +37,9 @@ public: utils::IdType AddType(const std::string& type, definition::Type&& type_info); + utils::IdType AddAbstractType(const std::string& abstract_type, + definition::AbstractType&& abstract_type_info); + utils::IdType AddTypeclass(const std::string& typeclass, definition::Typeclass&& typeclass_info); utils::IdType AddConstructor(const std::string& constructor, @@ -55,20 +57,17 @@ public: std::optional FindType(const std::optional>& path, const std::string& type); - std::optional FindTypeclass(const std::optional>& path, - const std::string& typeclass); + std::optional FindAbstractType(const std::string& abstract_type); + + std::optional FindTypeclass(const std::string& typeclass); std::optional FindConstructor(const std::optional>& path, - const std::string& typeclass); + const std::string& constructor); NamespaceVisitor CreateVisitor() { return global_info_.CreateVisitor(); } - type::TypeManager* GetTypeManager() { - return global_info_.GetTypeManager(); - } - GlobalInfo* GetGlobalInfo() { return &global_info_; } @@ -97,10 +96,6 @@ public: return NamespaceVisitor(*this); } - type::TypeManager* GetTypeManager() { - return &type_manager_; - } - // TODO: remember about vector realloc definition::Function* GetFunctionInfo(utils::IdType id) { return &functions_[id]; @@ -124,10 +119,12 @@ public: private: std::vector functions_; std::vector types_; + std::vector abstract_types_; std::vector typeclasses_; std::vector constructors_; - type::TypeManager type_manager_; + std::unordered_map name_to_typeclass_; + std::unordered_map name_to_abstract_type_; definition::Namespace global_namespace_; std::vector imports_; diff --git a/include/interpreter_tree.hpp b/include/interpreter_tree.hpp index 48b16b7..50770d5 100644 --- a/include/interpreter_tree.hpp +++ b/include/interpreter_tree.hpp @@ -297,7 +297,8 @@ struct Namespace { TypeIdentifier type; NamespaceSources scope; - std::optional type_id_; + std::optional link_type_id_; + std::optional link_typeclass_id_; }; // ----------------- Definitions ----------------- @@ -570,7 +571,7 @@ struct ExtendedScopedAnyType { struct TypeclassExpression { TypeclassSubExpression typeclass; - utils::IdType type_id_; + utils::IdType typeclass_id_; }; struct ParametrizedTypeclass { diff --git a/include/link_symbols_visitor.hpp b/include/link_symbols_visitor.hpp index beb43c9..30c1a25 100644 --- a/include/link_symbols_visitor.hpp +++ b/include/link_symbols_visitor.hpp @@ -17,30 +17,30 @@ public: private: // Sources ----------------- - void Visit(SourceFile* node) override; + // // void Visit(SourceFile* node) override; // Namespaces, partitions ----------------- - void Visit(PartitionSources* node) override; - void Visit(Partition* node) override; - void Visit(NamespaceSources* node) override; + // // void Visit(PartitionSources* node) override; + // // void Visit(Partition* node) override; + // // void Visit(NamespaceSources* node) override; void Visit(Namespace* node) override; // Definitions ----------------- - void Visit(ImportStatement* node) override; - void Visit(AliasDefinitionStatement* node) override; - void Visit(VariableDefinitionStatement* node) override; - void Visit(FunctionDeclaration* node) override; - void Visit(FunctionDefinitionStatement* node) override; - void Visit(TypeDefinitionStatement* node) override; - void Visit(AbstractTypeDefinitionStatement* node) override; - void Visit(TypeclassDefinitionStatement* node) override; + // // void Visit(ImportStatement* node) override; + // // void Visit(AliasDefinitionStatement* node) override; + // // void Visit(VariableDefinitionStatement* node) override; + // // void Visit(FunctionDeclaration* node) override; + // // void Visit(FunctionDefinitionStatement* node) override; + // // void Visit(TypeDefinitionStatement* node) override; + // // void Visit(AbstractTypeDefinitionStatement* node) override; + // // void Visit(TypeclassDefinitionStatement* node) override; // Definition parts - void Visit(FunctionDefinition* node) override; - void Visit(TypeDefinition* node) override; + // // void Visit(FunctionDefinition* node) override; + // // void Visit(TypeDefinition* node) override; // // void Visit(AnyAnnotatedType* node) override; // Flow control ----------------- @@ -76,7 +76,7 @@ private: // // void Visit(ReturnExpression* node) override; // // void Visit(TypeConstructorParameter* node) override; // // void Visit(TypeConstructor* node) override; - void Visit(LambdaFunction* node) override; + // // void Visit(LambdaFunction* node) override; // // void Visit(ArrayExpression* node) override; // // void Visit(LoopControlExpression& node) override; // enum @@ -95,13 +95,13 @@ private: // // void Visit(FunctionType* node) override; // // void Visit(TupleType* node) override; // // void Visit(VariantType* node) override; - void Visit(TypeExpression* node) override; // TODO + void Visit(TypeExpression* node) override; // // void Visit(ExtendedScopedAnyType* node) override; // Typeclass - void Visit(TypeclassExpression* node) override; // TODO + void Visit(TypeclassExpression* node) override; // // void Visit(ParametrizedTypeclass* node) override; // Typeclass & Type diff --git a/include/type_check_visitor.hpp b/include/type_check_visitor.hpp index 299e247..4751152 100644 --- a/include/type_check_visitor.hpp +++ b/include/type_check_visitor.hpp @@ -10,8 +10,8 @@ namespace interpreter { class TypeCheckVisitor : public Visitor { public: - explicit TypeCheckVisitor(info::GlobalInfo& global_info) - : namespace_visitor_(global_info.CreateVisitor()) {} + explicit TypeCheckVisitor(info::GlobalInfo& global_info, info::TypeInfoContextManager& context_manager) + : namespace_visitor_(global_info.CreateVisitor()), context_manager_(context_manager) {} private: // Sources ----------------- @@ -122,7 +122,7 @@ private: private: info::GlobalInfo::NamespaceVisitor namespace_visitor_; - info::TypeInfoContextManager context_manager_; + info::TypeInfoContextManager& context_manager_; utils::IdType current_type_; std::optional returned_type_; diff --git a/include/type_info_contexts.hpp b/include/type_info_contexts.hpp index 337e0bb..24be4ad 100644 --- a/include/type_info_contexts.hpp +++ b/include/type_info_contexts.hpp @@ -1,11 +1,13 @@ #pragma once +#include #include #include #include // for clangd -#include "types_info.hpp" +#include "error_handling.hpp" +#include "types.hpp" #include "utils.hpp" namespace info { @@ -13,32 +15,10 @@ namespace info { // TODO: remember about typespointers class TypeInfoContextManager { public: - template - utils::IdType AddType(T&& type) { - types_.push_back(std::forward(type)); - return types_.size() - 1; + type::TypeManager* GetTypeManager() { + return &type_manager_; } - const info::type::Type& GetType(utils::IdType type_id) { - return types_[type_id]; - } - - void AddTypeRequirement(utils::IdType type, utils::IdType requrement) {} // TODO - void EqualTypes(utils::IdType first_type, utils::IdType second_type) {} // TODO - - // void CallFunction(const std::vector& names, - // const std::vector& argument_types) { - // if (names.size() != argument_types.size()) { - // // error - // } - // - // contexts_.emplace_back(true); - // - // for (size_t i = 0; i < names.size(); ++i) { - // DefineVariable(names[i], argument_types[i]); - // } - // } - void EnterContext() { contexts_.emplace_back(false); } @@ -60,6 +40,10 @@ public: return contexts_.back().DefineVariable(name, type_id); } + bool DefineLocalAbstractType() { + // TODO + } + bool RemoveVariable(const std::string& name) { for (ssize_t i = (ssize_t)contexts_.size() - 1; i >= 0; --i) { if (contexts_[i].RemoveVariable(name)) { @@ -120,7 +104,7 @@ private: }; std::vector contexts_; - std::vector types_; + type::TypeManager type_manager_; }; } // namespace info diff --git a/include/type_manager.hpp b/include/type_manager.hpp deleted file mode 100644 index 4d33d4d..0000000 --- a/include/type_manager.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include - -// for clangd -#include "types.hpp" -#include "utils.hpp" - -namespace info::type { - -class TypeManager { -public: - template - void AddType(const T& type) { - types_.emplace(type); - } - - template - T GetType(utils::IdType type_id) { - return std::get(types_.at(type_id)); - } -private: - std::vector types_; -}; - -} // namespace info::type diff --git a/include/types.hpp b/include/types.hpp index 72d546f..0c0a358 100644 --- a/include/types.hpp +++ b/include/types.hpp @@ -4,68 +4,195 @@ #include #include #include +#include // for clangd #include "utils.hpp" namespace info::type { -// // Temporary frozen, TODO -// struct AbstractType { -// utils::IdType graph_id; -// std::vector paramaters; -// }; +// TODO: move in constructors -// TODO: check, if defined type is variant, etc. -struct DefinedType { - utils::IdType type_id; // in defined types - utils::IdType type; // in types manager, created using context types +class TypeManager; + +class AbstractType { // later will be found in context +public: + AbstractType() = default; + AbstractType(const std::string& name, + const std::vector& requirements) : name_(name) { + for (auto& typeclass : requirements) { + requirements_.insert(typeclass); + } + } + + bool Same(const AbstractType& type) const; + bool operator<(const AbstractType& type) const; + bool operator>(const AbstractType& type) const; +private: + std::string name_; + std::unordered_set requirements_; // TODO: all typeclasses from tree +}; + +class DefinedType { +public: + DefinedType() = default; + DefinedType(utils::IdType type_id, + utils::IdType type, + TypeManager* type_manager) + : type_id_(type_id), type_(type), type_manager_(type_manager) {} + + bool Same(const DefinedType& type) const; + bool operator<(const DefinedType& type) const; + bool operator>(const DefinedType& type) const; +private: + utils::IdType type_id_; // in defined types + utils::IdType type_; // in types manager, created using context types (if specific type) + TypeManager* type_manager_ = nullptr; }; enum class InternalType { - Float, - Int, - String, - Char, - Bool, - Unit, + Float = 0, + Int = 1, + String = 2, + Char = 3, + Bool = 4, + Unit = 5, }; -struct TupleType { - std::optional type; - std::vector, utils::IdType>> fields; +class TupleType { +public: + TupleType() = default; + TupleType(const std::optional& name, + const std::vector, utils::IdType>>& fields, + TypeManager* type_manager) + : name_(name), fields_(fields), type_manager_(type_manager) {} + + bool Same(const TupleType& type) const; + bool operator<(const TupleType& type) const; + bool operator>(const TupleType& type) const; +private: + std::optional name_; + std::vector, utils::IdType>> fields_; + TypeManager* type_manager_ = nullptr; }; -struct VariantType { - std::optional type; - std::vector constructors; +class VariantType { +public: + VariantType() = default; + VariantType(const std::optional& name, + const std::vector& constructors) + : name_(name), constructors_(constructors){} + + bool Same(const VariantType& type) const; + bool operator<(const VariantType& type) const; + bool operator>(const VariantType& type) const; +private: + std::optional name_; + std::vector constructors_; }; -struct OptionalType { - std::optional type; // Can be empty (Some or None) +class OptionalType { +public: + OptionalType() = default; + OptionalType(utils::IdType type, + TypeManager* type_manager) + : type_(type), type_manager_(type_manager) {} + + bool Same(const OptionalType& type) const; + bool operator<(const OptionalType& type) const; + bool operator>(const OptionalType& type) const; +private: + utils::IdType type_; + TypeManager* type_manager_ = nullptr; }; -struct ReferenceToType { - std::vector references; - utils::IdType type; +class ReferenceToType { +public: + ReferenceToType() = default; + ReferenceToType(const std::vector& references, + utils::IdType type, + TypeManager* type_manager) + : references_(references), type_(type), type_manager_(type_manager) {} + + bool Same(const ReferenceToType& type) const; + bool operator<(const ReferenceToType& type) const; + bool operator>(const ReferenceToType& type) const; +private: + std::vector references_; + utils::IdType type_; + TypeManager* type_manager_ = nullptr; }; -struct FunctionType { - std::vector argument_types; - utils::IdType return_type; +///////////////////////////// + +class FunctionType { +public: + FunctionType() = default; + FunctionType(const std::vector& argument_types, + utils::IdType return_type, + TypeManager* type_manager) + : argument_types_(argument_types), return_type_(return_type), type_manager_(type_manager) {} + + bool Same(const FunctionType& type) const; + bool operator<(const FunctionType& type) const; + bool operator>(const FunctionType& type) const; +private: + std::vector argument_types_; + utils::IdType return_type_; + TypeManager* type_manager_ = nullptr; }; -struct ArrayType { - size_t size; // ?? = 0 for dynamic ?? - std::optional elements_type; +class ArrayType { +public: + ArrayType() = default; + ArrayType(size_t size, + utils::IdType elements_type, + TypeManager* type_manager) + : size_(size), elements_type_(elements_type), type_manager_(type_manager) {} + + bool Same(const ArrayType& type) const; + bool operator<(const ArrayType& type) const; + bool operator>(const ArrayType& type) const; +private: + size_t size_; // = 0 for dynamic + utils::IdType elements_type_; + TypeManager* type_manager_ = nullptr; }; -using Type = std::variant; +class Type { +public: + template + explicit Type(T&& type) : type_(std::forward(type)) {} + + bool Same(const Type& type) const; // some rule exceptions ?? + bool operator<(const Type& type) const; // TODO: some rule exceptions ?? + bool operator>(const Type& type) const; +private: + std::variant type_; +}; + +class TypeManager { +public: + template + utils::IdType AddType(const T&& type); + + template + std::optional GetType(utils::IdType type_id); + + std::optional GetAnyType(utils::IdType type_id); + + void AddTypeRequirement(utils::IdType type, utils::IdType requrement); // TODO + void EqualTypes(utils::IdType first_type, utils::IdType second_type); // TODO +private: + std::vector types_; +}; } // namespace info::type + diff --git a/include/utils.hpp b/include/utils.hpp index cf13b62..de02aed 100644 --- a/include/utils.hpp +++ b/include/utils.hpp @@ -9,7 +9,7 @@ using std::size_t; using IdType = size_t; -enum class ReferenceType { Reference, UniqueReference }; +enum class ReferenceType { Reference = 0, UniqueReference = 1 }; template class Storage { diff --git a/src/find_symbols_visitor.cpp b/src/find_symbols_visitor.cpp index b7b2802..4a91bf2 100644 --- a/src/find_symbols_visitor.cpp +++ b/src/find_symbols_visitor.cpp @@ -159,28 +159,24 @@ void FindSymbolsVisitor::Visit(TypeDefinitionStatement* node) { void FindSymbolsVisitor::Visit(AbstractTypeDefinitionStatement* node) { is_in_statement = true; - info::definition::Type info; - - info::definition::AbstractType abstract_type_info; + info::definition::AbstractType info; Visit(node->type.get()); - abstract_type_info.type = std::move(std::any_cast(current_info_)); + info.type = std::move(std::any_cast(current_info_)); current_info_.reset(); switch (node->modifier) { case interpreter::AbstractTypeDefinitionStatement::Basic: - abstract_type_info.modifier = info::definition::AbstractType::Basic; + info.modifier = info::definition::AbstractType::Basic; break; case interpreter::AbstractTypeDefinitionStatement::Abstract: - abstract_type_info.modifier = info::definition::AbstractType::Abstract; + info.modifier = info::definition::AbstractType::Abstract; break; } - std::string type = abstract_type_info.type.type; + std::string type = info.type.type; - info.type = std::move(abstract_type_info); - - node->type_id_ = namespace_visitor_.AddType(type, std::move(info)); + node->type_id_ = namespace_visitor_.AddAbstractType(type, std::move(info)); is_in_statement = false; } diff --git a/src/global_info.cpp b/src/global_info.cpp index bcf19a8..864d181 100644 --- a/src/global_info.cpp +++ b/src/global_info.cpp @@ -31,9 +31,17 @@ void GlobalInfo::NamespaceVisitor::AddEnterNamespace(const std::string& name, current_path_.push_back(name); } -void GlobalInfo::NamespaceVisitor::EnterNamespace(const std::string& name) { // TODO: enter sibling namespace, etc. - namespace_stack_.push_back(&namespace_stack_.back()->namespaces[name]); - current_path_.push_back(name); +void GlobalInfo::NamespaceVisitor::EnterNamespace(const std::string& name) { + for (ssize_t i = (ssize_t)namespace_stack_.size() - 1; i >= 0; --i) { + auto namespace_iter = namespace_stack_[i]->namespaces.find(name); + if (namespace_iter != namespace_stack_[i]->namespaces.end()) { + namespace_stack_.push_back(&namespace_iter->second); + current_path_.push_back(name); + return; + } + } + + error_handling::HandleInternalError("Can't find namespace", "GlobalInfo.NamespaceVisitor.EnterNamespace"); } void GlobalInfo::NamespaceVisitor::ExitNamespace() { @@ -100,7 +108,7 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddFunctionDefinition(const std::str } // TODO: internal types, etc. -// TODO: extended constructor names +// TODO: extended constructor names (point separated names) utils::IdType GlobalInfo::NamespaceVisitor::AddType(const std::string& type, definition::Type&& type_info) { size_t id = 0; @@ -153,38 +161,44 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddType(const std::string& type, return id; } -utils::IdType GlobalInfo::NamespaceVisitor::AddTypeclass(const std::string& typeclass, - definition::Typeclass&& typeclass_info) { - size_t id = 0; - - auto typeclass_id_iter = namespace_stack_.back()->typeclasses.find(typeclass); - - if (typeclass_id_iter == namespace_stack_.back()->typeclasses.end()) { - id = global_info_.typeclasses_.size(); - namespace_stack_.back()->typeclasses[typeclass] = id; - global_info_.typeclasses_.push_back(std::move(typeclass_info)); - } else { - error_handling::HandleTypecheckError("More then one typeclass with the same name in namespace"); +// TODO: link abstract type with let definitions +utils::IdType GlobalInfo::NamespaceVisitor::AddAbstractType(const std::string& abstract_type, + definition::AbstractType&& abstract_type_info) { + if (!FindAbstractType(abstract_type).has_value()) { + size_t id = global_info_.abstract_types_.size(); + global_info_.name_to_abstract_type_[abstract_type] = id; + global_info_.abstract_types_.push_b(ack(std::move(abstract_type_info)); } - return id; + error_handling::HandleTypecheckError("More then one abstract type with the same name in namespace"); + return 0; +} + +utils::IdType GlobalInfo::NamespaceVisitor::AddTypeclass(const std::string& typeclass, + definition::Typeclass&& typeclass_info) { + if (!FindTypeclass(typeclass).has_value()) { + size_t id = global_info_.typeclasses_.size(); + global_info_.name_to_typeclass_[typeclass] = id; + global_info_.typeclasses_.push_back(std::move(typeclass_info)); + } + + + error_handling::HandleTypecheckError("More then one typeclass with the same name in namespace"); + return 0; } utils::IdType GlobalInfo::NamespaceVisitor::AddConstructor(const std::string& constructor, definition::Constructor&& constructor_info) { - size_t id = 0; - auto constructor_id_iter = namespace_stack_.back()->constructors.find(constructor); if (constructor_id_iter == namespace_stack_.back()->constructors.end()) { - id = global_info_.constructors_.size(); + size_t id = global_info_.constructors_.size(); namespace_stack_.back()->constructors[constructor] = id; global_info_.constructors_.push_back(std::move(constructor_info)); - } else { - error_handling::HandleTypecheckError("More then one constructor with the same name in namespace"); } - return id; + error_handling::HandleTypecheckError("More then one constructor with the same name in namespace"); + return 0; } std::optional GlobalInfo::NamespaceVisitor::FindNamespace(const std::optional>& path) { @@ -247,19 +261,24 @@ std::optional GlobalInfo::NamespaceVisitor::FindType( }); } -std::optional GlobalInfo::NamespaceVisitor::FindTypeclass( - const std::optional>& path, - const std::string& typeclass) { - return FindSomething(path, - [typeclass] (definition::Namespace* current_namespace) -> std::optional { +std::optional GlobalInfo::NamespaceVisitor::FindAbstractType(const std::string& abstract_type) { + auto abstract_type_id_iter = global_info_.name_to_abstract_type_.find(abstract_type); - auto typeclass_info_iter = current_namespace->typeclasses.find(typeclass); - if (typeclass_info_iter == current_namespace->typeclasses.end()) { - return std::nullopt; - } + if (abstract_type_id_iter != global_info_.name_to_abstract_type_.end()) { + return abstract_type_id_iter->second; + } - return typeclass_info_iter->second; - }); + return std::nullopt; +} + +std::optional GlobalInfo::NamespaceVisitor::FindTypeclass(const std::string& typeclass) { + auto typeclass_id_iter = global_info_.name_to_typeclass_.find(typeclass); + + if (typeclass_id_iter != global_info_.name_to_typeclass_.end()) { + return typeclass_id_iter->second; + } + + return std::nullopt; } std::optional GlobalInfo::NamespaceVisitor::FindConstructor( diff --git a/src/link_symbols_visitor.cpp b/src/link_symbols_visitor.cpp index 26de5f3..48356a1 100644 --- a/src/link_symbols_visitor.cpp +++ b/src/link_symbols_visitor.cpp @@ -4,187 +4,57 @@ namespace interpreter { -// Sources ----------------- - -void LinkSymbolsVisitor::Visit(SourceFile* node) { - for (auto& statement : node->statements) { - if (std::holds_alternative(statement)) { - Visit(&std::get(statement)); - } else if (std::holds_alternative(statement)) { - Visitor::Visit(std::get(statement)); - } else { - // error - } +const std::string& NameFromTypeSubExpression(const TypeSubExpression& type) { + if (std::holds_alternative>(type)) { + return *std::get>(type); + } else if (std::holds_alternative>(type)) { + return std::get>(type)->type; } -} -void LinkSymbolsVisitor::Visit(Sources* node) { - abstract_types_.EnterContext(); - for (auto& statement : node->statements) { - Visitor::Visit(statement); - } - abstract_types_.ExitContext(); + error_handling::HandleInternalError("Empty variant", "NameFromTypeSubExpression"); + exit(1); // TODO: better decision ?? } // Namespaces, partitions ----------------- -void LinkSymbolsVisitor::Visit(Partition* node) { - // TODO - Visit(node->scope.get()); -} - void LinkSymbolsVisitor::Visit(Namespace* node) { - node->type_id_ = namespace_visitor_.FindType({}, node->type); + // Visitor::Visit(&node->type); // not needed - if (node->name.has_value() && !node->type_id_.has_value()) { - error_handling::HandleTypecheckError("Variable namespace type not found"); + auto maybe_type = namespace_visitor_.FindType(std::nullopt, node->type); // TODO: find only in local namespace + auto maybe_typeclass = namespace_visitor_.FindType(std::nullopt, node->type); // TODO: find only if in global namespace + if (maybe_type.has_value() && maybe_typeclass.has_value()) { + error_handling::HandleTypecheckError("Ambigious namespace name (typeclass or type)"); + } + if (maybe_type.has_value()) { + node->link_type_id_ = maybe_type.value(); + } + if (maybe_typeclass.has_value()) { + node->link_typeclass_id_ = maybe_typeclass.value(); } namespace_visitor_.EnterNamespace(node->type); - Visit(node->scope.get()); + + Visitor::Visit(&node->scope); + namespace_visitor_.ExitNamespace(); } -// Definitions ----------------- - -void LinkSymbolsVisitor::Visit(ImportStatement* node) {} - -void LinkSymbolsVisitor::Visit(AliasDefinitionStatement* node) { - abstract_types_.EnterContext(); - for (size_t i = 0; i parameters.size(); ++i) { - abstract_types_.DefineType(node->parameters[i], node->parameter_graph_ids_[i]); - } - Visitor::Visit(node->value.get()); - abstract_types_.ExitContext(); -} - -void LinkSymbolsVisitor::Visit(VariableDefinitionStatement* node) { - abstract_types_.EnterContext(); - Visitor::Visit(node->name); - Visitor::Visit(node->value); - abstract_types_.ExitContext(); -} - -void LinkSymbolsVisitor::Visit(FunctionDeclaration* node) { - abstract_types_.EnterContext(); - for (auto& parameter : node->parameters) { - Visitor::Visit(parameter.get()); - abstract_types_.DefineType(parameter->type, parameter->type_graph_id_); - } - Visitor::Visit(node->type.get()); - abstract_types_.ExitContext(); -} - -void LinkSymbolsVisitor::Visit(FunctionDefinitionStatement* node) { - abstract_types_.EnterContext(); - Visit(node->definition.get()); - Visitor::Visit(node->value); - abstract_types_.ExitContext(); -} - -void LinkSymbolsVisitor::Visit(TypeDefinitionStatement* node) { - abstract_types_.EnterContext(); - Visit(node->definition.get()); - Visitor::Visit(node->value); - abstract_types_.ExitContext(); -} - -void LinkSymbolsVisitor::Visit(AbstractTypeDefinitionStatement* node) { - Visitor::Visit(node->type.get()); - // TODO: can't be used before definition - abstract_types_.DefineType(node->type->type, node->type->type_graph_id_); -} - -void LinkSymbolsVisitor::Visit(TypeclassDefinitionStatement* node) { - abstract_types_.EnterContext(); - Visit(node->definition.get()); - for (auto& requirement : node->requirements) { - Visit(requirement.get()); - } - abstract_types_.ExitContext(); -} - -// Definition parts - -void LinkSymbolsVisitor::Visit(FunctionDefinition* node) { - for (auto& parameter : node->parameters) { - Visitor::Visit(parameter.get()); - abstract_types_.DefineType(parameter->type, parameter->type_graph_id_); - } -} - -void LinkSymbolsVisitor::Visit(TypeDefinition* node) { - Visitor::Visit(node->type.get()); - for (auto& parameter : node->parameters) { - Visitor::Visit(parameter.get()); - abstract_types_.DefineType(parameter->type, parameter->type_graph_id_); - } -} - -// Flow control ----------------- - -// Statements, expressions, blocks, etc. ----------------- - -// Operators - -// Other Expressions - -// TODO: move to find_symbols_visitor -void LinkSymbolsVisitor::Visit(LambdaFunction* node) { - abstract_types_.EnterContext(); - for (auto& parameter : node->parameters) { - Visitor::Visit(parameter.get()); - abstract_types_.DefineType(parameter->type, parameter->type_graph_id_); - } - - //////////// - node->argument_graph_ids_.resize(node->arguments.size()); - for (size_t i = 0; i < node->arguments.size(); ++i) { - node->argument_graph_ids_[i] = namespace_visitor_.GetAbstractTypeGraph()->AddVertex(); - } - - node->return_type_graph_id_ = namespace_visitor_.GetAbstractTypeGraph()->AddVertex(); - /////////// - - Visitor::Visit(node->expression); - abstract_types_.ExitContext(); -} - -// Name - // Type, typeclass, etc. ----------------- // Type -void LinkSymbolsVisitor::Visit(TypeExpression* node) { +// TODO: link internal stages +void LinkSymbolsVisitor::Visit(TypeExpression* node) { // TODO: check std::vector path; - path.reserve(node->namespaces.size()); + path.reserve(node->path.size()); - for (auto& type_namespace : node->namespaces) { - Visitor::Visit(type_namespace); - if (std::holds_alternative>(type_namespace)) { - path.push_back(*std::get>(type_namespace)); - } else if (std::holds_alternative>(type_namespace)) { - path.push_back(std::get>(type_namespace)->type_expression->type); - } else { - // error - } + for (auto& path_type : node->path) { + path.push_back(NameFromTypeSubExpression(path_type)); } - std::optional maybe_type = namespace_visitor_.FindType(path, node->type); - std::optional maybe_abstract_type = std::nullopt; + std::optional maybe_type = namespace_visitor_.FindType(path, NameFromTypeSubExpression(node->type)); - if (path.size() == 0) { - maybe_abstract_type = abstract_types_.GetTypeId(node->type); - } - - if (maybe_abstract_type.has_value()) { - if (maybe_type.has_value()) { - error_handling::HandleTypecheckError("Ambigious type"); - } else { - node->type_id_ = maybe_abstract_type.value(); - } - } else if (maybe_type.has_value()) { + if (maybe_type.has_value()) { node->type_id_ = maybe_type.value(); } else { error_handling::HandleTypecheckError("Type not found"); @@ -193,36 +63,21 @@ void LinkSymbolsVisitor::Visit(TypeExpression* node) { // Typeclass -void LinkSymbolsVisitor::Visit(TypeclassExpression* node) { - std::vector path; - path.reserve(node->namespaces.size()); +void LinkSymbolsVisitor::Visit(TypeclassExpression* node) { // TODO: check + std::string typeclass; - for (auto& typeclass_namespace : node->namespaces) { - Visitor::Visit(typeclass_namespace); - if (std::holds_alternative>(typeclass_namespace)) { - path.push_back(*std::get>(typeclass_namespace)); - } else if (std::holds_alternative>(typeclass_namespace)) { - path.push_back(std::get>(typeclass_namespace)->type_expression->type); - } else { - // error - } + if (std::holds_alternative>(node->typeclass)) { + typeclass = *std::get>(node->typeclass); + } else if (std::holds_alternative>(node->typeclass)) { + typeclass = std::get>(node->typeclass)->typeclass; + } else { + // error } - std::optional maybe_typeclass = namespace_visitor_.FindType(path, node->typeclass); - std::optional maybe_abstract_typeclass = std::nullopt; + std::optional maybe_typeclass = namespace_visitor_.FindTypeclass(typeclass); - if (path.size() == 0) { - maybe_abstract_typeclass = abstract_types_.GetTypeId(node->typeclass); - } - - if (maybe_abstract_typeclass.has_value()) { - if (maybe_typeclass.has_value()) { - error_handling::HandleTypecheckError("Ambigious type"); - } else { - node->type_id_ = maybe_abstract_typeclass.value(); - } - } else if (maybe_typeclass.has_value()) { - node->type_id_ = maybe_typeclass.value(); + if (maybe_typeclass.has_value()) { + node->typeclass_id_ = maybe_typeclass.value(); } else { error_handling::HandleTypecheckError("Type not found"); } diff --git a/src/type_check_visitor.cpp b/src/type_check_visitor.cpp index da56801..2928723 100644 --- a/src/type_check_visitor.cpp +++ b/src/type_check_visitor.cpp @@ -12,44 +12,47 @@ namespace interpreter { // Sources ----------------- void TypeCheckVisitor::Visit(SourceFile* node) { - for (auto& statement : node->statements) { - if (std::holds_alternative(statement)) { - Visit(&std::get(statement)); - } else if (std::holds_alternative(statement)) { - Visitor::Visit(std::get(statement)); - } else { - // error - } - } - - current_type_ = context_manager_.AddType(info::type::InternalType::Unit); -} - -void TypeCheckVisitor::Visit(Sources* node) { for (auto& statement : node->statements) { Visitor::Visit(statement); } + current_type_ = context_manager_.AddType(info::type::InternalType::Unit); } // Namespaces, partitions ----------------- +void TypeCheckVisitor::Visit(PartitionSources* node) { + for (auto& statement : node->statements) { + Visitor::Visit(statement); + } + + current_type_ = context_manager_.AddType(info::type::InternalType::Unit); +} + void TypeCheckVisitor::Visit(Partition* node) { - Visit(node->scope.get()); + Visit(&node->scope); + + current_type_ = context_manager_.AddType(info::type::InternalType::Unit); +} + +void TypeCheckVisitor::Visit(NamespaceSources* node) { + for (auto& statement : node->statements) { + Visitor::Visit(statement); + } current_type_ = context_manager_.AddType(info::type::InternalType::Unit); } void TypeCheckVisitor::Visit(Namespace* node) { - if (node->name.has_value()) { - // TODO: add modifiers - context_manager_.EnterVariableContext(node->name.value().name, - context_manager_.AddType(info::type::DefinedType {node->type_id_.value()})); + if (node->modifier.has_value()) { + // TODO + // context_manager_.EnterVariableContext(node->name.value().name, + // context_manager_.AddType(info::type::DefinedType {node->type_id_.value()})); } namespace_visitor_.EnterNamespace(node->type); - Visit(node->scope.get()); + Visit(&node->scope); namespace_visitor_.ExitNamespace(); @@ -89,15 +92,24 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) { // check, that all paramaters used ?? context_manager_.EnterContext(); + info::definition::Function* function_info = namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(node->function_id_); + + if (!function_info->declaration.has_value()) { + error_handling::HandleTypecheckError("Function defined, but not declared"); + } + + info::definition::FunctionDeclaration& declaration = function_info->declaration.value(); + + declaration.parameters + // Visit(node->definition.get()); // ?? for (size_t i = 0; i < node->definition->arguments.size(); ++i) { context_manager_.DefineVariable(node->definition->arguments[i].name, - context_manager_.AddType(info::type::AbstractType { node->argument_graph_ids_[i] })); + declaration.argument_types[i]); } Visitor::Visit(node->value); - context_manager_.EqualTypes( - context_manager_.AddType(info::type::AbstractType { node->return_type_graph_id_ }), current_type_); + context_manager_.EqualTypes(declaration.argument_types.back(), current_type_); // return type ?? context_manager_.ExitContext(); @@ -113,7 +125,7 @@ void TypeCheckVisitor::Visit(TypeDefinitionStatement* node) { } void TypeCheckVisitor::Visit(AbstractTypeDefinitionStatement* node) { - utils::IdType type = context_manager_.AddType(info::type::AbstractType {node->type_graph_id_} ); + utils::IdType type = context_manager_.AddType(info::type::DefinedType ); // Visit(node->type.get()); ?? for (auto& typeclass : node->type->typeclasses) { // TODO @@ -680,9 +692,25 @@ void TypeCheckVisitor::Visit(ExtendedScopedAnyType* node) { // Typeclass -void TypeCheckVisitor::Visit(ParametrizedTypeclass* node) {} +void Visitor::Visit(TypeclassExpression* node) { + Visit(node->typeclass); +} -void TypeCheckVisitor::Visit(TypeclassExpression* node) {} +void Visitor::Visit(ParametrizedTypeclass* node) { + Visit(&node->typeclass); + for (auto& parameter : node->parameters) { + Visit(parameter.get()); + } +} + +// Typeclass & Type ----------------- + +void Visitor::Visit(ParametrizedType* node) { + Visit(&node->type); + for (auto& parameter : node->parameters) { + Visit(parameter.get()); + } +} // Identifiers, constants, etc. ----------------- diff --git a/src/types.cpp b/src/types.cpp new file mode 100644 index 0000000..18e8a1a --- /dev/null +++ b/src/types.cpp @@ -0,0 +1,275 @@ +// for clangd +#include "../include/types.hpp" + +namespace info::type { + +bool AbstractType::Same(const AbstractType& type) const { + return name_ == type.name_; +} + +bool AbstractType::operator<(const AbstractType& type) const { + for (auto& typeclass : requirements_) { + if (type.requirements_.count(typeclass) == 0) { + return false; + } + } + return true; +} + +bool AbstractType::operator>(const AbstractType& type) const { + return type < *this; +} + +// + +bool DefinedType::Same(const DefinedType& type) const { + return type_id_ == type.type_id_ + && type_manager_->GetAnyType(type_).value()->Same(*type_manager_->GetAnyType(type.type_).value()); +} + +bool DefinedType::operator<(const DefinedType& type) const { + return type_id_ == type.type_id_ + && *type_manager_->GetAnyType(type_).value() < *type_manager_->GetAnyType(type.type_).value(); +} + +bool DefinedType::operator>(const DefinedType& type) const { + return type < *this; +} + +// + +bool TupleType::Same(const TupleType& type) const { + if (fields_.size() != type.fields_.size()) { + return false; + } + + for (size_t i = 0; i < fields_.size(); ++i) { + if (!type_manager_->GetAnyType(fields_[i].second).value()->Same(*type_manager_->GetAnyType(type.fields_[i].second).value())) { + return false; + } + } + + return true; +} + +bool TupleType::operator<(const TupleType& type) const { + if (fields_.size() != type.fields_.size()) { + return false; + } + + for (size_t i = 0; i < fields_.size(); ++i) { + if (!(*type_manager_->GetAnyType(fields_[i].second).value() < *type_manager_->GetAnyType(type.fields_[i].second).value())) { + return false; + } + } + + return true; +} + +bool TupleType::operator>(const TupleType& type) const { + return type < *this; +} + +// + +bool VariantType::Same(const VariantType& type) const { + if (constructors_.size() != type.constructors_.size()) { + return false; + } + + for (size_t i = 0; i < constructors_.size(); ++i) { + if (!constructors_[i].Same(constructors_[i])) { + return false; + } + } + + return true; +} + +bool VariantType::operator<(const VariantType& type) const { + if (constructors_.size() != type.constructors_.size()) { + return false; + } + + for (size_t i = 0; i < constructors_.size(); ++i) { + if (!(constructors_[i] < constructors_[i])) { + return false; + } + } + + return true; +} + +bool VariantType::operator>(const VariantType& type) const { + return type < *this; +} + +// + +bool OptionalType::Same(const OptionalType& type) const { + return type_manager_->GetAnyType(type_).value()->Same(*type_manager_->GetAnyType(type.type_).value()); +} + +bool OptionalType::operator<(const OptionalType& type) const { + return *type_manager_->GetAnyType(type_).value() < *type_manager_->GetAnyType(type.type_).value(); +} + +bool OptionalType::operator>(const OptionalType& type) const { + return type < *this; +} + +// + +bool ReferenceToType::Same(const ReferenceToType& type) const { + return references_ == type.references_ && type_manager_->GetAnyType(type_).value()->Same(*type_manager_->GetAnyType(type.type_).value()); +} + +bool ReferenceToType::operator<(const ReferenceToType& type) const { + return references_ == type.references_ && *type_manager_->GetAnyType(type_).value() < *type_manager_->GetAnyType(type.type_).value(); +} + +bool ReferenceToType::operator>(const ReferenceToType& type) const { + return type < *this; +} + +// + +bool FunctionType::Same(const FunctionType& type) const { + if (argument_types_.size() != type.argument_types_.size()) { + return false; + } + + for (size_t i = 0; i < argument_types_.size(); ++i) { + if (!type_manager_->GetAnyType(argument_types_[i]).value()->Same(*type_manager_->GetAnyType(type.argument_types_[i]).value())) { + return false; + } + } + + return true; +} + +bool FunctionType::operator<(const FunctionType& type) const { + if (argument_types_.size() != type.argument_types_.size()) { + return false; + } + + for (size_t i = 0; i < argument_types_.size(); ++i) { + if (!(*type_manager_->GetAnyType(argument_types_[i]).value() < *type_manager_->GetAnyType(type.argument_types_[i]).value())) { + return false; + } + } + + return true; +} + +bool FunctionType::operator>(const FunctionType& type) const { + return type < *this; +} + +// + +bool ArrayType::Same(const ArrayType& type) const { + return size_ == type.size_ && type_manager_->GetAnyType(elements_type_).value()->Same(*type_manager_->GetAnyType(type.elements_type_).value()); +} + +bool ArrayType::operator<(const ArrayType& type) const { + return size_ == type.size_ && *type_manager_->GetAnyType(elements_type_).value() < *type_manager_->GetAnyType(type.elements_type_).value(); +} + +bool ArrayType::operator>(const ArrayType& type) const { + return type < *this; +} + +// + +bool Type::Same(const Type& type) const { + size_t this_index = type_.index(); + size_t type_index = type.type_.index(); + + if (this_index == type_index) { + switch (this_index) { + case 0: + return std::get(type_).Same(std::get(type.type_)); + case 1: + return std::get(type_).Same(std::get(type.type_)); + case 2: + return std::get(type_) == std::get(type.type_); + case 3: + return std::get(type_).Same(std::get(type.type_)); + case 4: + return std::get(type_).Same(std::get(type.type_)); + case 5: + return std::get(type_).Same(std::get(type.type_)); + case 6: + return std::get(type_).Same(std::get(type.type_)); + case 7: + return std::get(type_).Same(std::get(type.type_)); + default: + // error + break; + } + } + + return false; +} // some rule exceptions ?? + +bool Type::operator<(const Type& type) const { + size_t this_index = type_.index(); + size_t type_index = type.type_.index(); + + if (this_index == type_index) { + switch (this_index) { + case 0: + return std::get(type_) < std::get(type.type_); + case 1: + return std::get(type_) < std::get(type.type_); + case 2: + return std::get(type_) == std::get(type.type_); + case 3: + return std::get(type_) < std::get(type.type_); + case 4: + return std::get(type_) < std::get(type.type_); + case 5: + return std::get(type_) < std::get(type.type_); + case 6: + return std::get(type_) < std::get(type.type_); + case 7: + return std::get(type_) < std::get(type.type_); + default: + // error + break; + } + } + + return false; +} // TODO: some rule exceptions ?? + +bool Type::operator>(const Type& type) const { + return type < *this; +} + +// + +template +utils::IdType TypeManager::AddType(const T&& type) { + types_.emplace_back(std::forward(type)); + return types_.size() - 1; +} + +template +std::optional TypeManager::GetType(utils::IdType type_id) { + if (!std::holds_alternative(types_.at(type_id))) { + return std::nullopt; + } + return &std::get(types_.at(type_id)); +} + +std::optional TypeManager::GetAnyType(utils::IdType type_id) { + return &types_.at(type_id); +} + +void TypeManager::AddTypeRequirement(utils::IdType type, utils::IdType requrement) {} // TODO +void TypeManager::EqualTypes(utils::IdType first_type, utils::IdType second_type) {} // TODO + +} // namespace info::type +