From 4f54bb4bd7623b44985d73f7422a78c81651ebec Mon Sep 17 00:00:00 2001 From: ProgramSnail Date: Sun, 14 May 2023 11:28:37 +0300 Subject: [PATCH] better global_info API, better const/var/static handling, const typeclass requirements, fixes --- include/definitions.hpp | 2 +- include/error_handling.hpp | 22 +++--- include/global_info.hpp | 141 ++++++++++++++++++++++++++++++----- include/interpreter_tree.hpp | 7 +- include/typeclass_graph.hpp | 57 +++++++++++--- include/utils.hpp | 72 +++++++++++------- lang-parser | 2 +- src/build_visitor.cpp | 35 ++++++--- src/find_symbols_visitor.cpp | 14 +--- src/global_info.cpp | 45 ++++++----- src/link_symbols_visitor.cpp | 14 ++-- src/print_visitor.cpp | 68 +++++++++-------- src/type_check_visitor.cpp | 30 ++++---- src/typed_print_visitor.cpp | 78 +++++++++---------- src/visitor.cpp | 7 +- 15 files changed, 381 insertions(+), 213 deletions(-) diff --git a/include/definitions.hpp b/include/definitions.hpp index cfe6c68..5eed539 100644 --- a/include/definitions.hpp +++ b/include/definitions.hpp @@ -98,7 +98,7 @@ struct Namespace { utils::IdType parent_namespace; - std::optional modifier; // modifier => variable namespace + utils::ClassInternalsModifier modifier; std::string type_name; }; diff --git a/include/error_handling.hpp b/include/error_handling.hpp index 7b53ab1..fa06cab 100644 --- a/include/error_handling.hpp +++ b/include/error_handling.hpp @@ -23,35 +23,35 @@ inline void PrintPosition(std::ostream& out, inline void HandleParsingError(const std::string& message, std::pair start_position, std::pair end_position) { - std::cout << "\x1b[1;31mParsing Error:\x1b[0m " << message << " at "; - PrintPosition(std::cout, start_position, end_position); - std::cout << ".\n"; + std::cerr << "\x1b[1;31mParsing Error:\x1b[0m " << message << " at "; + PrintPosition(std::cerr, start_position, end_position); + std::cerr << ".\n"; exit(1); } 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); } 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); } inline void HandleTypecheckError(const std::string& message, const interpreter::tokens::BaseNode& node) { - std::cout << "\x1b[1;31mTypecheck Error:\x1b[0m " << message << " at "; - PrintPosition(std::cout, node.start_position, node.end_position); - std::cout << ".\n"; + std::cerr << "\x1b[1;31mTypecheck Error:\x1b[0m " << message << " at "; + PrintPosition(std::cerr, node.start_position, node.end_position); + std::cerr << ".\n"; exit(1); } inline void HandleRuntimeError(const std::string& message, const interpreter::tokens::BaseNode& node) { - std::cout << "\x1b[1;31mRuntime Error:\x1b[0m " << message << " at "; - PrintPosition(std::cout, node.start_position, node.end_position); - std::cout << ".\n"; + std::cerr << "\x1b[1;31mRuntime Error:\x1b[0m " << message << " at "; + PrintPosition(std::cerr, node.start_position, node.end_position); + std::cerr << ".\n"; exit(1); } diff --git a/include/global_info.hpp b/include/global_info.hpp index 7b34aa0..072c5b7 100644 --- a/include/global_info.hpp +++ b/include/global_info.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include @@ -8,6 +7,7 @@ // for clangd #include "definitions.hpp" #include "interpreter_tree.hpp" +#include "typeclass_graph.hpp" #include "utils.hpp" namespace info { @@ -40,11 +40,11 @@ public: void AddImport(definition::Import&& import_info, const std::optional& name = std::nullopt); void AddEnterNamespace(const std::string& name, - std::optional modifier, + utils::ClassInternalsModifier modifier, const interpreter::tokens::BaseNode& base_node); void EnterNamespace(const std::string& name, - std::optional modifier); + utils::ClassInternalsModifier modifier); void ExitNamespace(); @@ -77,28 +77,117 @@ public: utils::IdType AddPartition(const std::vector& path, // including name interpreter::tokens::PartitionStatement* node); - std::optional FindNamespace(const std::optional>& path); + std::optional FindNamespaceId(const std::optional>& path); - std::optional FindFunction(const std::optional>& path, - const std::string& name); + std::optional FindFunctionId(const std::optional>& path, + const std::string& name); - std::optional FindMethod(const std::optional>& path, - const std::string& type, - const std::string& name, - utils::IsConstModifier modifier); + std::optional FindMethodId(const std::optional>& path, + const std::string& type, + const std::string& name, + utils::IsConstModifier modifier); - std::optional FindType(const std::optional>& path, - const std::string& type); + std::optional FindTypeId(const std::optional>& path, + const std::string& type); - std::optional FindLocalType(const std::string& type); + std::optional FindLocalTypeId(const std::string& type); - std::optional FindAbstractType(const std::string& abstract_type); + std::optional FindAbstractTypeId(const std::string& abstract_type); - std::optional FindTypeclass(const std::string& typeclass); + std::optional FindTypeclassId(const std::string& typeclass); - std::optional FindConstructor(const std::optional>& path, + std::optional FindConstructorId(const std::optional>& path, const std::string& constructor); + std::optional FindNamespace(const std::optional>& path) { + std::optional id = FindNamespaceId(path); + if (!id.has_value()) { + return std::nullopt; + } + return &global_info_.GetNamespaceInfo(id.value()); + } + + std::optional FindFunction(const std::optional>& path, + const std::string& name) { + std::optional id = FindFunctionId(path, name); + if (!id.has_value()) { + return std::nullopt; + } + return &global_info_.GetFunctionInfo(id.value()); + } + + std::optional FindMethod(const std::optional>& path, + const std::string& type, + const std::string& name, + utils::IsConstModifier modifier) { + std::optional id = FindFunctionId(path, name); + if (!id.has_value()) { + return std::nullopt; + } + return &global_info_.GetFunctionInfo(id.value()); + } + + std::optional FindAnyType(const std::optional>& path, + const std::string& type) { + std::optional id = FindTypeId(path, type); + if (!id.has_value()) { + return std::nullopt; + } + return &global_info_.GetAnyTypeInfo(id.value()); + } + + template + std::optional FindType(const std::optional>& path, + const std::string& type) { + std::optional id = FindTypeId(path, type); + if (!id.has_value()) { + return std::nullopt; + } + return global_info_.GetTypeInfo(id.value()); + } + + std::optional FindAnyLocalType(const std::string& type) { + std::optional id = FindLocalTypeId(type); + if (!id.has_value()) { + return std::nullopt; + } + return &global_info_.GetAnyTypeInfo(id.value()); + } + + template + std::optional FindLocalType(const std::string& type) { + std::optional id = FindLocalTypeId(type); + if (!id.has_value()) { + return std::nullopt; + } + return global_info_.GetTypeInfo(id.value()); + } + + std::optional FindAbstractType(const std::string& abstract_type) { + std::optional id = FindAbstractTypeId(abstract_type); + if (!id.has_value()) { + return std::nullopt; + } + return &global_info_.GetAbstractTypeInfo(id.value()); + } + + std::optional FindTypeclass(const std::string& typeclass) { + std::optional id = FindTypeclassId(typeclass); + if (!id.has_value()) { + return std::nullopt; + } + return &global_info_.GetTypeclassInfo(id.value()); + } + + std::optional FindConstructor(const std::optional>& path, + const std::string& constructor) { + std::optional id = FindConstructorId(path, constructor); + if (!id.has_value()) { + return std::nullopt; + } + return &global_info_.GetConstructorInfo(id.value()); + } + NamespaceVisitor CreateVisitor() { return global_info_.CreateVisitor(); } @@ -107,6 +196,10 @@ public: return &global_info_; } + TypeclassGraph* GetTypeclassGraph() { + return global_info_.GetTypeclassGraph(); + } + const std::vector& GetCurrentPath() { return current_path_; } @@ -128,7 +221,7 @@ public: const std::vector& path); std::unordered_map* - ChooseNamespaces(std::optional modifier, + ChooseNamespaces(utils::ClassInternalsModifier modifier, utils::IdType namespace_id); private: GlobalInfo& global_info_; @@ -145,6 +238,10 @@ public: return functions_.at(id); } + definition::Type& GetAnyTypeInfo(utils::IdType id) { + return types_.at(id); + } + template std::optional GetTypeInfo(utils::IdType id) { if (!std::holds_alternative(types_.at(id).type)) { @@ -153,8 +250,8 @@ public: return &std::get(types_[id].type); } - definition::Type& GetAnyTypeInfo(utils::IdType id) { - return types_.at(id); + definition::AbstractType& GetAbstractTypeInfo(utils::IdType id) { + return abstract_types_.at(id); } definition::Typeclass& GetTypeclassInfo(utils::IdType id) { @@ -190,6 +287,10 @@ public: return ans; } + TypeclassGraph* GetTypeclassGraph() { + return &typeclass_graph_; + } + private: const utils::IdType GlobalNamespaceId = 0; @@ -209,6 +310,8 @@ private: std::vector imports_; std::unordered_map usages_; + + TypeclassGraph typeclass_graph_; }; } // namespace info diff --git a/include/interpreter_tree.hpp b/include/interpreter_tree.hpp index 1cedf8d..15ca1ec 100644 --- a/include/interpreter_tree.hpp +++ b/include/interpreter_tree.hpp @@ -240,7 +240,6 @@ struct ParametrizedTypeclass; struct ParametrizedType; -// Comments [IGNORE] ----------------- // Identifiers, constants, etc. ----------------- using Pattern = std::variant< @@ -272,7 +271,7 @@ struct NamespaceSources { struct Namespace { BaseNode base; - std::optional modifier; // modifier => variable namespace + utils::ClassInternalsModifier modifier; TypeIdentifier type; NamespaceSources scope; @@ -355,8 +354,8 @@ struct TypeclassDefinitionStatement { BaseNode base; std::unique_ptr definition; - std::vector> method_requirements; - std::vector> function_requirements; + std::vector>> requirements; utils::IdType typeclass_id_; }; diff --git a/include/typeclass_graph.hpp b/include/typeclass_graph.hpp index 76cb131..28c12b4 100644 --- a/include/typeclass_graph.hpp +++ b/include/typeclass_graph.hpp @@ -2,9 +2,6 @@ #include #include - -#pragma once - #include // for calngd @@ -22,7 +19,12 @@ public: struct ParametrizedTypeclass { std::string typeclass; - // TODO: parameters + std::vector parameters; // only abstract types from owner + }; + + struct AnnotatedType { + std::string name; + std::vector requirements; }; struct TypeclassVertex { @@ -31,16 +33,48 @@ public: std::unordered_map methods; std::vector dependencies; - // TODO: std::vector>> parameters; + std::vector parameters; }; - std::optional AddTypeclass( +// // TODO: write + rewrite +// std::optional AddTypeclassByNode(interpreter::tokens::TypeclassDefinitionStatement* node) { +// std::string name = node->definition->type->type; +// std::vector dependencies; +// // std::vector> function_declarations; +// // std::vector> function_definitions; +// // std::vector 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 AddTypeclass( // move parameters ?? const std::string& name, interpreter::tokens::TypeclassDefinitionStatement* definition, const std::vector& dependencies, - const std::vector>& method_declarations, - const std::vector>& method_definitions) { - for (auto& method : method_declarations) { + const std::vector>& function_declarations, + const std::vector>& function_definitions, + const std::vector& parameters) { + for (auto& method : function_declarations) { if (method_to_typeclass_.count(method.first) != 0) { return std::nullopt; } @@ -53,14 +87,15 @@ public: typeclass.name = name; typeclass.definition = definition; typeclass.dependencies = dependencies; + typeclass.parameters = parameters; - for (auto& method : method_declarations) { + for (auto& method : function_declarations) { method_to_typeclass_[method.first] = typeclasses_.size(); typeclass.methods[method.first].declaration = method.second; } name_to_typeclass_[name] = typeclasses_.size() - 1; - for (auto& method : method_definitions) { + for (auto& method : function_definitions) { typeclass.methods[method.first].definition = method.second; } diff --git a/include/utils.hpp b/include/utils.hpp index 9300f8b..3f6008e 100644 --- a/include/utils.hpp +++ b/include/utils.hpp @@ -18,6 +18,7 @@ const size_t MaxOperatorPrecedence = 4; enum class ReferenceModifier { Reference = 0, UniqueReference = 1, Dereference = 2 }; 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 AssignmentModifier { Assign = 0, Move = 1 }; enum class AliasModifier { Alias = 0, Type = 1, Let = 2 }; @@ -33,8 +34,21 @@ inline ValueType IsConstModifierToValueType(IsConstModifier modifier) { case IsConstModifier::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 @@ -214,32 +228,32 @@ private: std::vector ranks_; }; -// static void BackVisitDfs(size_t id, -// std::vector& verticles, -// std::vector& marks, -// const std::vector>& edges, -// size_t mark) { -// if (marks[id] != 0) { -// return; -// } -// -// marks[id] = mark; -// verticles.push_back(id); -// -// for (size_t i = 0; i < edges[id].size(); ++i) { -// BackVisitDfs(id, verticles, marks, edges, mark); -// } -// } -// -// static std::vector BackTopSort(const std::vector>& edges_) { -// std::vector sorted_verticles; -// std::vector marks(edges_.size(), 0); -// -// for (size_t i = 0; i < marks.size(); ++i) { -// BackVisitDfs(i, sorted_verticles, marks, edges_, 1); -// } -// -// return sorted_verticles; -// } +static void BackVisitDfs(size_t id, + std::vector& verticles, + std::vector& marks, + const std::vector>& edges, + size_t mark) { + if (marks[id] != 0) { + return; + } + + marks[id] = mark; + verticles.push_back(id); + + for (size_t i = 0; i < edges[id].size(); ++i) { + BackVisitDfs(id, verticles, marks, edges, mark); + } +} + +static std::vector BackTopSort(const std::vector>& edges_) { + std::vector sorted_verticles; + std::vector marks(edges_.size(), 0); + + for (size_t i = 0; i < marks.size(); ++i) { + BackVisitDfs(i, sorted_verticles, marks, edges_, 1); + } + + return sorted_verticles; +} } // namespace utils diff --git a/lang-parser b/lang-parser index 3610504..630eced 160000 --- a/lang-parser +++ b/lang-parser @@ -1 +1 @@ -Subproject commit 3610504b4ce142fe30f47851709fef6bc2fc53f1 +Subproject commit 630eced5368dca21af5eb2b6bea7f90651ce5e30 diff --git a/src/build_visitor.cpp b/src/build_visitor.cpp index 367726a..6a209d3 100644 --- a/src/build_visitor.cpp +++ b/src/build_visitor.cpp @@ -58,12 +58,14 @@ void BuildVisitor::Visit(Namespace* node) { if (child_count > 3) { // "namespace", ["var"/"const",] type, scope std::string modifier = parse_node.NthChild(1).GetValue(); if (modifier == "const") { - node->modifier = utils::IsConstModifier::Const; + node->modifier = utils::ClassInternalsModifier::Const; } else if (modifier == "var") { - node->modifier = utils::IsConstModifier::Var; + node->modifier = utils::ClassInternalsModifier::Var; } else { error_handling::HandleInternalError("Can't parse namespace modifier", "BuildVisitor.Namespace"); } + } else { + node->modifier = utils::ClassInternalsModifier::Static; } node->type = parse_node.ChildByFieldName("type").GetValue(); @@ -273,15 +275,26 @@ void BuildVisitor::Visit(TypeclassDefinitionStatement* node) { size_t child_count = parse_node.NamedChildCount(); - for (size_t i = 0; i + 1 < child_count; ++i) { - current_node_ = parse_node.NthNamedChild(i + 1); - if (current_node_.PreviousSibling().GetValue() != "var") { - node->function_requirements.push_back(std::make_unique()); - Visit(node->function_requirements.back().get()); - } else { - node->method_requirements.push_back(std::make_unique()); - Visit(node->method_requirements.back().get()); - } + if (child_count > 1) { + node->requirements.reserve(child_count - 1); + + for (size_t i = 0; i + 1 < child_count; ++i) { + current_node_ = parse_node.NthNamedChild(i + 1); + + std::string modifier_name = current_node_.PreviousSibling().GetValue(); + utils::ClassInternalsModifier modifier; + if (modifier_name == "const") { + modifier = utils::ClassInternalsModifier::Const; + } else if (modifier_name == "var") { + modifier = utils::ClassInternalsModifier::Var; + } else { + modifier = utils::ClassInternalsModifier::Static; + } + node->requirements.push_back({modifier, + std::make_unique()}); + Visit(node->requirements.back().second.get()); + } + } current_node_ = parse_node; diff --git a/src/find_symbols_visitor.cpp b/src/find_symbols_visitor.cpp index 2273a82..9b97e15 100644 --- a/src/find_symbols_visitor.cpp +++ b/src/find_symbols_visitor.cpp @@ -135,17 +135,11 @@ void FindSymbolsVisitor::Visit(TypeclassDefinitionStatement* node) { current_info_.reset(); } - namespace_visitor_.AddEnterNamespace(type_name, std::nullopt, node->base); - for (size_t i = 0; i < node->function_requirements.size(); ++i) { - Visit(node->function_requirements[i].get()); + for (size_t i = 0; i < node->requirements.size(); ++i) { + namespace_visitor_.AddEnterNamespace(type_name, node->requirements[i].first, node->base); + 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; diff --git a/src/global_info.cpp b/src/global_info.cpp index 766dd30..d95f3a9 100644 --- a/src/global_info.cpp +++ b/src/global_info.cpp @@ -18,7 +18,7 @@ void GlobalInfo::NamespaceVisitor::AddImport(definition::Import&& import_info, } void GlobalInfo::NamespaceVisitor::AddEnterNamespace(const std::string& name, - std::optional modifier, + utils::ClassInternalsModifier modifier, const interpreter::tokens::BaseNode& base_node) { if (type::ToInternalType(name).has_value()) { 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]; - if (modifier.has_value()) { + if (modifier != utils::ClassInternalsModifier::Static) { namespace_info->modifier = modifier; } @@ -51,7 +51,7 @@ void GlobalInfo::NamespaceVisitor::AddEnterNamespace(const std::string& name, } void GlobalInfo::NamespaceVisitor::EnterNamespace(const std::string& name, - std::optional modifier) { + utils::ClassInternalsModifier modifier) { for (ssize_t i = (ssize_t)namespace_stack_.size() - 1; i >= 0; --i) { auto current_namespaces = ChooseNamespaces(modifier, i); auto namespace_iter = current_namespaces->find(name); @@ -222,6 +222,7 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddAbstractType(const std::string& a return id; } +// TODO: which info needed ?? utils::IdType GlobalInfo::NamespaceVisitor::AddTypeclass(const std::string& typeclass, definition::Typeclass&& typeclass_info, 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_.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; } @@ -282,14 +289,14 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddPartition(const std::vector GlobalInfo::NamespaceVisitor::FindNamespace(const std::optional>& path) { +std::optional GlobalInfo::NamespaceVisitor::FindNamespaceId(const std::optional>& path) { return FindSomething(path, [] (utils::IdType current_namespace) -> std::optional { return current_namespace; }); } -std::optional GlobalInfo::NamespaceVisitor::FindFunction( +std::optional GlobalInfo::NamespaceVisitor::FindFunctionId( const std::optional>& path, const std::string& name) { return FindSomething(path, @@ -304,7 +311,7 @@ std::optional GlobalInfo::NamespaceVisitor::FindFunction( }); } -std::optional GlobalInfo::NamespaceVisitor::FindMethod( +std::optional GlobalInfo::NamespaceVisitor::FindMethodId( const std::optional>& path, const std::string& type, const std::string& name, @@ -335,7 +342,7 @@ std::optional GlobalInfo::NamespaceVisitor::FindMethod( }); } -std::optional GlobalInfo::NamespaceVisitor::FindType( +std::optional GlobalInfo::NamespaceVisitor::FindTypeId( const std::optional>& path, const std::string& type) { return FindSomething(path, @@ -350,7 +357,7 @@ std::optional GlobalInfo::NamespaceVisitor::FindType( }); } -std::optional GlobalInfo::NamespaceVisitor::FindLocalType(const std::string& type) { +std::optional GlobalInfo::NamespaceVisitor::FindLocalTypeId(const std::string& 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()) { @@ -360,7 +367,7 @@ std::optional GlobalInfo::NamespaceVisitor::FindLocalType(const s return std::nullopt; } -std::optional GlobalInfo::NamespaceVisitor::FindAbstractType(const std::string& abstract_type) { +std::optional GlobalInfo::NamespaceVisitor::FindAbstractTypeId(const std::string& 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()) { @@ -370,7 +377,7 @@ std::optional GlobalInfo::NamespaceVisitor::FindAbstractType(cons return std::nullopt; } -std::optional GlobalInfo::NamespaceVisitor::FindTypeclass(const std::string& typeclass) { +std::optional GlobalInfo::NamespaceVisitor::FindTypeclassId(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()) { @@ -380,7 +387,7 @@ std::optional GlobalInfo::NamespaceVisitor::FindTypeclass(const s return std::nullopt; } -std::optional GlobalInfo::NamespaceVisitor::FindConstructor( +std::optional GlobalInfo::NamespaceVisitor::FindConstructorId( const std::optional>& path, const std::string& constructor) { return FindSomething(path, @@ -439,17 +446,19 @@ std::optional GlobalInfo::NamespaceVisitor::FindNamespaceIn( } std::unordered_map* - GlobalInfo::NamespaceVisitor::ChooseNamespaces(std::optional modifier, + GlobalInfo::NamespaceVisitor::ChooseNamespaces(utils::ClassInternalsModifier modifier, utils::IdType namespace_id) { std::unordered_map* current_namespaces = nullptr; - if (modifier.has_value()) { - if (modifier.value() == utils::IsConstModifier::Const) { + switch (modifier) { + case utils::ClassInternalsModifier::Const: current_namespaces = &global_info_.namespaces_[namespace_id].const_namespaces; - } else { + break; + case utils::ClassInternalsModifier::Var: current_namespaces = &global_info_.namespaces_[namespace_id].var_namespaces; - } - } else { - current_namespaces = &global_info_.namespaces_[namespace_id].namespaces; + break; + case utils::ClassInternalsModifier::Static: + current_namespaces = &global_info_.namespaces_[namespace_id].namespaces; + break; } return current_namespaces; diff --git a/src/link_symbols_visitor.cpp b/src/link_symbols_visitor.cpp index 5d939c3..aa2e9b6 100644 --- a/src/link_symbols_visitor.cpp +++ b/src/link_symbols_visitor.cpp @@ -12,11 +12,11 @@ namespace interpreter { void LinkSymbolsVisitor::Visit(Namespace* node) { // Visitor::Visit(&node->type); // not needed - std::optional maybe_type = namespace_visitor_.FindLocalType(node->type); + std::optional maybe_type = namespace_visitor_.FindLocalTypeId(node->type); std::optional maybe_typeclass; 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()) { @@ -49,8 +49,8 @@ void LinkSymbolsVisitor::Visit(TypeExpression* node) { // TODO: check path.push_back(path_type.type); } - node->type_id_ = namespace_visitor_.FindType(path, node->type.type); - node->constructor_id_ = namespace_visitor_.FindConstructor(path, node->type.type); + node->type_id_ = namespace_visitor_.FindTypeId(path, node->type.type); + node->constructor_id_ = namespace_visitor_.FindConstructorId(path, node->type.type); // internal type 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(); } - std::optional maybe_type_namespace = namespace_visitor_.FindNamespace(path); + std::optional maybe_type_namespace = namespace_visitor_.FindNamespace(path); 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) { 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 void LinkSymbolsVisitor::Visit(ParametrizedTypeclass* node) { // TODO: check - std::optional maybe_typeclass = namespace_visitor_.FindTypeclass(node->typeclass); + std::optional maybe_typeclass = namespace_visitor_.FindTypeclassId(node->typeclass); if (maybe_typeclass.has_value()) { node->typeclass_id_ = maybe_typeclass.value(); diff --git a/src/print_visitor.cpp b/src/print_visitor.cpp index 46b8069..d362f5f 100644 --- a/src/print_visitor.cpp +++ b/src/print_visitor.cpp @@ -25,15 +25,15 @@ void PrintVisitor::Visit(NamespaceSources* node) { void PrintVisitor::Visit(Namespace* node) { out_ << "[Namespace] "; - if (node->modifier.has_value()) { - switch (node->modifier.value()) { - case utils::IsConstModifier::Const: - out_ << "const "; - break; - case utils::IsConstModifier::Var: - out_ << "var "; - break; - } + switch (node->modifier) { + case utils::ClassInternalsModifier::Const: + out_ << "const "; + break; + case utils::ClassInternalsModifier::Var: + out_ << "var "; + break; + case utils::ClassInternalsModifier::Static: + break; } Visit(&node->type); out_ << "{\n"; @@ -157,20 +157,22 @@ void PrintVisitor::Visit(AbstractTypeDefinitionStatement* node) { void PrintVisitor::Visit(TypeclassDefinitionStatement* node) { out_ << "[Typeclass] ("; Visit(node->definition.get()); - if (!node->function_requirements.empty()) { + if (!node->requirements.empty()) { out_ << ") : (\n"; } - for (auto& requirement : node->function_requirements) { + for (auto& requirement : node->requirements) { out_ << "& "; - Visit(requirement.get()); - out_ << "\n"; - } - if (!node->method_requirements.empty()) { - out_ << ") : (\n"; - } - for (auto& requirement : node->method_requirements) { - out_ << "& var "; - Visit(requirement.get()); + switch (requirement.first) { + case utils::ClassInternalsModifier::Const: + out_ << "const "; + break; + case utils::ClassInternalsModifier::Var: + out_ << "var "; + break; + case utils::ClassInternalsModifier::Static: + break; + } + Visit(requirement.second.get()); out_ << "\n"; } out_ << ")\n"; @@ -392,15 +394,15 @@ void PrintVisitor::Visit(ReferenceExpression* node) { out_ << "[ReferenceExpression "; for (auto& reference : node->references) { switch (reference) { - case utils::ReferenceModifier::Reference: - out_ << '^'; - break; - case utils::ReferenceModifier::UniqueReference: - out_ << '@'; - break; - case utils::ReferenceModifier::Dereference: - out_ << '~'; - break; + case utils::ReferenceModifier::Reference: + out_ << '^'; + break; + case utils::ReferenceModifier::UniqueReference: + out_ << '@'; + break; + case utils::ReferenceModifier::Dereference: + out_ << '~'; + break; } } out_ << "] ("; @@ -491,11 +493,11 @@ void PrintVisitor::Visit(TypeConstructorParameter* node) { Visit(&node->name.value()); switch (node->asignment_modifier.value()) { case utils::AssignmentModifier::Assign: - out_ << " = "; - break; + out_ << " = "; + break; case utils::AssignmentModifier::Move: - out_ << " <- "; - break; + out_ << " <- "; + break; } } Visitor::Visit(node->value); diff --git a/src/type_check_visitor.cpp b/src/type_check_visitor.cpp index 40b61b5..323578e 100644 --- a/src/type_check_visitor.cpp +++ b/src/type_check_visitor.cpp @@ -38,9 +38,9 @@ void TypeCheckVisitor::Visit(Namespace* node) { // TODO: two var namespces for c std::vector requirements {node->link_typeclass_id_.value()}; utils::IdType abstract_type = context_manager_.AddValue( 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, abstract_type); } else { @@ -48,7 +48,7 @@ void TypeCheckVisitor::Visit(Namespace* node) { // TODO: two var namespces for c } context_manager_.DefineLocalType(node->type, abstract_type); } 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(node->link_type_id_.value()); if (!maybe_type_info.has_value()) { @@ -64,7 +64,7 @@ void TypeCheckVisitor::Visit(Namespace* node) { // TODO: two var namespces for c current_type_, maybe_type_info.value()->modifier, context_manager_.GetValueManager()), - IsConstModifierToValueType(node->modifier.value()))); + ClassInternalsModifierToValueType(node->modifier))); } else { context_manager_.EnterContext(); } @@ -599,7 +599,7 @@ void TypeCheckVisitor::Visit(LoopControlExpression& node) { // enum // TODO: better structure void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) { // 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; node->is_method_ = false; @@ -621,16 +621,16 @@ void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) { std::string left_type_name = maybe_left_type_info.value()->type.type; - auto maybe_const_operator_id = namespace_visitor_.FindMethod(std::nullopt, - left_type_name, - node->operator_name, - utils::IsConstModifier::Const); + auto maybe_const_operator_id = namespace_visitor_.FindMethodId(std::nullopt, + left_type_name, + node->operator_name, + utils::IsConstModifier::Const); if (left_value_type != utils::ValueType::Const) { - maybe_operator_id = namespace_visitor_.FindMethod(std::nullopt, - left_type_name, - node->operator_name, - utils::IsConstModifier::Var); + maybe_operator_id = namespace_visitor_.FindMethodId(std::nullopt, + left_type_name, + node->operator_name, + utils::IsConstModifier::Var); } if (!maybe_operator_id.has_value() && !maybe_const_operator_id.has_value()) { @@ -795,14 +795,14 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) { } 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>(node->prefix.value()), context); } else { // error } } 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()) { diff --git a/src/typed_print_visitor.cpp b/src/typed_print_visitor.cpp index a3ff3e1..9cb18ee 100644 --- a/src/typed_print_visitor.cpp +++ b/src/typed_print_visitor.cpp @@ -43,15 +43,15 @@ void TypedPrintVisitor::Visit(Namespace* node) { } out_ << "] "; - if (node->modifier.has_value()) { - switch (node->modifier.value()) { - case utils::IsConstModifier::Const: - out_ << "const "; - break; - case utils::IsConstModifier::Var: - out_ << "var "; - break; - } + switch (node->modifier) { + case utils::ClassInternalsModifier::Const: + out_ << "const "; + break; + case utils::ClassInternalsModifier::Var: + out_ << "var "; + break; + case utils::ClassInternalsModifier::Static: + break; } Visit(&node->type); out_ << "{\n"; @@ -87,14 +87,14 @@ void TypedPrintVisitor::Visit(AliasDefinitionStatement* node) { out_ << ") "; switch (node->modifier) { case utils::AliasModifier::Alias: - out_ << "alias"; - break; + out_ << "alias"; + break; case utils::AliasModifier::Type: - out_ << "type"; - break; + out_ << "type"; + break; case utils::AliasModifier::Let: - out_ << "let"; - break; + out_ << "let"; + break; } out_ << ' '; Visit(&node->type); @@ -113,11 +113,11 @@ void TypedPrintVisitor::Visit(VariableDefinitionStatement* node) { out_ << ") "; switch (node->modifier) { case utils::IsConstModifier::Const: - out_ << "const"; - break; + out_ << "const"; + break; case utils::IsConstModifier::Var: - out_ << "var"; - break; + out_ << "var"; + break; } out_ << ' '; Visitor::Visit(node->name); @@ -172,11 +172,11 @@ void TypedPrintVisitor::Visit(TypeDefinitionStatement* node) { out_ << ") "; switch (node->modifier) { case utils::ClassModifier::Struct: - out_ << "struct"; - break; + out_ << "struct"; + break; case utils::ClassModifier::Class: - out_ << "class"; - break; + out_ << "class"; + break; } if (node->is_in_interface) { out_ << " interface"; @@ -198,11 +198,11 @@ void TypedPrintVisitor::Visit(AbstractTypeDefinitionStatement* node) { out_ << ") "; switch (node->modifier) { case utils::AbstractTypeModifier::Basic: - out_ << "basic"; - break; + out_ << "basic"; + break; case utils::AbstractTypeModifier::Abstract: - out_ << "abstract"; - break; + out_ << "abstract"; + break; } out_ << "] ("; Visit(node->type.get()); @@ -218,20 +218,22 @@ void TypedPrintVisitor::Visit(TypeclassDefinitionStatement* node) { out_ << "] ("; Visit(node->definition.get()); - if (!node->function_requirements.empty()) { + if (!node->requirements.empty()) { out_ << ") : (\n"; } - for (auto& requirement : node->function_requirements) { + for (auto& requirement : node->requirements) { out_ << "& "; - Visit(requirement.get()); - out_ << "\n"; - } - if (!node->method_requirements.empty()) { - out_ << ") : (\n"; - } - for (auto& requirement : node->method_requirements) { - out_ << "& var "; - Visit(requirement.get()); + switch (requirement.first) { + case utils::ClassInternalsModifier::Const: + out_ << "const "; + break; + case utils::ClassInternalsModifier::Var: + out_ << "var "; + break; + case utils::ClassInternalsModifier::Static: + break; + } + Visit(requirement.second.get()); out_ << "\n"; } out_ << ")\n"; diff --git a/src/visitor.cpp b/src/visitor.cpp index 87ee5d6..967d168 100644 --- a/src/visitor.cpp +++ b/src/visitor.cpp @@ -357,11 +357,8 @@ void Visitor::Visit(AbstractTypeDefinitionStatement* node) { void Visitor::Visit(TypeclassDefinitionStatement* node) { Visit(node->definition.get()); - for (auto& function_requirement : node->function_requirements) { - Visit(function_requirement.get()); - } - for (auto& method_requirement : node->method_requirements) { - Visit(method_requirement.get()); + for (auto& function_requirement : node->requirements) { + Visit(function_requirement.second.get()); } }