diff --git a/include/contexts.hpp b/include/contexts.hpp index 5b6005b..c5fc083 100644 --- a/include/contexts.hpp +++ b/include/contexts.hpp @@ -33,10 +33,7 @@ private: std::unordered_map variables_; }; - // TODO handle current namespace (for class names, function names, etc.) - // TODO ?? are global variables forbidden ?? - - Context global_context_; + // Context global_context_; // ?? std::vector contexts_; }; diff --git a/include/global_info.hpp b/include/global_info.hpp index dd2d5a6..e0047a8 100644 --- a/include/global_info.hpp +++ b/include/global_info.hpp @@ -6,202 +6,90 @@ // for clangd #include "symbols_info.hpp" +#include "utils.hpp" namespace info { // TODO: partitions class GlobalInfo { + friend class NamespaceVisitor; public: - GlobalInfo() { - namespace_stack_.push_back(&global_namespace_); + class NamespaceVisitor { + friend GlobalInfo; + NamespaceVisitor() = delete; + public: + void AddImport(ImportInfo&& import_info, const std::optional& name = std::nullopt); + + void AddEnterNamespace(const std::string& name, + const std::optional& modifier = std::nullopt, + const std::optional& variable = std::nullopt); + + void EnterNamespace(const std::string& name); + + void ExitNamespace(); + + void ToGlobalNamespace(); + + utils::IdType AddFunctionDeclaration(const std::string& name, + FunctionDeclarationInfo&& function_declaration_info); + + utils::IdType AddFunctionDefinition(const std::string& name, + FunctionDefinitionInfo&& function_definition_info); + + utils::IdType AddType(const std::string& type, TypeInfo&& type_info); + + utils::IdType AddTypeclass(const std::string& typeclass, TypeclassInfo&& typeclass_info); + + std::optional FindNamespace(const std::optional>& path); + + std::optional FindFunction(const std::optional>& path, + const std::string& name); + + std::optional FindMethod(const std::optional>& path, + const std::string& type, + const std::string& name); + + std::optional FindType(const std::optional>& path, + const std::string type); + + std::optional FindTypeclass(const std::optional>& path, + const std::string typeclass); + private: + NamespaceVisitor(GlobalInfo& global_info) : global_info_(global_info), + namespace_stack_({&global_info.global_namespace_}) {} + + template + std::optional FindSomething(const std::optional>& path, + std::function(NamespaceInfo*)> search_func); + + std::optional FindNamespaceIn(NamespaceInfo* current_namespace, + const std::vector& path); + private: + std::vector namespace_stack_; + + GlobalInfo& global_info_; + }; + + NamespaceVisitor CreateVisitor() { + return NamespaceVisitor(*this); } - void AddImport(ImportInfo&& import_info, const std::optional& name = std::nullopt) { - if (name.has_value()) { - usages_[name.value()] = std::move(import_info); - } else { - imports_.push_back(std::move(import_info)); - } + FunctionInfo* GetFunctionInfo(utils::IdType id) { + return functions_.GetValue(id); } - void AddEnterNamespace(const std::string& name, - const std::optional& modifier = std::nullopt, - const std::optional& variable = std::nullopt) { - NamespaceInfo* namespace_info = nullptr; - if (variable.has_value()) { - namespace_info = &namespace_stack_.back()->variable_namespaces[name].emplace_back(); - namespace_stack_.push_back(namespace_info); - - namespace_info->modifier = modifier; - namespace_info->variable = variable; - } else { - namespace_info = &namespace_stack_.back()->namespaces[name]; - namespace_stack_.push_back(namespace_info); - } - - namespace_info->type_name = name; + TypeInfo* GetTypeInfo(utils::IdType id) { + return types_.GetValue(id); } - void EnterNamespace(const std::string& name) { // TODO: enter sibling namespace, etc. - namespace_stack_.push_back(&namespace_stack_.back()->namespaces[name]); - } - - void ExitAllNameNamespaces(const std::string& name) { - while(namespace_stack_.size() > 1 && namespace_stack_.back()->type_name == name) { - namespace_stack_.pop_back(); - } - } - - void ExitNamespace() { - if (namespace_stack_.size() <= 1) { - // error - return; - } - - namespace_stack_.pop_back(); - } - - void ToGlobalNamespace() { - namespace_stack_.clear(); - namespace_stack_.push_back(&global_namespace_); - } - - void AddFunctionDeclaration(const std::string& name, - FunctionDeclarationInfo&& function_declaration_info) { - FunctionInfo* function_info = &namespace_stack_.back()->functions[name]; - - function_info->declaration = std::move(function_declaration_info); - } - - void AddFunctionDefinition(const std::string& name, - FunctionDefinitionInfo&& function_definition_info) { - FunctionInfo* function_info = &namespace_stack_.back()->functions[name]; - - function_info->definition = std::move(function_definition_info); - } - - void AddType(const std::string& type, TypeInfo&& type_info) { - namespace_stack_.back()->types[type] = std::move(type_info); - } - - void AddTypeclass(const std::string& typeclass, - TypeclassInfo&& typeclass_info) { - namespace_stack_.back()->typeclasses[typeclass] = std::move(typeclass_info); - } - - std::optional FindNamespace(const std::vector& path) { - return FindSomething(path, - [](NamespaceInfo* current_namespace) -> std::optional { - return current_namespace; - }); - } - - std::optional FindFunction(const std::vector& path, - const std::string& name) { - return FindSomething(path, - [name](NamespaceInfo* current_namespace) -> std::optional { - - auto function_info_iter = current_namespace->functions.find(name); - if (function_info_iter == current_namespace->functions.end()) { - return std::nullopt; - } - - return &function_info_iter->second; - }); - } - - std::optional FindMethod(const std::vector& path, - const std::string& type, - const std::string& name) { - // TODO: remove overhead - - return FindSomething(path, - [type, name](NamespaceInfo* current_namespace) -> std::optional { - - auto variable_namespaces_iter = current_namespace->variable_namespaces.find(type); - if (variable_namespaces_iter == current_namespace->variable_namespaces.end()) { - return std::nullopt; - } - - for (auto& variable_namespace : variable_namespaces_iter->second) { - auto method_iter = variable_namespace.functions.find(name); - - if (method_iter == variable_namespace.functions.end()) { - continue; - } - - return &method_iter->second; - } - - return std::nullopt; - }); - } - - std::optional FindType(const std::vector& path, - const std::string type) { - return FindSomething(path, - [type](NamespaceInfo* current_namespace) -> std::optional { - - auto type_info_iter = current_namespace->types.find(type); - if (type_info_iter == current_namespace->types.end()) { - return std::nullopt; - } - - return &type_info_iter->second; - }); - } - - std::optional FindTypeclass(const std::vector& path, - const std::string typeclass) { - return FindSomething(path, - [typeclass](NamespaceInfo* current_namespace) -> std::optional { - - auto typeclass_info_iter = current_namespace->typeclasses.find(typeclass); - if (typeclass_info_iter == current_namespace->typeclasses.end()) { - return std::nullopt; - } - - return &typeclass_info_iter->second; - }); + TypeclassInfo* GetTypeclassInfo(utils::IdType id) { + return typeclasses_.GetValue(id); } private: - template - std::optional FindSomething(const std::vector& path, - std::function(NamespaceInfo*)> search_func) { - for (ssize_t i = namespace_stack_.size(); i >= 0; --i) { - auto maybe_namespace = FindNamespaceIn(namespace_stack_[i], path); - - if (!maybe_namespace.has_value()) { - continue; - } - - std::optional result = search_func(maybe_namespace.value()); - - if (result.has_value()) { - return result.value(); - } - } - - return std::nullopt; - } - - std::optional FindNamespaceIn(NamespaceInfo* current_namespace, - const std::vector& path) { - NamespaceInfo* next_namespace = current_namespace; - for (auto& name : path) { - auto next_namespace_iter = next_namespace->namespaces.find(name); - if (next_namespace_iter == next_namespace->namespaces.end()) { - return std::nullopt; - } - next_namespace = &next_namespace_iter->second; - } - - return next_namespace; - } - -private: - std::vector namespace_stack_; + utils::Storage functions_; + utils::Storage types_; + utils::Storage typeclasses_; NamespaceInfo global_namespace_; std::vector imports_; diff --git a/include/symbols_info.hpp b/include/symbols_info.hpp index 790eb18..7c0bc9b 100644 --- a/include/symbols_info.hpp +++ b/include/symbols_info.hpp @@ -9,6 +9,7 @@ #include // for clangd +#include "utils.hpp" namespace interpreter { class Node; @@ -110,9 +111,9 @@ struct ImportInfo { struct NamespaceInfo { enum Modifier { Const, Var }; - std::unordered_map types; - std::unordered_map typeclasses; - std::unordered_map functions; + std::unordered_map types; + std::unordered_map typeclasses; + std::unordered_map functions; std::unordered_map namespaces; std::unordered_map> variable_namespaces; diff --git a/include/type_check_visitor.hpp b/include/type_check_visitor.hpp index 3d49dfd..fbbc83f 100644 --- a/include/type_check_visitor.hpp +++ b/include/type_check_visitor.hpp @@ -1,14 +1,19 @@ #pragma once // for clangd +#include "type_info_contexts.hpp" +#include "symbols_info.hpp" #include "visitor.hpp" #include "global_info.hpp" +#include "type_graph.hpp" namespace interpreter { class TypeCheckVisitor : public Visitor { public: - explicit TypeCheckVisitor(info::GlobalInfo& global_info) : global_info_(global_info) {} + explicit TypeCheckVisitor(info::GlobalInfo& global_info, + info::TypeGraph& type_graph) + : global_info_(global_info), type_graph_(type_graph) {} private: // Sources ----------------- @@ -99,9 +104,9 @@ private: // Identifiers, constants, etc. ----------------- - void Visit(ExtendedName* node) override; + // // void Visit(ExtendedName* node) override; - void Visit(std::string* node) override; // std::string + // // void Visit(std::string* node) override; // std::string void Visit(FloatNumberLiteral* node) override; void Visit(NumberLiteral* node) override; @@ -110,6 +115,10 @@ private: private: info::GlobalInfo& global_info_; + info::TypeGraph type_graph_; + info::TypeInfoContextManager context_manager_; + + info::TypeInfo current_type_; }; } // namespace interpreter diff --git a/include/type_graph.hpp b/include/type_graph.hpp index cf49a13..ea5b7a6 100644 --- a/include/type_graph.hpp +++ b/include/type_graph.hpp @@ -4,6 +4,11 @@ #include #include +// for clangd +#include "utils.hpp" + +namespace info { + // TODO: optimize recalc class TypeGraph { @@ -17,11 +22,11 @@ public: vertex.path = path; for (auto& method : methods) { - vertex.new_requirements.methods.insert(GetHash(method)); + vertex.new_requirements.methods.insert(storage_.GetId(method)); } for (auto& typeclass : typeclasses) { - vertex.new_requirements.typeclasses.insert(GetHash(typeclass)); + vertex.new_requirements.typeclasses.insert(storage_.GetId(typeclass)); } verticles_.push_back(vertex); @@ -49,13 +54,13 @@ public: methods.reserve(cluster_requirements_[cluster_id].methods.size()); for (auto& method : cluster_requirements_[cluster_id].methods) { - methods.push_back(std::move(GetString(method))); + methods.push_back(std::move(storage_.GetValue(method))); } return methods; } - std::vector VertexTypeclasses(size_t id) { + std::vector VertexTypeclasses(size_t id) { if (!is_calculated_) { // error return {}; @@ -63,27 +68,27 @@ public: size_t cluster_id = verticles_[id].cluster.value(); - std::vector typeclasses; + std::vector typeclasses; typeclasses.reserve(cluster_requirements_[cluster_id].typeclasses.size()); for (auto& typeclass : cluster_requirements_[cluster_id].typeclasses) { - typeclasses.push_back(std::move(GetString(typeclass))); + typeclasses.push_back(typeclass); } return typeclasses; } - void AddTypeclass(size_t id, const std::string& method) { + void AddMethod(size_t id, const std::string& method) { is_calculated_ = false; - verticles_[id].new_requirements.methods.insert(GetHash(method)); + verticles_[id].new_requirements.methods.insert(storage_.GetId(method)); } - void AddMethod(size_t id, const std::string& typeclass) { + void AddTypeclass(size_t id, utils::IdType typeclass) { is_calculated_ = false; - verticles_[id].new_requirements.typeclasses.insert(GetHash(typeclass)); + verticles_[id].new_requirements.typeclasses.insert(typeclass); } void AddEdge(size_t from, size_t to) { @@ -150,8 +155,8 @@ public: private: struct RequirementsData { - std::unordered_set methods; - std::unordered_set typeclasses; + std::unordered_set methods; + std::unordered_set typeclasses; }; struct Vertex { @@ -204,27 +209,8 @@ private: return sorted_verticles; } - size_t GetHash(const std::string& str) { - size_t hash = 0; - auto str_position = string_to_hash_.find(str); - - if (str_position == string_to_hash_.end()) { - hash = hash_to_string_.size(); - string_to_hash_[str] = hash; - hash_to_string_.push_back(str); - } else { - hash = str_position->second; - } - - return hash; - } - - std::string GetString(size_t hash) { - return hash_to_string_[hash]; - } - private: - std::unordered_map, size_t> verticle_ids_; + std::unordered_map, size_t> verticle_ids_; std::vector> edges_; std::vector> back_edges_; std::vector verticles_; @@ -232,8 +218,9 @@ private: std::vector> clusters_; std::vector cluster_requirements_; - std::vector hash_to_string_; - std::unordered_map string_to_hash_; + utils::Storage storage_; bool is_calculated_ = false; }; + +} // namespace info diff --git a/include/type_info_contexts.hpp b/include/type_info_contexts.hpp new file mode 100644 index 0000000..562c80c --- /dev/null +++ b/include/type_info_contexts.hpp @@ -0,0 +1,96 @@ +#pragma once + +#include +#include +#include + +// for clangd +#include "symbols_info.hpp" + +namespace info { + +class TypeInfoContextManager { +public: + void CallFunction(const std::vector& names, + const std::vector& types) { + if (names.size() != types.size()) { + // error + } + + contexts_.emplace_back(true); + + for (size_t i = 0; i < names.size(); ++i) { + DefineVariable(names[i], types[i]); + } + } + + void EnterContext() { + contexts_.emplace_back(false); + } + + void ExitContext() { + if (contexts_.empty()) { + // error + } + + contexts_.pop_back(); + } + + void ExitFromAllContexts() { + contexts_.clear(); + } + + // TODO Variable modifiers + bool DefineVariable(const std::string& name, TypeInfo* type) { + return contexts_.back().DefineVariable(name, type); + } + + void EnterVariableContext(const std::string& name, TypeInfo* type) { // for variable namespaces, for loops + contexts_.push_back(false); + + DefineVariable(name, type); + } + + std::optional GetVariableType(const std::string& name) { + for (ssize_t i = contexts_.size() - 1; i >= 0; --i) { + auto maybe_type = contexts_[i].GetVariableType(name); + if (maybe_type.has_value()) { + return maybe_type.value(); + } + } + return std::nullopt; + } + +private: + class Context { + public: + Context(bool hide_previous) : hide_previous_(hide_previous) {} + + bool DefineVariable(const std::string& name, TypeInfo* type) { + if (variables_.count(name) > 0) { + return false; + } + variables_[name] = type; + return true; + } + + std::optional GetVariableType(const std::string& name) { + auto variable_iter = variables_.find(name); + + if (variable_iter == variables_.end()) { + return std::nullopt; + } + + return variable_iter->second; + } + + bool IsFirst() { return hide_previous_; } + private: + bool hide_previous_; + std::unordered_map variables_; + }; + + std::vector contexts_; +}; + +} // namespace info diff --git a/include/types_info.hpp b/include/types_info.hpp new file mode 100644 index 0000000..f834a80 --- /dev/null +++ b/include/types_info.hpp @@ -0,0 +1,48 @@ +// for clangd +#include "symbols_info.hpp" + +namespace info { + +struct BasicType { + std::string name; + std::vector methods; // ?? + std::vector typeclasses; +}; + +struct AbstractType { + size_t graph_id; +}; + +struct TupleType; +struct VariantType; +struct ReferenceType; +using AnyType = std::variant, + std::unique_ptr, + std::unique_ptr, + std::unique_ptr, + std::unique_ptr>; + +struct TupleType { + std::vector, AnyType>> fields; +}; + +struct VariantType { + std::vector> constructors; +}; + +struct ReferenceType { + enum { Reference, UniqueReference } reference_type; + AnyType type; +}; + +struct FunctionalType { + +}; + +struct Type { + size_t graph_id_; + TypeInfo* info = nullptr; + std::vector requrements_; +}; + +} // namespace info diff --git a/include/utils.hpp b/include/utils.hpp new file mode 100644 index 0000000..5313b3b --- /dev/null +++ b/include/utils.hpp @@ -0,0 +1,36 @@ +#include +#include +#include + +namespace utils { + +using IdType = std::size_t; + +template +class Storage { +public: + IdType GetId(const T& value) { + IdType id = 0; + auto value_position = value_to_id_.find(value); + + if (value_position == value_to_id_.end()) { + id = id_to_value_.size(); + value_to_id_[value] = id; + id_to_value_.push_back(value); + } else { + id = value_position->second; + } + + return id; + } + + const T& GetValue(IdType id) { + return id_to_value_[id]; + } + +private: + std::vector id_to_value_; + std::unordered_map value_to_id_; +}; + +} // namespace utils diff --git a/src/.global_info.cpp.kate-swp b/src/.global_info.cpp.kate-swp new file mode 100644 index 0000000..a2a7ac1 Binary files /dev/null and b/src/.global_info.cpp.kate-swp differ diff --git a/src/global_info.cpp b/src/global_info.cpp new file mode 100644 index 0000000..edf7847 --- /dev/null +++ b/src/global_info.cpp @@ -0,0 +1,226 @@ +// for clangd +#include "../include/global_info.hpp" + +namespace info { + +void GlobalInfo::NamespaceVisitor::AddImport(ImportInfo&& import_info, + const std::optional& name) { + if (name.has_value()) { + global_info_.usages_[name.value()] = std::move(import_info); + } else { + global_info_.imports_.push_back(std::move(import_info)); + } +} + +void GlobalInfo::NamespaceVisitor::AddEnterNamespace(const std::string& name, + const std::optional& modifier, + const std::optional& variable) { + NamespaceInfo* namespace_info = nullptr; + if (variable.has_value()) { + namespace_info = &namespace_stack_.back()->variable_namespaces[name].emplace_back(); + namespace_stack_.push_back(namespace_info); + + namespace_info->modifier = modifier; + namespace_info->variable = variable; + } else { + namespace_info = &namespace_stack_.back()->namespaces[name]; + namespace_stack_.push_back(namespace_info); + } + + namespace_info->type_name = name; +} + +void GlobalInfo::NamespaceVisitor::EnterNamespace(const std::string& name) { // TODO: enter sibling namespace, etc. + namespace_stack_.push_back(&namespace_stack_.back()->namespaces[name]); +} + +void GlobalInfo::NamespaceVisitor::ExitNamespace() { + if (namespace_stack_.size() <= 1) { + // error + return; + } + + namespace_stack_.pop_back(); +} + +void GlobalInfo::NamespaceVisitor::ToGlobalNamespace() { + namespace_stack_.clear(); + namespace_stack_.push_back(&global_info_.global_namespace_); +} + +utils::IdType GlobalInfo::NamespaceVisitor::AddFunctionDeclaration(const std::string& name, + FunctionDeclarationInfo&& function_declaration_info) { + FunctionInfo* function_info = &namespace_stack_.back()->functions[name]; + + function_info->declaration = std::move(function_declaration_info); + + return global_info_.functions_.GetId(function_info); +} + +utils::IdType GlobalInfo::NamespaceVisitor::AddFunctionDefinition(const std::string& name, + FunctionDefinitionInfo&& function_definition_info) { + FunctionInfo* function_info = &namespace_stack_.back()->functions[name]; + + function_info->definition = std::move(function_definition_info); + + return global_info_.functions_.GetId(function_info); +} + +utils::IdType GlobalInfo::NamespaceVisitor::AddType(const std::string& type, + TypeInfo&& type_info) { + namespace_stack_.back()->types[type] = std::move(type_info); +} + +utils::IdType GlobalInfo::NamespaceVisitor::AddTypeclass(const std::string& typeclass, + TypeclassInfo&& typeclass_info) { + namespace_stack_.back()->typeclasses[typeclass] = std::move(typeclass_info); + + return global_info_.functions_.GetId(typeclass_info); +} + +std::optional GlobalInfo::NamespaceVisitor::FindNamespace(const std::optional>& path) { + return FindSomething(path, + [] (NamespaceInfo* current_namespace) -> std::optional { + return current_namespace; + }); +} + +std::optional GlobalInfo::NamespaceVisitor::FindFunction( + const std::optional>& path, + const std::string& name) { + auto result = FindSomething(path, + [name] (NamespaceInfo* current_namespace) -> std::optional { + + auto function_info_iter = current_namespace->functions.find(name); + if (function_info_iter == current_namespace->functions.end()) { + return std::nullopt; + } + + return &function_info_iter->second; + }); + + if (result.has_value()) { + return global_info_.functions_.GetId(result.value()); + } else { + return std::nullopt; + } +} + +std::optional GlobalInfo::NamespaceVisitor::FindMethod( + const std::optional>& path, + const std::string& type, + const std::string& name) { + // TODO: remove overhead + + auto result = GlobalInfo::NamespaceVisitor::FindSomething(path, + [type, name] (NamespaceInfo* current_namespace) -> std::optional { + + auto variable_namespaces_iter = current_namespace->variable_namespaces.find(type); + if (variable_namespaces_iter == current_namespace->variable_namespaces.end()) { + return std::nullopt; + } + + for (auto& variable_namespace : variable_namespaces_iter->second) { + auto method_iter = variable_namespace.functions.find(name); + + if (method_iter == variable_namespace.functions.end()) { + continue; + } + + return &method_iter->second; + } + + return std::nullopt; + }); + + if (result.has_value()) { + return global_info_.functions_.GetId(result.value()); + } else { + return std::nullopt; + } +} + +std::optional GlobalInfo::NamespaceVisitor::FindType( + const std::optional>& path, + const std::string type) { + auto result = FindSomething(path, + [type] (NamespaceInfo* current_namespace) -> std::optional { + + auto type_info_iter = current_namespace->types.find(type); + if (type_info_iter == current_namespace->types.end()) { + return std::nullopt; + } + + return &type_info_iter->second; + }); + + if (result.has_value()) { + return global_info_.types_.GetId(result.value()); + } else { + return std::nullopt; + } +} + +std::optional GlobalInfo::NamespaceVisitor::FindTypeclass( + const std::optional>& path, + const std::string typeclass) { + auto result = FindSomething(path, + [typeclass] (NamespaceInfo* current_namespace) -> std::optional { + + auto typeclass_info_iter = current_namespace->typeclasses.find(typeclass); + if (typeclass_info_iter == current_namespace->typeclasses.end()) { + return std::nullopt; + } + + return &typeclass_info_iter->second; + }); + + if (result.has_value()) { + return global_info_.typeclasses_.GetId(result.value()); + } else { + return std::nullopt; + } +} + +template +std::optional GlobalInfo::NamespaceVisitor::FindSomething( + const std::optional>& path, + std::function(NamespaceInfo*)> search_func) { + for (ssize_t i = namespace_stack_.size() - 1; i >= 0; --i) { + NamespaceInfo* current_namespace = nullptr; + if (path.has_value()) { + auto maybe_namespace = FindNamespaceIn(namespace_stack_[i], path.value()); + + if (!maybe_namespace.has_value()) { + continue; + } + } else { + current_namespace = namespace_stack_[i]; + } + + std::optional result = search_func(current_namespace); + + if (result.has_value()) { + return result.value(); + } + } + + return std::nullopt; +} + +std::optional GlobalInfo::NamespaceVisitor::FindNamespaceIn( + NamespaceInfo* current_namespace, + const std::vector& path) { + NamespaceInfo* next_namespace = current_namespace; + for (auto& name : path) { + auto next_namespace_iter = next_namespace->namespaces.find(name); + if (next_namespace_iter == next_namespace->namespaces.end()) { + return std::nullopt; + } + next_namespace = &next_namespace_iter->second; + } + + return next_namespace; +} + +} // namespace info diff --git a/src/type_check_visitor.cpp b/src/type_check_visitor.cpp index 52c98c3..61fc635 100644 --- a/src/type_check_visitor.cpp +++ b/src/type_check_visitor.cpp @@ -7,7 +7,6 @@ namespace interpreter { // Sources ----------------- void TypeCheckVisitor::Visit(SourceFile* node) { - out_ << "[SourceFile] (\n\n"; for (auto& statement : node->statements) { if (std::holds_alternative(statement)) { Visit(&std::get(statement)); @@ -17,295 +16,197 @@ void TypeCheckVisitor::Visit(SourceFile* node) { // error } } - out_ << "\n)\n"; } void TypeCheckVisitor::Visit(Sources* node) { - out_ << "[Sources](\n"; for (auto& statement : node->statements) { Visitor::Visit(statement); } - out_ << ")\n"; } // Namespaces, partitions ----------------- void TypeCheckVisitor::Visit(Partition* node) { - out_ << "[Partition] "; - switch (node->name) { - case Partition::Test: - out_ << "TEST"; - break; - case Partition::Interface: - out_ << "INTERFACE"; - break; - case Partition::Core: - out_ << "CORE"; - break; - case Partition::Lib: - out_ << "LIB"; - break; - case Partition::Module: - out_ << "MODULE"; - break; - case Partition::Exe: - out_ << "EXE"; - break; - } - out_ << " {\n"; Visit(node->scope.get()); - out_ << "}\n"; } void TypeCheckVisitor::Visit(Namespace* node) { - out_ << "[Namespace] "; if (node->name.has_value()) { if (node->modifier.has_value()) { - switch (node->modifier.value()) { + switch (node->modifier.value()) { // TODO case Namespace::Const: - out_ << "const "; + // TODO break; case Namespace::Var: - out_ << "var "; + // TODO break; } } else { // error } Visit(&node->name.value()); + context_manager_.EnterVariableContext(node->name.value().name, + global_info_.FindType(std::nullopt, node->type).value()); // TODO ?? } - Visit(&node->type); - out_ << "{\n"; + // global_info_.FindType(std::nullopt, node->type); // ?? + + global_info_.EnterNamespace(node->type); + Visit(node->scope.get()); - out_ << "}\n"; + + global_info_.ExitNamespace(); } // Definitions ----------------- -void TypeCheckVisitor::Visit(ImportStatement* node) { - if (node->name.has_value()) { - out_ << "[Use " << node->name.value() << "] = "; - } - out_ << "[Import " << node->module_name << "]"; - if (!node->symbols.empty()) { - out_ << " (\n"; - for (auto& symbol : node->symbols) { - Visit(&symbol); - out_ << '\n'; - } - out_ << ')'; - } - out_ << '\n'; +void TypeCheckVisitor::Visit(ImportStatement* node) { // TODO + // if (node->name.has_value()) { + // } + // if (!node->symbols.empty()) { + // for (auto& symbol : node->symbols) { + // Visit(&symbol); + // } + // } } void TypeCheckVisitor::Visit(AliasDefinitionStatement* node) { - out_ << "[Alias "; switch (node->modifier) { case AliasDefinitionStatement::Alias: - out_ << "alias"; break; case AliasDefinitionStatement::Type: - out_ << "type"; break; case AliasDefinitionStatement::Let: - out_ << "let"; break; } - out_ << ' '; + + Visit(&node->type); - out_ << "] = ("; Visit(node->value.get()); - out_ << ")\n"; } void TypeCheckVisitor::Visit(VariableDefinitionStatement* node) { - out_ << "[Variable "; switch (node->modifier) { case VariableDefinitionStatement::Const: - out_ << "const"; break; case VariableDefinitionStatement::Var: - out_ << "var"; break; } - out_ << ' '; Visitor::Visit(node->name); - out_ << "] = ("; Visitor::Visit(node->value); - out_ << ")\n"; } void TypeCheckVisitor::Visit(FunctionDeclaration* node) { - out_ << "[FunctionDeclaration "; Visit(&node->name); - out_ << "] ("; for (auto& parameter : node->parameters) { Visit(parameter.get()); } - out_ << ") : ("; Visit(node->type.get()); - out_ << ")\n"; } void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) { - out_ << "[Function] ("; Visit(node->definition.get()); - out_ << ") = ("; Visitor::Visit(node->value); - out_ << ")\n"; } void TypeCheckVisitor::Visit(TypeDefinitionStatement* node) { - out_ << "[Type "; switch (node->modifier) { case TypeDefinitionStatement::Struct: - out_ << "struct"; break; case TypeDefinitionStatement::Class: - out_ << "class"; break; } - out_ << "] ("; Visit(node->definition.get()); - out_ << ") = ("; Visitor::Visit(node->value); - out_ << ")\n"; } void TypeCheckVisitor::Visit(AbstractTypeDefinitionStatement* node) { - out_ << "[AbstractType "; switch (node->modifier) { case AbstractTypeDefinitionStatement::Basic: - out_ << "basic"; break; case AbstractTypeDefinitionStatement::Abstract: - out_ << "abstract"; break; } - out_ << "] ("; Visit(node->type.get()); - out_ << ")\n"; } void TypeCheckVisitor::Visit(TypeclassDefinitionStatement* node) { - out_ << "[Typeclass] ("; Visit(node->definition.get()); if (!node->requirements.empty()) { - out_ << ") : (\n"; } for (auto& requirement : node->requirements) { - out_ << "& "; Visit(requirement.get()); - out_ << "\n"; } - out_ << ")\n"; } // Definition parts void TypeCheckVisitor::Visit(FunctionDefinition* node) { - out_ << "[FunctionDefinition "; switch (node->modifier) { case FunctionDefinition::Operator: - out_ << "operator"; break; case FunctionDefinition::Function: - out_ << "function"; break; } - out_ << ' '; Visit(&node->name); - out_ << "]"; if (!node->parameters.empty()) { - out_ << " ("; for (auto& parameter : node->parameters) { Visit(parameter.get()); } - out_ << ')'; } if (!node->arguments.empty()) { - out_ << " : ("; for (auto& argument : node->arguments) { Visit(&argument); } - out_ << ')'; } - out_ << ' '; } void TypeCheckVisitor::Visit(TypeDefinition* node) { - out_ << "[TypeDefinition] ("; Visit(node->type.get()); - out_ << ')'; if (!node->parameters.empty()) { - out_ << '('; for (auto& parameter : node->parameters) { Visit(parameter.get()); } - out_ << ')'; } - out_ << ' '; } void TypeCheckVisitor::Visit(AnyAnnotatedType* node) { - out_ << "[Annotated (Abstract) Type "; Visit(&node->type); - out_ << ']'; if (!node->typeclasses.empty() > 0) { - out_ << " ("; for (auto& typeclass : node->typeclasses) { Visitor::Visit(typeclass); } - out_ << ')'; } - out_ << ' '; } // Flow control ----------------- void TypeCheckVisitor::Visit(MatchCase* node) { - out_ << "[MatchCase | "; Visitor::Visit(node->value); if (node->condition.has_value()) { - out_ << " ? "; Visitor::Visit(node->condition.value()); } if (node->statement.has_value()) { - out_ << " -> "; Visitor::Visit(node->statement.value()); } - out_ << "]\n"; } void TypeCheckVisitor::Visit(Match* node) { - out_ << "[Match] ("; Visitor::Visit(node->value); - out_ << ") [with] (\n"; for (auto& match_case : node->matches) { Visit(&match_case); } - out_ << ")\n"; } void TypeCheckVisitor::Visit(Condition* node) { - out_ << "[If] ("; Visitor::Visit(node->conditions[0]); - out_ << ") [then] (\n"; Visitor::Visit(node->statements[0]); - out_ << ')'; for (size_t i = 1; i < node->conditions.size(); ++i) { - out_ << " [elif] ("; Visitor::Visit(node->conditions[i]); - out_ << ") [then] (\n"; Visitor::Visit(node->statements[i]); - out_ << ')'; } if (node->statements.size() > node->conditions.size()) { - out_ << " [else] (\n"; Visitor::Visit(node->statements[node->conditions.size()]); - out_ << ')'; } - out_ << '\n'; } void TypeCheckVisitor::Visit(DoWhileLoop* node) { @@ -657,16 +558,8 @@ void TypeCheckVisitor::Visit(TypeclassExpression* node) { // Identifiers, constants, etc. ----------------- -void TypeCheckVisitor::Visit(ExtendedName* node) { - out_ << "[ExtendedName " << node->name << "] "; -} - -void TypeCheckVisitor::Visit(std::string* node) { // std::string - out_ << "[Identifier " << *node << "] "; -} - void TypeCheckVisitor::Visit(FloatNumberLiteral* node) { - out_ << "[FloatNumber " << node->value << "] "; + current_type_ = info::BuiltInTypeInfo::FloatT; } void TypeCheckVisitor::Visit(NumberLiteral* node) {