diff --git a/CMakeLists.txt b/CMakeLists.txt index c8c844f..ca1a949 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,10 @@ add_executable(lang_interpreter src/main.cpp src/visitor.cpp src/build_visitor.cpp src/print_visitor.cpp + src/find_symbols_visitor.cpp + src/link_symbols_visitor.cpp + src/type_check_visitor.cpp + src/typed_print_visitor.cpp lang-parser/src/parser.c lang-parser/src/tree_sitter/parser.h tree-sitter/lib/src/lib.c) diff --git a/archived/type_graph.hpp b/archived/type_graph.hpp index b5cb68b..6f36270 100644 --- a/archived/type_graph.hpp +++ b/archived/type_graph.hpp @@ -15,6 +15,7 @@ namespace info { +// TODO: fix dfs, etc. // TODO: optimize recalc class TypeGraph { @@ -69,6 +70,7 @@ public: size_t cluster_id = verticles_[id].cluster.value(); + typeclasses_[id].methods[method.first].definition = method.second.definition; std::vector typeclasses; typeclasses.reserve(cluster_requirements_[cluster_id].typeclasses.size()); @@ -174,20 +176,20 @@ private: std::vector> FindClusters() { std::vector> clusters; - auto sorted_verticles = TopSort(); + auto sorted_verticles = BackTopSort(); std::vector marks(sorted_verticles.size(), 0); for (size_t i = 0; i < sorted_verticles.size(); ++i) { if (marks[i] == 0) { clusters.emplace_back(); - VisitDfs(i, clusters[i], marks, back_edges_, clusters.size()); + BackVisitDfs(i, clusters[i], marks, back_edges_, clusters.size()); } } return clusters; } - void VisitDfs(size_t id, + void BackVisitDfs(size_t id, std::vector& verticles, std::vector& marks, const std::vector>& edges, @@ -197,19 +199,20 @@ private: } marks[id] = mark; - verticles.push_back(id); for (size_t i = 0; i < edges[id].size(); ++i) { - VisitDfs(id, verticles, marks, edges, mark); + BackVisitDfs(id, verticles, marks, edges, mark); } + + verticles.push_back(id); } - std::vector TopSort() { + std::vector BackTopSort() { std::vector sorted_verticles; std::vector marks(verticles_.size(), 0); for (size_t i = 0; i < marks.size(); ++i) { - VisitDfs(i, sorted_verticles, marks, edges_, 1); + BackVisitDfs(i, sorted_verticles, marks, edges_, 1); } return sorted_verticles; diff --git a/include/.type_check_visitor.hpp.kate-swp b/include/.type_check_visitor.hpp.kate-swp new file mode 100644 index 0000000..43b2e79 Binary files /dev/null and b/include/.type_check_visitor.hpp.kate-swp differ diff --git a/include/interpreter_tree.hpp b/include/interpreter_tree.hpp index bcf3539..86ae5f0 100644 --- a/include/interpreter_tree.hpp +++ b/include/interpreter_tree.hpp @@ -14,6 +14,8 @@ namespace interpreter::tokens { struct BaseNode { std::pair start_position; std::pair end_position; + + std::optional type_; }; // ----------------- Declarations ----------------- diff --git a/include/typeclass_graph.hpp b/include/typeclass_graph.hpp index 7136425..76cb131 100644 --- a/include/typeclass_graph.hpp +++ b/include/typeclass_graph.hpp @@ -1,9 +1,7 @@ #pragma once +#include #include -//////////////////////////////////////////////////////////////////////////////////////// -// Temporary frozen, TODO -//////////////////////////////////////////////////////////////////////////////////////// #pragma once @@ -12,41 +10,63 @@ // for calngd #include "utils.hpp" #include "interpreter_tree.hpp" -#include "error_handling.hpp" namespace info { class TypeclassGraph { public: - struct TypeclassMethod { - std::string name; - interpreter::tokens::FunctionDeclaration* definition = nullptr; + struct MethodInfo { + interpreter::tokens::FunctionDeclaration* declaration = nullptr; + std::optional definition; }; struct ParametrizedTypeclass { - utils::IdType typeclass; - std::vector parameter_ids; // ?? + std::string typeclass; + // TODO: parameters }; struct TypeclassVertex { - std::vector>> parameters; - std::vector methods; - std::vector dependencies; + std::string name; interpreter::tokens::TypeclassDefinitionStatement* definition = nullptr; + std::unordered_map methods; + std::vector dependencies; + + // TODO: std::vector>> parameters; }; - utils::IdType AddTypeclass(const TypeclassVertex& typeclass) { // TODO: universal reference - for (auto& method : typeclass.methods) { - if (method_to_typeclass_.count(method.name) != 0) { - error_handling::HandleTypecheckError(""); + std::optional AddTypeclass( + 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) { + if (method_to_typeclass_.count(method.first) != 0) { + return std::nullopt; } } - for (auto& method : typeclass.methods) { - method_to_typeclass_[method.name] = typeclasses_.size(); + + is_calculated_ = false; + + typeclasses_.emplace_back(); + TypeclassVertex& typeclass = typeclasses_.back(); + typeclass.name = name; + typeclass.definition = definition; + typeclass.dependencies = dependencies; + + for (auto& method : method_declarations) { + method_to_typeclass_[method.first] = typeclasses_.size(); + typeclass.methods[method.first].declaration = method.second; } - typeclasses_.push_back(typeclass); + name_to_typeclass_[name] = typeclasses_.size() - 1; + + for (auto& method : method_definitions) { + typeclass.methods[method.first].definition = method.second; + } + return typeclasses_.size() - 1; } + std::optional FindMethodTypeclass(const std::string& name) { auto method_iter = method_to_typeclass_.find(name); if (method_iter == method_to_typeclass_.end()) { @@ -55,12 +75,62 @@ public: return method_iter->second; } - const TypeclassVertex& GetTypeclass(utils::IdType id) { + const TypeclassVertex& GetTypeclass(utils::IdType id) { // check, if calculated ?? return typeclasses_.at(id); } + + bool IsCalculated() { + return is_calculated_; + } + + bool CalculateGraph() { + if (is_calculated_) { + return true; + } + + std::vector> edges(typeclasses_.size()); + + for (size_t i = 0; i < typeclasses_.size(); ++i) { + edges[i].resize(typeclasses_[i].dependencies.size()); + for (size_t j = 0; j < edges[i].size(); ++j) { + auto dependency_iter = name_to_typeclass_.find(typeclasses_[i].dependencies[j].typeclass); + + if (dependency_iter == name_to_typeclass_.end()) { + return false; + } + + edges[i][j] = dependency_iter->second; + } + } + + std::vector sorted_verticles = utils::BackTopSort(edges); + std::reverse(sorted_verticles.begin(), sorted_verticles.end()); + + for (auto& id : sorted_verticles) { + for (auto& dependency : typeclasses_[id].dependencies) { + for (auto& method : typeclasses_[name_to_typeclass_[dependency.typeclass]].methods) { + auto method_iter = typeclasses_[id].methods.find(method.first); + if (method_iter == typeclasses_[id].methods.end()) { + typeclasses_[id].methods[method.first] = method.second; + } else { + if (!method_iter->second.definition.has_value()) { + method_iter->second.definition = method.second.definition; + } + } + } + } + } + + is_calculated_ = true; + + return true; + } private: std::unordered_map method_to_typeclass_; + std::unordered_map name_to_typeclass_; std::vector typeclasses_; + + bool is_calculated_ = true; }; } // namespace info diff --git a/include/typed_print_visitor.hpp b/include/typed_print_visitor.hpp new file mode 100644 index 0000000..d542714 --- /dev/null +++ b/include/typed_print_visitor.hpp @@ -0,0 +1,128 @@ +#pragma once + +#include + +// for clangd +#include "type_info_contexts.hpp" +#include "visitor.hpp" + +namespace interpreter { + +class TypedPrintVisitor : public Visitor { +public: + explicit TypedPrintVisitor(std::ostream& out, + info::TypeInfoContextManager& context_manager) + : out_(out), context_manager_(context_manager) {} + +private: + // Sources ----------------- + + void Visit(SourceFile* node) override; + + // Namespaces, partitions ----------------- + + 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; + + // Definition parts + + void Visit(FunctionDefinition* node) override; + void Visit(TypeDefinition* node) override; + void Visit(AnyAnnotatedType* node) override; + + // Flow control ----------------- + + void Visit(TypeConstructorPatternParameter* node) override; + void Visit(TypeConstructorPattern* node) override; + void Visit(MatchCase* node) override; + void Visit(Match* node) override; + void Visit(Condition* node) override; + void Visit(DoWhileLoop* node) override; + void Visit(WhileLoop* node) override; + void Visit(ForLoop* node) override; + void Visit(LoopLoop* node) override; + + // Statements, expressions, blocks, etc. ----------------- + + void Visit(Block* node) override; + + void Visit(ScopedStatement* node) override; + + // Operators + + void Visit(BinaryOperatorExpression* node) override; + void Visit(UnaryOperatorExpression* node) override; + void Visit(ReferenceExpression* node) override; + void Visit(AccessExpression* node) override; + + // Simple Expressions + + void Visit(FunctionCallExpression* node) override; + + void Visit(TupleExpression* node) override; + void Visit(VariantExpression* node) override; + void Visit(ReturnExpression* node) override; + void Visit(TypeConstructorParameter* node) override; + void Visit(TypeConstructor* node) override; + void Visit(LambdaFunction* node) override; + void Visit(ArrayExpression* node) override; + + void Visit(LoopControlExpression& node) override; // enum + + // Name + + void Visit(NameExpression* node) override; + void Visit(TupleName* node) override; + void Visit(VariantName* node) override; + void Visit(AnnotatedName* node) override; + + // Type, typeclass, etc. ----------------- + + // Type + + void Visit(FunctionType* node) override; + void Visit(TupleType* node) override; + void Visit(VariantType* node) override; + void Visit(TypeExpression* node) override; + + void Visit(ExtendedScopedAnyType* node) override; + + // Typeclass + + void Visit(ParametrizedTypeclass* node) override; + + // Typeclass & Type + + void Visit(ParametrizedType* node) override; + + // Identifiers, constants, etc. ----------------- + + void Visit(ExtendedName* node) override; + + void Visit(std::string* node) override; // std::string + + void Visit(FloatNumberLiteral* node) override; + void Visit(NumberLiteral* node) override; + void Visit(StringLiteral* node) override; + void Visit(CharLiteral* node) override; + void Visit(UnitLiteral* node) override; + +private: + std::ostream& out_; + info::TypeInfoContextManager& context_manager_; +}; + +} // namespace interpreter diff --git a/include/types.hpp b/include/types.hpp index 08cfb83..bdceb7f 100644 --- a/include/types.hpp +++ b/include/types.hpp @@ -234,6 +234,8 @@ public: std::optional GetFieldType(const std::string& name) const; + std::string GetTypeName() const; + private: std::variant 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; +} + } // namespace utils diff --git a/lang-parser b/lang-parser index d7c58c4..60a270e 160000 --- a/lang-parser +++ b/lang-parser @@ -1 +1 @@ -Subproject commit d7c58c48cc7afc031e5dc350eb2a497c1bac5511 +Subproject commit 60a270ed79f866baae441b823f241cbc032999da diff --git a/src/.type_check_visitor.cpp.kate-swp b/src/.type_check_visitor.cpp.kate-swp deleted file mode 100644 index 61da736..0000000 Binary files a/src/.type_check_visitor.cpp.kate-swp and /dev/null differ diff --git a/src/link_symbols_visitor.cpp b/src/link_symbols_visitor.cpp index c5c7986..cc95335 100644 --- a/src/link_symbols_visitor.cpp +++ b/src/link_symbols_visitor.cpp @@ -50,9 +50,9 @@ void LinkSymbolsVisitor::Visit(TypeExpression* node) { // TODO: check node->type_id_ = namespace_visitor_.FindType(path, node->type.type); node->constructor_id_ = namespace_visitor_.FindConstructor(path, node->type.type); - if (!node->type_id_.has_value() && !node->constructor_id_.has_value()) { - error_handling::HandleTypecheckError("Type or constructor not found", node->base); - } + // if (!node->type_id_.has_value() && !node->constructor_id_.has_value()) { // TODO: check, that not bastract types + // error_handling::HandleTypecheckError("Type or constructor not found", node->base); + // } if (node->constructor_id_.has_value()) { utils::IdType constructor_type_id = namespace_visitor_.GetGlobalInfo()->GetConstructorInfo(node->constructor_id_.value()).type_id; diff --git a/src/main.cpp b/src/main.cpp index 885ace7..4198c67 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,9 +4,15 @@ // for clangd #include "../include/parse_tree.hpp" +#include "../include/global_info.hpp" +#include "../include/type_info_contexts.hpp" #include "../include/interpreter_tree.hpp" #include "../include/build_visitor.hpp" #include "../include/print_visitor.hpp" +#include "../include/find_symbols_visitor.hpp" +#include "../include/link_symbols_visitor.hpp" +#include "../include/type_check_visitor.hpp" +#include "../include/typed_print_visitor.hpp" #include "../include/error_handling.hpp" int main(int argc, char** argv) { // TODO, only test version @@ -37,9 +43,19 @@ int main(int argc, char** argv) { // TODO, only test version std::unique_ptr source_file = std::make_unique(); + info::GlobalInfo global_info; + info::TypeInfoContextManager context_manager; + interpreter::BuildVisitor build_visitor(parse_tree); - interpreter::PrintVisitor print_visitor(std::cout); + // interpreter::PrintVisitor print_visitor(std::cout); + interpreter::FindSymbolsVisitor find_symbols_visitor(global_info); + interpreter::LinkSymbolsVisitor link_symbols_visitor(global_info); + interpreter::TypeCheckVisitor type_check_visitor(global_info, context_manager); + interpreter::TypedPrintVisitor typed_print_visitor(std::cout, context_manager); build_visitor.VisitSourceFile(source_file.get()); - print_visitor.VisitSourceFile(source_file.get()); + find_symbols_visitor.VisitSourceFile(source_file.get()); + link_symbols_visitor.VisitSourceFile(source_file.get()); + type_check_visitor.VisitSourceFile(source_file.get()); + typed_print_visitor.VisitSourceFile(source_file.get()); } diff --git a/src/type_check_visitor.cpp b/src/type_check_visitor.cpp index bf16d53..77bf865 100644 --- a/src/type_check_visitor.cpp +++ b/src/type_check_visitor.cpp @@ -19,6 +19,8 @@ void TypeCheckVisitor::Visit(SourceFile* node) { Visitor::Visit(statement); } current_type_ = context_manager_.AddType(info::type::InternalType::Unit, utils::ValueType::Tmp); + + node->base.type_ = current_type_; } // Namespaces, partitions ----------------- @@ -28,11 +30,15 @@ void TypeCheckVisitor::Visit(PartitionSources* node) { Visitor::Visit(statement); } current_type_ = context_manager_.AddType(info::type::InternalType::Unit, utils::ValueType::Tmp); + + node->base.type_ = current_type_; } void TypeCheckVisitor::Visit(Partition* node) { Visit(&node->scope); current_type_ = context_manager_.AddType(info::type::InternalType::Unit, utils::ValueType::Tmp); + + node->base.type_ = current_type_; } void TypeCheckVisitor::Visit(NamespaceSources* node) { @@ -40,6 +46,8 @@ void TypeCheckVisitor::Visit(NamespaceSources* node) { Visitor::Visit(statement); } current_type_ = context_manager_.AddType(info::type::InternalType::Unit, utils::ValueType::Tmp); + + node->base.type_ = current_type_; } void TypeCheckVisitor::Visit(Namespace* node) { // TODO: two var namespces for class: const and var @@ -78,6 +86,8 @@ void TypeCheckVisitor::Visit(Namespace* node) { // TODO: two var namespces for c namespace_visitor_.ExitNamespace(); context_manager_.ExitContext(); current_type_ = context_manager_.AddType(info::type::InternalType::Unit, utils::ValueType::Tmp); + + node->base.type_ = current_type_; } // Definitions ----------------- @@ -107,6 +117,8 @@ void TypeCheckVisitor::Visit(AliasDefinitionStatement* node) { // Visit(node->value.get()); // // context_manager_.ExitContext(); + // + // node->base.type_ = current_type_; } void TypeCheckVisitor::Visit(VariableDefinitionStatement* node) { @@ -127,6 +139,8 @@ void TypeCheckVisitor::Visit(VariableDefinitionStatement* node) { current_type_ = context_manager_.AddType(info::type::InternalType::Unit, utils::ValueType::Tmp); is_in_statement_ = false; + + node->base.type_ = current_type_; } void TypeCheckVisitor::Visit(FunctionDeclaration* node) { @@ -138,6 +152,8 @@ void TypeCheckVisitor::Visit(FunctionDeclaration* node) { if (!was_in_statement) { is_in_statement_ = false; } + + node->base.type_ = current_type_; } void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) { @@ -190,6 +206,8 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) { current_type_ = context_manager_.AddType(info::type::InternalType::Unit, utils::ValueType::Tmp); is_in_statement_ = false; + + node->base.type_ = current_type_; } void TypeCheckVisitor::Visit(TypeDefinitionStatement* node) { @@ -198,6 +216,8 @@ void TypeCheckVisitor::Visit(TypeDefinitionStatement* node) { current_type_ = context_manager_.AddType(info::type::InternalType::Unit, utils::ValueType::Tmp); is_in_statement_ = false; + + node->base.type_ = current_type_; } void TypeCheckVisitor::Visit(AbstractTypeDefinitionStatement* node) { @@ -219,6 +239,8 @@ void TypeCheckVisitor::Visit(AbstractTypeDefinitionStatement* node) { current_type_ = context_manager_.AddType(info::type::InternalType::Unit, utils::ValueType::Tmp); is_in_statement_ = false; + + node->base.type_ = current_type_; } void TypeCheckVisitor::Visit(TypeclassDefinitionStatement* node) { @@ -227,20 +249,28 @@ void TypeCheckVisitor::Visit(TypeclassDefinitionStatement* node) { current_type_ = context_manager_.AddType(info::type::InternalType::Unit, utils::ValueType::Tmp); is_in_statement_ = false; + + node->base.type_ = current_type_; } // Definition parts void TypeCheckVisitor::Visit(FunctionDefinition* node) { current_type_ = context_manager_.AddType(info::type::InternalType::Unit, utils::ValueType::Tmp); + + node->base.type_ = current_type_; } void TypeCheckVisitor::Visit(TypeDefinition* node) { current_type_ = context_manager_.AddType(info::type::InternalType::Unit, utils::ValueType::Tmp); + + node->base.type_ = current_type_; } void TypeCheckVisitor::Visit(AnyAnnotatedType* node) { current_type_ = context_manager_.AddType(info::type::InternalType::Unit, utils::ValueType::Tmp); + + node->base.type_ = current_type_; } // Flow control ----------------- @@ -313,6 +343,8 @@ void TypeCheckVisitor::Visit(TypeConstructorPattern* node) { // TODO: match name Visitor::Visit(*type_info.value); current_type_ = TypeInContext(current_type_, context); current_type_ = context_manager_.ToModifiedType(current_type_, utils::ValueType::Tmp); + + node->base.type_ = current_type_; } void TypeCheckVisitor::Visit(MatchCase* node) { @@ -339,6 +371,8 @@ void TypeCheckVisitor::Visit(MatchCase* node) { Visitor::Visit(node->statement.value()); } // current_type_ from statement is current_type_ for MatchCase + + node->base.type_ = current_type_; } void TypeCheckVisitor::Visit(Match* node) { // TODO: move value to match @@ -376,6 +410,8 @@ void TypeCheckVisitor::Visit(Match* node) { // TODO: move value to match } current_type_ = type; + + node->base.type_ = current_type_; } void TypeCheckVisitor::Visit(Condition* node) { @@ -413,6 +449,8 @@ void TypeCheckVisitor::Visit(Condition* node) { info::type::OptionalType(type, context_manager_.GetTypeManager()), utils::ValueType::Tmp); // ?? } + + node->base.type_ = current_type_; } void TypeCheckVisitor::Visit(DoWhileLoop* node) { @@ -443,6 +481,8 @@ void TypeCheckVisitor::Visit(WhileLoop* node) { current_type_ = context_manager_.AddType( info::type::ArrayType(0, current_type_, context_manager_.GetTypeManager()), utils::ValueType::Tmp); + + node->base.type_ = current_type_; } void TypeCheckVisitor::Visit(ForLoop* node) { @@ -479,6 +519,8 @@ void TypeCheckVisitor::Visit(LoopLoop* node) { current_type_ = context_manager_.AddType( info::type::ArrayType(0, current_type_, context_manager_.GetTypeManager()), utils::ValueType::Tmp); + + node->base.type_ = current_type_; } // Statements, expressions, blocks, etc. ----------------- @@ -511,11 +553,15 @@ void TypeCheckVisitor::Visit(Block* node) { } current_type_ = type; + + node->base.type_ = current_type_; } void TypeCheckVisitor::Visit(ScopedStatement* node) { Visitor::Visit(node->statement); // current_type_ is type of statement + + node->base.type_ = current_type_; } void TypeCheckVisitor::Visit(LoopControlExpression& node) { // enum @@ -524,7 +570,7 @@ void TypeCheckVisitor::Visit(LoopControlExpression& node) { // enum // Operators -// TODO +// 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); @@ -632,8 +678,11 @@ void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) { } Visitor::Visit(*operator_info.declaration.value().argument_types.back()); + + node->base.type_ = current_type_; } +// TODO: can be method ?? void TypeCheckVisitor::Visit(UnaryOperatorExpression* node) { // TODO: Check, that type is not abstract ?? auto maybe_operator_id = namespace_visitor_.FindFunction({}, node->operator_name); @@ -652,7 +701,7 @@ void TypeCheckVisitor::Visit(UnaryOperatorExpression* node) { error_handling::HandleTypecheckError("Operator definition not found", node->base); } - if (operator_info.argument_count != 1) { + if (operator_info.argument_count != 2) { // 1 + return type error_handling::HandleTypecheckError("Operator wrong argument count", node->base); } @@ -667,6 +716,10 @@ void TypeCheckVisitor::Visit(UnaryOperatorExpression* node) { if (!context_manager_.AddTypeRequirement(current_type_, expression_type)) { error_handling::HandleTypecheckError("Operator expression has wrong type", node->base); } + + Visitor::Visit(*operator_info.declaration.value().argument_types.back()); + + node->base.type_ = current_type_; } void TypeCheckVisitor::Visit(ReferenceExpression* node) { @@ -693,6 +746,8 @@ void TypeCheckVisitor::Visit(AccessExpression* node) { } current_type_ = maybe_type_value.value()->GetElementsType(); + + node->base.type_ = current_type_; } // Other Expressions @@ -701,6 +756,7 @@ void TypeCheckVisitor::Visit(AccessExpression* node) { // TODO: builtin functions/methods // TODO: alias types, abstract types, etc. // TODO: deduce function parameter types +// TODO: find functions in typeclasses void TypeCheckVisitor::Visit(FunctionCallExpression* node) { std::optional maybe_function_id; std::unordered_map context; @@ -830,6 +886,8 @@ void TypeCheckVisitor::Visit(TupleExpression* node) { current_type_ = context_manager_.AddType( info::type::TupleType(std::nullopt, fields, context_manager_.GetTypeManager()), utils::ValueType::Tmp); + + node->base.type_ = current_type_; } // ?? @@ -847,11 +905,15 @@ void TypeCheckVisitor::Visit(VariantExpression* node) { current_type_ = context_manager_.AddType(info::type::VariantType(std::nullopt, constructors, -1), utils::ValueType::Tmp); + + node->base.type_ = current_type_; } void TypeCheckVisitor::Visit(ReturnExpression* node) { Visitor::Visit(node->expression); returned_type_ = current_type_; + + node->base.type_ = current_type_; } void TypeCheckVisitor::Visit(TypeConstructorParameter* node) {} // Handeled in TypeConstructor visit @@ -931,11 +993,15 @@ void TypeCheckVisitor::Visit(TypeConstructor* node) { } current_type_ = TypeInContext(current_type_, context); + + node->base.type_ = current_type_; } void TypeCheckVisitor::Visit(LambdaFunction* node) { // TODO error_handling::HandleInternalError("Unimplemented (unsolved type deduction problems)", "TypeCheckVisitor.LambdaFunction"); + + node->base.type_ = current_type_; } void TypeCheckVisitor::Visit(ArrayExpression* node) { @@ -959,6 +1025,8 @@ void TypeCheckVisitor::Visit(ArrayExpression* node) { current_type_ = context_manager_.AddType( info::type::ArrayType(node->elements.size(), elements_type, context_manager_.GetTypeManager()), utils::ValueType::Tmp); + + node->base.type_ = current_type_; } // Name @@ -993,6 +1061,8 @@ void TypeCheckVisitor::Visit(NameExpression* node) { } current_type_ = context_manager_.ToModifiedType(current_type_, variable_value_type); + + node->base.type_ = current_type_; } void TypeCheckVisitor::Visit(TupleName* node) { @@ -1034,6 +1104,8 @@ void TypeCheckVisitor::Visit(TupleName* node) { } current_type_ = type; + + node->base.type_ = current_type_; } void TypeCheckVisitor::Visit(VariantName* node) { @@ -1084,6 +1156,8 @@ void TypeCheckVisitor::Visit(VariantName* node) { } current_type_ = type; + + node->base.type_ = current_type_; } void TypeCheckVisitor::Visit(AnnotatedName* node) { @@ -1109,6 +1183,8 @@ void TypeCheckVisitor::Visit(AnnotatedName* node) { error_handling::HandleTypecheckError("Wrong type annotation in annotated name", node->base); } } + + node->base.type_ = current_type_; } // Type, typeclass, etc. ----------------- @@ -1129,6 +1205,8 @@ void TypeCheckVisitor::Visit(FunctionType* node) { current_type_ = context_manager_.AddType( info::type::FunctionType(argument_types, return_type, context_manager_.GetTypeManager()), utils::ValueType::Tmp); + + node->base.type_ = current_type_; } void TypeCheckVisitor::Visit(TupleType* node) { @@ -1143,6 +1221,8 @@ void TypeCheckVisitor::Visit(TupleType* node) { current_type_ = context_manager_.AddType( info::type::TupleType(node->type, fields, context_manager_.GetTypeManager()), utils::ValueType::Tmp); + + node->base.type_ = current_type_; } void TypeCheckVisitor::Visit(VariantType* node) { @@ -1167,6 +1247,8 @@ void TypeCheckVisitor::Visit(VariantType* node) { current_type_ = context_manager_.AddType(info::type::VariantType(node->type, constructors, -1), utils::ValueType::Tmp); + + node->base.type_ = current_type_; } // TODO handle local abstract types, abstract types, aliases, etc. @@ -1194,6 +1276,8 @@ void TypeCheckVisitor::Visit(TypeExpression* node) { info::type::ArrayType(node->array_size.value(), current_type_, context_manager_.GetTypeManager()), utils::ValueType::Tmp); } + + node->base.type_ = current_type_; } void TypeCheckVisitor::Visit(ExtendedScopedAnyType* node) { @@ -1202,6 +1286,8 @@ void TypeCheckVisitor::Visit(ExtendedScopedAnyType* node) { current_type_ = context_manager_.AddType( info::type::ReferenceToType(node->references, current_type_, context_manager_.GetTypeManager()), utils::ValueType::Tmp); + + node->base.type_ = current_type_; } // Typeclass @@ -1210,6 +1296,8 @@ void TypeCheckVisitor::Visit(ParametrizedTypeclass* node) { // TODO ?? for (auto& parameter : node->parameters) { Visit(parameter.get()); } + + node->base.type_ = current_type_; } // Typeclass & Type ----------------- @@ -1220,18 +1308,26 @@ void TypeCheckVisitor::Visit(ParametrizedType* node) {} // Handled in TypeExpres void TypeCheckVisitor::Visit(FloatNumberLiteral* node) { current_type_ = context_manager_.AddType(info::type::InternalType::Float, utils::ValueType::Tmp); + + node->base.type_ = current_type_; } void TypeCheckVisitor::Visit(NumberLiteral* node) { current_type_ = context_manager_.AddType(info::type::InternalType::Int, utils::ValueType::Tmp); + + node->base.type_ = current_type_; } void TypeCheckVisitor::Visit(StringLiteral* node) { current_type_ = context_manager_.AddType(info::type::InternalType::String, utils::ValueType::Tmp); + + node->base.type_ = current_type_; } void TypeCheckVisitor::Visit(CharLiteral* node) { current_type_ = context_manager_.AddType(info::type::InternalType::Char, utils::ValueType::Tmp); + + node->base.type_ = current_type_; } // diff --git a/src/typed_print_visitor.cpp b/src/typed_print_visitor.cpp new file mode 100644 index 0000000..ee8e872 --- /dev/null +++ b/src/typed_print_visitor.cpp @@ -0,0 +1,1061 @@ +// for clangd +#include "../include/typed_print_visitor.hpp" + +namespace interpreter { + +// Sources ----------------- + +void TypedPrintVisitor::Visit(SourceFile* node) { + out_ << "[SourceFile : "; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << "] (\n\n"; + for (auto& statement : node->statements) { + Visitor::Visit(statement); + } + out_ << "\n)\n"; +} + +// Namespaces, partitions ----------------- + +void TypedPrintVisitor::Visit(PartitionSources* node) { + out_ << "[PartitionSources : "; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << "](\n"; + for (auto& statement : node->statements) { + Visitor::Visit(statement); + } + out_ << ")\n"; +} + +void TypedPrintVisitor::Visit(Partition* node) { + out_ << "[Partition : "; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << "] "; + switch (node->name) { + case Partition::Test: + out_ << "TEST"; + break; + case Partition::Interface: + out_ << "INTERFACE"; + break; + case Partition::Code: + out_ << "CODE"; + break; + } + out_ << " {\n"; + Visit(&node->scope); + out_ << "}\n"; +} + +void TypedPrintVisitor::Visit(NamespaceSources* node) { + out_ << "[NamespaceSources : "; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << "](\n"; + for (auto& statement : node->statements) { + Visitor::Visit(statement); + } + out_ << ")\n"; +} + +void TypedPrintVisitor::Visit(Namespace* node) { + out_ << "[Namespace : "; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << "] "; + if (node->modifier.has_value()) { + switch (node->modifier.value()) { + case utils::IsConstModifier::Const: + out_ << "const "; + break; + case utils::IsConstModifier::Var: + out_ << "var "; + break; + } + } + Visit(&node->type); + out_ << "{\n"; + Visit(&node->scope); + out_ << "}\n"; +} + +// Definitions ----------------- + +void TypedPrintVisitor::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 TypedPrintVisitor::Visit(AliasDefinitionStatement* node) { + out_ << "[Alias : ("; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << ") "; + switch (node->modifier) { + case utils::AliasModifier::Alias: + out_ << "alias"; + break; + case utils::AliasModifier::Type: + out_ << "type"; + break; + case utils::AliasModifier::Let: + out_ << "let"; + break; + } + out_ << ' '; + Visit(&node->type); + out_ << "] = ("; + Visit(node->value.get()); + out_ << ")\n"; +} + +void TypedPrintVisitor::Visit(VariableDefinitionStatement* node) { + out_ << "[Variable : ("; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << ") "; + switch (node->modifier) { + case utils::IsConstModifier::Const: + out_ << "const"; + break; + case utils::IsConstModifier::Var: + out_ << "var"; + break; + } + out_ << ' '; + Visitor::Visit(node->name); + out_ << "] = ("; + Visitor::Visit(node->value); + out_ << ")\n"; +} + +void TypedPrintVisitor::Visit(FunctionDeclaration* node) { + out_ << "[FunctionDeclaration : ("; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << ") "; + Visit(&node->name); + out_ << "] ("; + for (auto& parameter : node->parameters) { + Visit(parameter.get()); + } + out_ << ") : ("; + Visit(node->type.get()); + out_ << ")\n"; +} + +void TypedPrintVisitor::Visit(FunctionDefinitionStatement* node) { + out_ << "[Function : "; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << "] ("; + Visit(node->definition.get()); + out_ << ") = ("; + Visitor::Visit(node->value); + out_ << ")\n"; +} + +void TypedPrintVisitor::Visit(TypeDefinitionStatement* node) { + out_ << "[Type : ("; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << ") "; + switch (node->modifier) { + case utils::ClassModifier::Struct: + out_ << "struct"; + break; + case utils::ClassModifier::Class: + out_ << "class"; + break; + } + out_ << "] ("; + Visit(node->definition.get()); + out_ << ") = ("; + Visitor::Visit(node->value); + out_ << ")\n"; +} + +void TypedPrintVisitor::Visit(AbstractTypeDefinitionStatement* node) { + out_ << "[AbstractType : ("; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << ") "; + switch (node->modifier) { + case utils::AbstractTypeModifier::Basic: + out_ << "basic"; + break; + case utils::AbstractTypeModifier::Abstract: + out_ << "abstract"; + break; + } + out_ << "] ("; + Visit(node->type.get()); + out_ << ")\n"; +} + +void TypedPrintVisitor::Visit(TypeclassDefinitionStatement* node) { + out_ << "[Typeclass : "; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << "] ("; + 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 TypedPrintVisitor::Visit(FunctionDefinition* node) { + out_ << "[FunctionDefinition : ("; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << ") "; + switch (node->modifier) { + case utils::FunctionTypeModifier::Operator: + out_ << "operator"; + break; + case utils::FunctionTypeModifier::Function: + out_ << "function"; + break; + } + out_ << ' '; + Visit(&node->name); + out_ << "]"; + if (!node->arguments.empty()) { + out_ << " : ("; + for (auto& argument : node->arguments) { + Visit(&argument); + } + out_ << ')'; + } + out_ << ' '; +} + +void TypedPrintVisitor::Visit(TypeDefinition* node) { + out_ << "[TypeDefinition : "; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << "] ("; + Visit(node->type.get()); + out_ << ')'; + if (!node->parameters.empty()) { + out_ << '('; + for (auto& parameter : node->parameters) { + Visit(parameter.get()); + } + out_ << ')'; + } + out_ << ' '; +} + +void TypedPrintVisitor::Visit(AnyAnnotatedType* node) { + out_ << "[Annotated (Abstract) Type : ("; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << ") "; + Visit(&node->type); + out_ << ']'; + if (!node->typeclasses.empty()) { + out_ << " ("; + for (auto& typeclass : node->typeclasses) { + Visit(typeclass.get()); + } + out_ << ')'; + } + out_ << ' '; +} + +// Flow control ----------------- + +void TypedPrintVisitor::Visit(TypeConstructorPatternParameter* node) { + out_ << "[TypeConstructorPatternParameter : ("; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << ") "; + if (node->name.has_value()) { + Visit(&node->name.value()); + out_ << " = "; + } + Visitor::Visit(node->value); + out_ << "]"; +} + +void TypedPrintVisitor::Visit(TypeConstructorPattern* node) { + out_ << "[TypeConstructorPattern : ("; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << ") "; + Visit(node->constructor.get()); + out_ << "]\n("; + + bool is_first = true; + for (auto& parameter : node->parameters) { + if (!is_first) { + out_ << ")\n"; + } + is_first = false; + out_ << '('; + Visit(¶meter); + } + out_ << ")\n"; +} + +void TypedPrintVisitor::Visit(MatchCase* node) { + out_ << "[MatchCase | : ("; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << ") "; + 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 TypedPrintVisitor::Visit(Match* node) { + out_ << "[Match : "; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << "] ("; + Visitor::Visit(node->value); + out_ << ") [with] (\n"; + for (auto& match_case : node->matches) { + Visit(&match_case); + } + out_ << ")\n"; +} + +void TypedPrintVisitor::Visit(Condition* node) { + out_ << "[If : "; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << "] ("; + 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 TypedPrintVisitor::Visit(DoWhileLoop* node) { + out_ << "[Do : "; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << "] (\n"; + Visitor::Visit(node->statement); + out_ << ") [while] ("; + Visitor::Visit(node->condition); + out_ << ")\n"; +} + +void TypedPrintVisitor::Visit(WhileLoop* node) { + out_ << "[While : "; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << "] ("; + Visitor::Visit(node->condition); + out_ << ") [do] (\n"; + Visitor::Visit(node->statement); + out_ << ")\n"; +} +void TypedPrintVisitor::Visit(ForLoop* node) { + out_ << "[For : "; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << ") "; + switch (node->variable_modifier) { + case utils::IsConstModifier::Const: + break; + case utils::IsConstModifier::Var: + out_ << "var"; + break; + } + out_ << "] ("; + Visitor::Visit(node->variable); + out_ << ") [in] ("; + Visitor::Visit(node->interval); + out_ << ") [do] (\n"; + Visitor::Visit(node->statement); + out_ << ")\n"; +} + +void TypedPrintVisitor::Visit(LoopLoop* node) { + out_ << "[Loop : "; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << "] (\n"; + Visitor::Visit(node->statement); + out_ << ")\n"; +} + +// Statements, expressions, blocks, etc. ----------------- + +void TypedPrintVisitor::Visit(Block* node) { + out_ << "[Block : "; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << "] {\n"; + for (auto& statement : node->statements) { + Visitor::Visit(statement); + } + out_ << "}\n"; +} + +void TypedPrintVisitor::Visit(ScopedStatement* node) { + out_ << "[Scoped : "; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << "] ( "; + Visitor::Visit(node->statement); + out_ << ")\n"; +} + +void TypedPrintVisitor::Visit(LoopControlExpression& node) { // enum + switch (node) { + case LoopControlExpression::Break: + out_ << "[Break]\n"; + break; + case LoopControlExpression::Continue: + out_ << "[Continue]\n"; + break; + } +} + +// Operators + +void TypedPrintVisitor::Visit(BinaryOperatorExpression* node) { + out_ << "[BinaryOperator : "; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << "] ("; + Visitor::Visit(node->left_expression); + out_ << ") ["; + Visit(&node->operator_name); + out_ << "] ("; + Visitor::Visit(node->right_expression); + out_ << ')'; +} + +void TypedPrintVisitor::Visit(UnaryOperatorExpression* node) { + out_ << "[UnaryOperator : ("; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << ") "; + Visit(&node->operator_name); + out_ << "] ("; + Visitor::Visit(node->expression); + out_ << ')'; +} + +void TypedPrintVisitor::Visit(ReferenceExpression* node) { + out_ << "[ReferenceExpression : ("; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << ") "; + for (auto& reference : node->references) { + switch (reference) { + case utils::ReferenceModifier::Reference: + out_ << '~'; + break; + case utils::ReferenceModifier::UniqueReference: + out_ << '@'; + break; + } + } + out_ << "] ("; + Visit(node->expression.get()); + out_ << ')'; +} + +void TypedPrintVisitor::Visit(AccessExpression* node) { + out_ << "[AccessExpression : "; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << "] ("; + Visit(node->name.get()); + out_ << ") ` ("; + Visitor::Visit(node->id); + out_ << ')'; +} + +// Other Expressions + +void TypedPrintVisitor::Visit(FunctionCallExpression* node) { + out_ << "[FunctionCall : ("; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << ") "; + if (node->prefix.has_value()) { + out_ << '('; + if (std::holds_alternative>(node->prefix.value())) { + Visitor::Visit(*std::get>(node->prefix.value())); + } else if (std::holds_alternative>(node->prefix.value())) { + Visit(std::get>(node->prefix.value()).get()); + } else { + // error + } + out_ << ")."; + } + + Visit(&node->name); + + out_ << "] ("; + + bool is_first = true; + for (auto& parameter : node->parameters) { + if (!is_first) { + out_ << ", "; + } + is_first = false; + + Visit(parameter.get()); + } + + out_ << ") : ("; + + is_first = true; + for (auto& argument : node->arguments) { + if (!is_first) { + out_ << ", "; + } + is_first = false; + + Visitor::Visit(argument); + } + out_ << ")"; +} + +void TypedPrintVisitor::Visit(TupleExpression* node) { + out_ << "[TupleExpression : "; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << "] ("; + for (auto& expression : node->expressions) { + out_ << "&"; + Visitor::Visit(expression); + } + out_ << ")"; +} + +void TypedPrintVisitor::Visit(VariantExpression* node) { + out_ << "[VariantExpression : "; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << "] ("; + for (auto& expression : node->expressions) { + out_ << "|"; + Visitor::Visit(expression); + } + out_ << ")"; +} + +void TypedPrintVisitor::Visit(ReturnExpression* node) { + out_ << "[Return : "; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << "] ("; + Visitor::Visit(node->expression); + out_ << ")\n"; +} + +void TypedPrintVisitor::Visit(TypeConstructorParameter* node) { + out_ << "[TypeConstructorParameter : ("; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << ") "; + if (node->name.has_value()) { + Visit(&node->name.value()); + switch (node->asignment_modifier.value()) { + case utils::AssignmentModifier::Assign: + out_ << " = "; + break; + case utils::AssignmentModifier::Move: + out_ << " <- "; + break; + } + } + Visitor::Visit(node->value); + out_ << "]"; +} + +void TypedPrintVisitor::Visit(TypeConstructor* node) { + out_ << "[TypeConstructor : ("; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << ") "; + Visit(node->constructor.get()); + out_ << "]\n("; + + bool is_first = true; + for (auto& parameter : node->parameters) { + if (!is_first) { + out_ << ")\n"; + } + is_first = false; + out_ << '('; + Visit(¶meter); + } + out_ << ")\n"; +} + +void TypedPrintVisitor::Visit(LambdaFunction* node) { + out_ << "[LambdaFunction : "; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << "] ("; + for (auto& parameter : node->parameters) { + Visit(parameter.get()); + } + if (!node->parameters.empty()) { + out_ << ") : ("; + } + for (auto& argument : node->arguments) { + Visit(&argument); + } + out_ << ") -> (\n"; + Visitor::Visit(node->expression); + out_ << ")\n"; +} + +void TypedPrintVisitor::Visit(ArrayExpression* node) { + out_ << "[ArrayExpression : "; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << "] ( ,"; + for (auto& element : node->elements) { + Visitor::Visit(element); + out_ << " ,"; + } + out_ << ")"; +} + +// Name + +void TypedPrintVisitor::Visit(NameExpression* node) { + out_ << "[NameExpression : "; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << "] ("; + for (size_t i = 0; i < node->names.size(); ++i) { + Visit(&node->names[i]); + if (i + 1 < node->names.size()) { + out_ << "::"; + } + } + out_ << ')'; +} + +void TypedPrintVisitor::Visit(TupleName* node) { + out_ << "[TupleName : "; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << "] ("; + for (auto& name : node->names) { + out_ << "& "; + Visitor::Visit(name); + } + out_ << ')'; +} + +void TypedPrintVisitor::Visit(VariantName* node) { + out_ << "[VariantName : "; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << "] ("; + for (auto& name : node->names) { + out_ << "| "; + Visitor::Visit(name); + } + out_ << ')'; +} + +void TypedPrintVisitor::Visit(AnnotatedName* node) { + out_ << "[AnnotatedName : ("; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << ") "; + Visit(&node->name); + out_ << ']'; + if (node->type.has_value()) { + out_ << " : ("; + Visitor::Visit(node->type.value()); + out_ << ')'; + } +} + +// Type, typeclass, etc. ----------------- + +// Type + +void TypedPrintVisitor::Visit(FunctionType* node) { + out_ << "[FunctionType : "; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << "] ("; + bool is_first = true; + for (auto& type : node->types) { + if (!is_first) { + out_ << " -> "; + } + is_first = false; + Visitor::Visit(type); + } + out_ << ')'; +} + +void TypedPrintVisitor::Visit(TupleType* node) { + out_ << "[TupleType : ("; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << ") "; + if (node->type.has_value()) { + Visit(&node->type.value()); + } + out_ << "] ("; + for (auto& entity : node->entities) { + out_ << "& "; + if (entity.first.has_value()) { + Visit(&entity.first.value()); + out_ << " : "; + } + Visit(entity.second.get()); + } + out_ << ')'; +} + +void TypedPrintVisitor::Visit(VariantType* node) { + out_ << "[VariantType : ("; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << ") "; + if (node->type.has_value()) { + Visit(&node->type.value()); + } + out_ << "] ("; + for (auto& constructor : node->constructors) { + out_ << "| "; + if (std::holds_alternative(constructor)) { + Visit(&std::get(constructor)); + } else if (std::holds_alternative>(constructor)) { + Visit(std::get>(constructor).get()); + } else { + // error + } + } + out_ << ')'; +} + +void TypedPrintVisitor::Visit(TypeExpression* node) { + out_ << "[TypeExpression : ("; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << ") "; + if (node->array_size.has_value()) { + out_ << "[array size: " << node->array_size.value() << ']'; + } + + out_ << "] ("; + for (auto& type : node->path) { + Visit(&type); + out_ << "::"; + } + Visit(&node->type); + out_ << ')'; +} + +void TypedPrintVisitor::Visit(ExtendedScopedAnyType* node) { + out_ << "[ExtendedScopedAnyType : ("; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << ") "; + for (auto& reference : node->references) { + switch (reference) { + case utils::ReferenceModifier::Reference: + out_ << '~'; + break; + case utils::ReferenceModifier::UniqueReference: + out_ << '@'; + break; + } + } + out_ << "] ("; + Visitor::Visit(node->type); + out_ << ')'; +} + +// Typeclass + +void TypedPrintVisitor::Visit(ParametrizedTypeclass* node) { + out_ << "[ParametrizedTypeclass] ("; // print type?? + Visit(&node->typeclass); + for (auto& parameter : node->parameters) { + out_ << ' '; + Visit(parameter.get()); + } + out_ << ')'; +} + +// Typeclass & Type ----------------- + +void TypedPrintVisitor::Visit(ParametrizedType* node) { + out_ << "[ParametrizedType : "; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << "] ("; + Visit(&node->type); + for (auto& parameter : node->parameters) { + out_ << ' '; + Visit(parameter.get()); + } + out_ << ')'; +} + +// Identifiers, constants, etc. ----------------- + +void TypedPrintVisitor::Visit(ExtendedName* node) { + out_ << "[ExtendedName : ("; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << ") " << node->name << "] "; +} + +void TypedPrintVisitor::Visit(std::string* node) { // std::string + out_ << "[Identifier " << *node << "] "; +} + +void TypedPrintVisitor::Visit(FloatNumberLiteral* node) { + out_ << "[FloatNumber : ("; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << ") " << node->value << "] "; +} + +void TypedPrintVisitor::Visit(NumberLiteral* node) { + out_ << "[Number : ("; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << ") " << node->value << "] "; +} + +void TypedPrintVisitor::Visit(StringLiteral* node) { + out_ << "[String : ("; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << ") " << node->value << "] "; +} + +void TypedPrintVisitor::Visit(CharLiteral* node) { + out_ << "[Char : ("; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << ") " << node->value << "] "; +} + +void TypedPrintVisitor::Visit(UnitLiteral* node) { + out_ << "[Unit : ("; + + if (node->base.type_.has_value()) { + out_ << context_manager_.GetAnyType(node->base.type_.value())->GetTypeName(); + } + + out_ << ") ()] "; +} + +} // namespace interpreter diff --git a/src/types.cpp b/src/types.cpp index ddd1b67..44cc612 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -436,6 +436,36 @@ std::optional Type::GetFieldType(const std::string& name) const { return std::nullopt; } +std::string Type::GetTypeName() const { + size_t index = type_.index(); + + switch (index) { + case 0: + return "AbstractType"; + case 1: + return "DefinedType"; + case 2: + return "Builtin"; + case 3: + return "TupleType"; + case 4: + return "VariantType"; + case 5: + return "ReferenceToType"; + case 6: + return "FunctionType"; + case 7: + return "ArrayType"; + case 8: + return "OptionalType"; + default: + // error + break; + } + + return ""; // ?? +} + // template