diff --git a/CMakeLists.txt b/CMakeLists.txt index ca1a949..8639cf5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,10 @@ include_directories(include # target_link_libraries(tests PRIVATE Catch2::Catch2WithMain) add_executable(lang_interpreter src/main.cpp + src/types.cpp + src/global_info.cpp + include/type_info_contexts.hpp + include/definitions.hpp src/visitor.cpp src/build_visitor.cpp src/print_visitor.cpp diff --git a/include/.type_check_visitor.hpp.kate-swp b/include/.type_check_visitor.hpp.kate-swp deleted file mode 100644 index 43b2e79..0000000 Binary files a/include/.type_check_visitor.hpp.kate-swp and /dev/null differ diff --git a/include/definitions.hpp b/include/definitions.hpp index 78db090..0d72526 100644 --- a/include/definitions.hpp +++ b/include/definitions.hpp @@ -1,6 +1,5 @@ #pragma once -#include "interpreter_tree.hpp" #include #include #include @@ -9,6 +8,7 @@ #include // for clangd +#include "interpreter_tree.hpp" #include "utils.hpp" namespace interpreter { diff --git a/include/execute_visitor.hpp b/include/execute_visitor.hpp new file mode 100644 index 0000000..3f39cfa --- /dev/null +++ b/include/execute_visitor.hpp @@ -0,0 +1,134 @@ +#pragma once + +#include + +// for clangd +#include "contexts.hpp" +#include "global_info.hpp" +#include "type_info_contexts.hpp" +#include "visitor.hpp" + +namespace interpreter { + +class ExecuteVisitor : public Visitor { +public: + explicit ExecuteVisitor(info::GlobalInfo& global_info, + info::TypeInfoContextManager& type_info_context_manager, + info::ContextManager& context_manager) + : namespace_visitor_(global_info.CreateVisitor()), + type_info_context_manager_(type_info_context_manager), + 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: + info::GlobalInfo::NamespaceVisitor namespace_visitor_; + info::TypeInfoContextManager& type_info_context_manager_; + info::ContextManager& context_manager_; +}; + +} // namespace interpreter diff --git a/include/global_info.hpp b/include/global_info.hpp index c3cb784..d6b1d8b 100644 --- a/include/global_info.hpp +++ b/include/global_info.hpp @@ -107,10 +107,10 @@ public: definition::Namespace* current_namespace, const std::vector& path); private: + GlobalInfo& global_info_; + std::vector namespace_stack_; std::vector current_path_; - - GlobalInfo& global_info_; }; NamespaceVisitor CreateVisitor() { @@ -123,11 +123,11 @@ public: } template - const std::optional& GetTypeInfo(utils::IdType id) { + std::optional GetTypeInfo(utils::IdType id) { if (!std::holds_alternative(types_.at(id).type)) { return std::nullopt; } - return std::get(types_[id].type); + return &std::get(types_[id].type); } // remember about vector realloc @@ -146,6 +146,7 @@ public: } private: + std::vector functions_; std::vector types_; std::vector abstract_types_; diff --git a/include/parse_token_types.hpp b/include/parse_token_types.hpp index 161398c..1c74b33 100644 --- a/include/parse_token_types.hpp +++ b/include/parse_token_types.hpp @@ -40,8 +40,9 @@ const std::string AnnotatedType = "annotated_type"; // Flow control ----------------- +const std::string TypeConstructorPatternParameter = "type_constructor_pattern_parameter"; const std::string TypeConstructorPattern = "type_constructor_pattern"; -const std::string PatternToken = "pattern_token"; +const std::string ScopedPattern = "scoped_pattern"; const std::string Pattern = "pattern"; const std::string MatchCase = "match_case"; const std::string Match = "match"; @@ -77,6 +78,7 @@ const std::string FunctionCallExpression = "function_call_expression"; const std::string TupleExpression = "tuple_expression"; const std::string VariantExpression = "variant_expression"; const std::string ReturnExpression = "return_expression"; +const std::string TypeConstructorParameter = "type_constructor_parameter"; const std::string TypeConstructor = "type_constructor"; const std::string LambdaFunction = "lambda_function"; const std::string ArrayExpression = "array_expression"; @@ -88,7 +90,6 @@ const std::string NameExpression = "name_expression"; const std::string TupleName = "tuple_name"; const std::string VariantName = "variant_name"; const std::string AnnotatedName = "annotated_name"; -const std::string NameSubExpression = "name_subexpression"; const std::string AnyName = "any_name"; const std::string ScopedAnyName = "scoped_any_name"; diff --git a/include/type_check_visitor.hpp b/include/type_check_visitor.hpp index e9d656c..715d88e 100644 --- a/include/type_check_visitor.hpp +++ b/include/type_check_visitor.hpp @@ -11,7 +11,8 @@ namespace interpreter { class TypeCheckVisitor : public Visitor { public: - explicit TypeCheckVisitor(info::GlobalInfo& global_info, info::TypeInfoContextManager& context_manager) + explicit TypeCheckVisitor(info::GlobalInfo& global_info, + info::TypeInfoContextManager& context_manager) : namespace_visitor_(global_info.CreateVisitor()), context_manager_(context_manager) {} private: diff --git a/include/type_info_contexts.hpp b/include/type_info_contexts.hpp index 7652f0e..6cf445b 100644 --- a/include/type_info_contexts.hpp +++ b/include/type_info_contexts.hpp @@ -14,13 +14,17 @@ namespace info { // TODO: remember about type pointers class TypeInfoContextManager { public: + TypeInfoContextManager() { + contexts_.emplace_back(); + } + template - utils::IdType AddType(T&& type, utils::ValueType value_type) { - return type_manager_.AddType(std::forward(type), value_type); + utils::IdType AddType(const T& type, utils::ValueType value_type) { + return type_manager_.AddType(type, value_type); } utils::IdType AddAnyType(type::Type&& type, utils::ValueType value_type) { - return type_manager_.AddType(std::move(type), value_type); + return type_manager_.AddAnyType(std::move(type), value_type); } template @@ -45,7 +49,8 @@ public: } utils::IdType ToModifiedType(utils::IdType type_id, utils::ValueType new_value_type) { - return AddAnyType(type::Type(*GetAnyType(type_id)), new_value_type); + type::Type type = *GetAnyType(type_id); + return AddAnyType(std::move(type), new_value_type); } type::TypeManager* GetTypeManager() { @@ -53,7 +58,7 @@ public: } void EnterContext() { - contexts_.emplace_back(false); + contexts_.emplace_back(); } void ExitContext() { @@ -74,11 +79,10 @@ public: } bool DefineLocalAbstractType(const std::string& name, utils::IdType type_id) { - if (GetLocalAbstractType(name)) { + if (GetLocalAbstractType(name).has_value()) { return false; } - contexts_.back().DefineLocalAbstractType(name, type_id); - return true; + return contexts_.back().DefineLocalAbstractType(name, type_id); } @@ -124,7 +128,7 @@ private: Context() = default; bool DefineVariable(const std::string& name, utils::IdType type_id) { - if (name == "_") { // placeholder // TODO: check in all places + if (name == "_") { // placeholder // TODO: ?? return true; } diff --git a/include/types.hpp b/include/types.hpp index bdceb7f..b27c35f 100644 --- a/include/types.hpp +++ b/include/types.hpp @@ -225,7 +225,7 @@ public: Type() = default; template - explicit Type(T&& type) : type_(std::forward(type)) {} + explicit Type(const T& type) : type_(type) {} std::optional InContext(const std::unordered_map& context); bool Same(const Type& type) const; @@ -236,6 +236,17 @@ public: std::string GetTypeName() const; + std::variant& GetType() { + return type_; + } private: std::variant - utils::IdType AddType(T&& type, utils::ValueType value_type); + utils::IdType AddType(const T& type, utils::ValueType value_type) { + types_.push_back(std::pair {type, value_type}); + return types_.size() - 1; + } - utils::IdType AddAnyType(Type&& type, utils::ValueType value_type); + utils::IdType AddAnyType(Type&& type, utils::ValueType value_type) { + types_.push_back(std::pair {std::move(type), value_type}); + return types_.size() - 1; + } template - std::optional GetType(utils::IdType type_id); + std::optional GetType(utils::IdType type_id) { + if (!std::holds_alternative(types_.at(type_id).first.GetType())) { + return std::nullopt; + } + return &std::get(types_.at(type_id).first.GetType()); + } - Type* GetAnyType(utils::IdType type_id); + Type* GetAnyType(utils::IdType type_id) { + return &types_.at(type_id).first; + } - utils::ValueType GetValueType(utils::IdType type_id); + utils::ValueType GetValueType(utils::IdType type_id) { + return types_.at(type_id).second; + } - bool AddTypeRequirement(utils::IdType type, utils::IdType requrement); - bool EqualTypes(utils::IdType first_type, utils::IdType second_type); + bool EqualTypes(utils::IdType first_type, utils::IdType second_type) { + return GetAnyType(first_type)->Same(*GetAnyType(second_type)); + } + + bool AddTypeRequirement(utils::IdType type, utils::IdType requrement) { + return *GetAnyType(requrement) < *GetAnyType(type); + } private: - std::vector> types_; + std::vector> types_; }; } // namespace info::type diff --git a/include/utils.hpp b/include/utils.hpp index 159ebce..25463ed 100644 --- a/include/utils.hpp +++ b/include/utils.hpp @@ -28,6 +28,7 @@ inline ValueType IsConstModifierToValueType(IsConstModifier modifier) { return ValueType::Var; } // unreachable + exit(1); } template @@ -107,32 +108,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/include/values.hpp b/include/values.hpp new file mode 100644 index 0000000..cf121f7 --- /dev/null +++ b/include/values.hpp @@ -0,0 +1,143 @@ +#pragma once + +#include +#include +#include +#include + +// for clangd +#include "interpreter_tree.hpp" +#include "utils.hpp" + +namespace info::value { + +struct Unit {}; + + + +struct InternalValue { +public: + InternalValue() = default; + InternalValue(std::variant&& value) : value(std::move(value)) {} + +public: + std::variant value; +}; + +struct TupleValue { +public: + TupleValue() = default; + TupleValue(std::unordered_map&& fields) : fields(fields) {} + +public: + std::unordered_map fields; +}; + +struct VariantValue { +public: + VariantValue() = default; + VariantValue(size_t constructor, TupleValue value) + : constructor(constructor), value(value) {} + +public: + size_t constructor; + TupleValue value; +}; + +struct ReferenceToValue { +public: + ReferenceToValue() = default; + ReferenceToValue(const std::vector& references, + utils::IdType value) + : references(references), value(value) {} + +public: + std::vector references; + utils::IdType value; +}; + +struct FunctionValue { +public: + FunctionValue() = default; + FunctionValue(std::variant function) + : function(function) {} + +public: + std::variant function; +}; + + +struct ArrayValue { +public: + ArrayValue() = default; + ArrayValue(const std::vector& elements) + : elements(elements) {} + +public: + std::vector elements; +}; + +struct OptionalValue { +public: + OptionalValue() = default; + OptionalValue(utils::IdType value) : value(value) {} + +public: + std::optional value; +}; + +struct Value { // DefinedValue ?? + std::variant value; +}; + +class ValueManager { +public: + template + utils::IdType AddType(const T& value, utils::ValueType value_type) { + values_.push_back(std::pair {value, value_type}); + return values_.size() - 1; + } + + utils::IdType AddAnyType(Value&& value, utils::ValueType value_type) { + values_.push_back(std::pair {std::move(value), value_type}); + return values_.size() - 1; + } + + template + std::optional GetType(utils::IdType value_id) { + if (!std::holds_alternative(values_.at(value_id).first.value)) { + return std::nullopt; + } + return &std::get(values_.at(value_id).first.value); + } + + Value* GetAnyType(utils::IdType value_id) { + return &values_.at(value_id).first; + } + + utils::ValueType GetValueType(utils::IdType value_id) { + return values_.at(value_id).second; + } +private: + std::vector> values_; +}; + +} // namespace info::value diff --git a/src/build_visitor.cpp b/src/build_visitor.cpp index 7e7353b..acce463 100644 --- a/src/build_visitor.cpp +++ b/src/build_visitor.cpp @@ -487,6 +487,7 @@ void BuildVisitor::Visit(TypeConstructorPattern* node) { auto parse_node = current_node_; current_node_ = parse_node.ChildByFieldName("constructor"); + node->constructor = std::make_unique(); Visit(node->constructor.get()); size_t child_count = parse_node.NamedChildCount(); @@ -988,8 +989,6 @@ void BuildVisitor::Visit(FunctionCallExpression* node) { if (child_count > excluded_child_count) { bool parameters_ended = false; - node->arguments.resize(child_count - excluded_child_count); - for (size_t i = 0; i + excluded_child_count < child_count; ++i) { current_node_ = parse_node.NthNamedChild(i + excluded_child_count); @@ -1499,12 +1498,7 @@ void BuildVisitor::Visit(ParametrizedType* node) { void BuildVisitor::Visit(ExtendedName* node) { SetPosition(node->base, current_node_); - size_t child_count = current_node_.NamedChildCount(); - if (child_count > 1) { - node->name = current_node_.GetValue(); - } else { - node->name = current_node_.NthNamedChild(0).GetValue(); - } + node->name = current_node_.GetValue(); } // void BuildVisitor::Visit(AnyIdentifier* node) { // std::string diff --git a/src/execute_visitor.cpp b/src/execute_visitor.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/global_info.cpp b/src/global_info.cpp index bc29fca..93d9676 100644 --- a/src/global_info.cpp +++ b/src/global_info.cpp @@ -47,7 +47,8 @@ void GlobalInfo::NamespaceVisitor::EnterNamespace(const std::string& name) { } } - error_handling::HandleInternalError("Can't find namespace", "GlobalInfo.NamespaceVisitor.EnterNamespace"); + error_handling::HandleInternalError("Can't find namespace", + "GlobalInfo.NamespaceVisitor.EnterNamespace"); } void GlobalInfo::NamespaceVisitor::ExitNamespace() { @@ -67,8 +68,10 @@ void GlobalInfo::NamespaceVisitor::ToGlobalNamespace() { namespace_stack_.push_back(&global_info_.global_namespace_); } -utils::IdType GlobalInfo::NamespaceVisitor::AddFunctionDeclaration(const std::string& name, - definition::FunctionDeclaration&& function_declaration_info) { +utils::IdType GlobalInfo::NamespaceVisitor::AddFunctionDeclaration( + const std::string& name, + definition::FunctionDeclaration&& function_declaration_info) { + size_t id = 0; auto function_id_iter = namespace_stack_.back()->functions.find(name); @@ -77,12 +80,13 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddFunctionDeclaration(const std::st id = global_info_.functions_.size(); namespace_stack_.back()->functions[name] = id; global_info_.functions_.emplace_back(); - global_info_.functions_.back().argument_count = function_declaration_info.argument_types.size(); + global_info_.functions_.back().argument_count = function_declaration_info.argument_types.size(); // add return type global_info_.functions_.back().declaration = std::move(function_declaration_info); } else { id = function_id_iter->second; if (global_info_.functions_.back().argument_count != function_declaration_info.argument_types.size()) { - error_handling::HandleInternalError("Not same argument count in function definition and declaration", "GlobalInfo"); + error_handling::HandleInternalError("Not same argument count in function definition and declaration", + "GlobalInfo.NamespaceVisitor. AddFunctionDeclaration"); } global_info_.functions_[id].declaration = std::move(function_declaration_info); } @@ -100,11 +104,11 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddFunctionDefinition(const std::str id = global_info_.functions_.size(); namespace_stack_.back()->functions[name] = id; global_info_.functions_.emplace_back(); - global_info_.functions_.back().argument_count = function_definition_info.argument_names.size(); + global_info_.functions_.back().argument_count = function_definition_info.argument_names.size() + 1; global_info_.functions_.back().definition = std::move(function_definition_info); } else { id = function_id_iter->second; - if (global_info_.functions_.back().argument_count != function_definition_info.argument_names.size()) { + if (global_info_.functions_.back().argument_count != function_definition_info.argument_names.size() + 1) { error_handling::HandleInternalError("Not same argument count in function definition and declaration", "GlobalInfo"); } global_info_.functions_[id].definition = std::move(function_definition_info); @@ -178,12 +182,15 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddAbstractType(const std::string& a definition::AbstractType&& abstract_type_info, const interpreter::tokens::BaseNode& base_node) { if (!FindAbstractType(abstract_type).has_value()) { - size_t id = global_info_.abstract_types_.size(); + utils::IdType id = global_info_.abstract_types_.size(); global_info_.name_to_abstract_type_[abstract_type] = id; global_info_.abstract_types_.push_back(std::move(abstract_type_info)); + + return id; } - error_handling::HandleTypecheckError("More then one abstract type with the same name in namespace", base_node); + error_handling::HandleTypecheckError("More then one abstract type with the same name in namespace", + base_node); return 0; } @@ -341,6 +348,8 @@ std::optional GlobalInfo::NamespaceVisitor::FindSomething( if (!maybe_namespace.has_value()) { continue; } + + current_namespace = maybe_namespace.value(); } else { current_namespace = namespace_stack_[i]; } diff --git a/src/link_symbols_visitor.cpp b/src/link_symbols_visitor.cpp index cc95335..9b96eec 100644 --- a/src/link_symbols_visitor.cpp +++ b/src/link_symbols_visitor.cpp @@ -50,9 +50,14 @@ 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()) { // TODO: check, that not bastract types - // error_handling::HandleTypecheckError("Type or constructor not found", node->base); - // } + if (path.size() == 0 && namespace_visitor_.FindAbstractType(node->type.type).has_value()) { // TODO + // abstract / basic / TODO: local abstract type + return; + } + + 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 4198c67..6bd6f0a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -47,15 +47,21 @@ int main(int argc, char** argv) { // TODO, only test version 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()); + + std::cout << "\n---------------------------------- Untyped -------------------------------------\n\n"; + 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()); + + std::cout << "\n---------------------------------- Typed -------------------------------------\n\n"; typed_print_visitor.VisitSourceFile(source_file.get()); } diff --git a/src/type_check_visitor.cpp b/src/type_check_visitor.cpp index 77bf865..01e63f7 100644 --- a/src/type_check_visitor.cpp +++ b/src/type_check_visitor.cpp @@ -52,8 +52,6 @@ void TypeCheckVisitor::Visit(NamespaceSources* node) { void TypeCheckVisitor::Visit(Namespace* node) { // TODO: two var namespces for class: const and var if (node->modifier.has_value()) { - bool is_const = (node->modifier.value() == utils::IsConstModifier::Const); - if (node->link_typeclass_id_.has_value()) { // TODO: think about typeclass std::vector requirements {node->link_typeclass_id_.value()}; @@ -65,10 +63,10 @@ void TypeCheckVisitor::Visit(Namespace* node) { // TODO: two var namespces for c abstract_type); context_manager_.DefineLocalAbstractType(node->type, abstract_type); } else if (node->link_type_id_.has_value()) { - Visitor::Visit(*namespace_visitor_.GetGlobalInfo()->GetTypeInfo(node->link_type_id_.value()).value().value); // handle error? + Visitor::Visit(*namespace_visitor_.GetGlobalInfo()->GetTypeInfo(node->link_type_id_.value()).value()->value); // handle error? context_manager_.EnterVariableContext( - "self", // TODO: different name ?? + "self", // TODO: different name context_manager_.AddType( info::type::DefinedType(node->link_type_id_.value(), current_type_, context_manager_.GetTypeManager()), IsConstModifierToValueType(node->modifier.value()))); @@ -147,6 +145,20 @@ void TypeCheckVisitor::Visit(FunctionDeclaration* node) { bool was_in_statement = is_in_statement_; is_in_statement_ = true; + context_manager_.EnterContext(); + for (auto& parameter : node->parameters) { // declaration correctness check // TODO: needed?? + std::vector requirements; + // TODO: + current_type_ = context_manager_.AddType( + info::type::AbstractType(utils::AbstractTypeModifier::Abstract, + parameter->type, + requirements), // TODO: typeclasses-requirements + utils::ValueType::Tmp); + context_manager_.DefineLocalAbstractType(parameter->type, current_type_); + } + Visit(node->type.get()); + context_manager_.ExitContext(); + current_type_ = context_manager_.AddType(info::type::InternalType::Unit, utils::ValueType::Tmp); if (!was_in_statement) { @@ -196,7 +208,7 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) { Visitor::Visit(*declaration.argument_types.back()); utils::IdType return_type = current_type_; - Visitor::Visit(node->value); + // Visitor::Visit(node->value); if (!context_manager_.EqualTypes(return_type, current_type_)) { error_handling::HandleTypecheckError("Wrong function return type", node->base); } @@ -298,7 +310,7 @@ void TypeCheckVisitor::Visit(TypeConstructorPattern* node) { // TODO: match name CollectTypeExpressionContext(*node->constructor, context); // TODO: handle alias types - const std::optional& maybe_type_info = + std::optional maybe_type_info = namespace_visitor_.GetGlobalInfo()->GetTypeInfo(type_id); if (!maybe_type_info.has_value()) { // TODO @@ -306,7 +318,7 @@ void TypeCheckVisitor::Visit(TypeConstructorPattern* node) { // TODO: match name "TypeCheckVisitor.TypeConstructorPattern"); } - const info::definition::AnyType& type_info = maybe_type_info.value(); + info::definition::AnyType& type_info = *maybe_type_info.value(); if (constructor_info.constructor_tuple_node.has_value()) { @@ -495,8 +507,8 @@ void TypeCheckVisitor::Visit(ForLoop* node) { context_manager_.EnterContext(); - current_type_ = context_manager_.AddType(maybe_interval_type.value()->GetElementsType(), - utils::IsConstModifierToValueType(node->variable_modifier)); + current_type_ = context_manager_.ToModifiedType(maybe_interval_type.value()->GetElementsType(), + utils::IsConstModifierToValueType(node->variable_modifier)); is_const_definition_ = node->variable_modifier; Visitor::Visit(node->variable); // type passed to variable definition throught current_type_ @@ -625,7 +637,7 @@ void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) { auto maybe_left_type_info = namespace_visitor_.GetGlobalInfo()->GetTypeInfo(maybe_left_type.value()->GetTypeId()); - std::string left_type_name = maybe_left_type_info.value().type.type; + std::string left_type_name = maybe_left_type_info.value()->type.type; auto maybe_const_operator_id = namespace_visitor_.FindMethod(std::nullopt, left_type_name, @@ -780,7 +792,7 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) { utils::IdType type_id = maybe_expression_type.value()->GetTypeId(); - const std::optional& maybe_type_info = namespace_visitor_.GetGlobalInfo()->GetTypeInfo(type_id); + std::optional maybe_type_info = namespace_visitor_.GetGlobalInfo()->GetTypeInfo(type_id); if (!maybe_type_info.has_value()) { error_handling::HandleInternalError("Functions/Methods implemented only for AnyType", @@ -788,7 +800,7 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) { } // TODO: better decision ?? - std::optional maybe_const_function_id = maybe_type_info.value().parent_namespace->const_namespaces.at(maybe_type_info->type.type).functions[node->name.name]; + std::optional maybe_const_function_id = maybe_type_info.value()->parent_namespace->const_namespaces.at(maybe_type_info.value()->type.type).functions[node->name.name]; utils::ValueType expression_value_type = context_manager_.GetValueType(current_type_); @@ -799,7 +811,7 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) { if (expression_value_type == utils::ValueType::Var || expression_value_type == utils::ValueType::Tmp) { // TODO: choose expression value types - maybe_function_id = maybe_type_info.value().parent_namespace->var_namespaces.at(maybe_type_info->type.type).functions[node->name.name]; + maybe_function_id = maybe_type_info.value()->parent_namespace->var_namespaces.at(maybe_type_info.value()->type.type).functions[node->name.name]; } if (maybe_const_function_id.has_value() && maybe_function_id.has_value()) { // TODO: handle on link_types stage @@ -899,7 +911,7 @@ void TypeCheckVisitor::Visit(VariantExpression* node) { // TODO: deal with expression tuple types, etc, ?? std::vector, utils::IdType>> constructor_fields {{std::nullopt, current_type_}}; - constructors.emplace_back(std::nullopt, constructor_fields, context_manager_.GetTypeManager()); + constructors.push_back(info::type::TupleType(std::nullopt, constructor_fields, context_manager_.GetTypeManager())); } @@ -937,14 +949,14 @@ void TypeCheckVisitor::Visit(TypeConstructor* node) { CollectTypeExpressionContext(*node->constructor, context); // TODO: handle alias types - const std::optional& maybe_type_info = + std::optional maybe_type_info = namespace_visitor_.GetGlobalInfo()->GetTypeInfo(type_id); if (!maybe_type_info.has_value()) { // TODO error_handling::HandleInternalError("Implemented only for AnyType", "TypeCheckVisitor.TypeConstructor"); } - const info::definition::AnyType& type_info = maybe_type_info.value(); + info::definition::AnyType& type_info = *maybe_type_info.value(); if (constructor_info.constructor_tuple_node.has_value()) { @@ -1215,7 +1227,11 @@ void TypeCheckVisitor::Visit(TupleType* node) { fields.reserve(node->entities.size()); for (auto& entity : node->entities) { Visit(entity.second.get()); - fields.emplace_back(entity.first, current_type_); + if (entity.first.has_value()) { + fields.push_back({entity.first.value().name, current_type_}); + } else { + fields.push_back({std::nullopt, current_type_}); + } } current_type_ = context_manager_.AddType( @@ -1232,14 +1248,14 @@ void TypeCheckVisitor::Visit(VariantType* node) { for (auto& constructor : node->constructors) { if (std::holds_alternative(constructor)) { std::vector, utils::IdType>> constructor_fields; - constructors.emplace_back(std::get(constructor), constructor_fields, context_manager_.GetTypeManager()); + constructors.push_back(info::type::TupleType(std::get(constructor), constructor_fields, context_manager_.GetTypeManager())); } else if (std::holds_alternative>(constructor)) { Visit(std::get>(constructor).get()); - std::optional maybe_constructor = context_manager_.GetType(current_type_); + std::optional maybe_constructor = context_manager_.GetType(current_type_); if (!maybe_constructor.has_value()) { error_handling::HandleInternalError("Entity of VariantType is not TupleType", "TypeCheckVisitor.VariantType"); } - constructors.emplace_back(maybe_constructor.value()); + constructors.push_back(*maybe_constructor.value()); } else { // error } @@ -1256,20 +1272,23 @@ void TypeCheckVisitor::Visit(TypeExpression* node) { std::unordered_map context; CollectTypeExpressionContext(*node, context); - const std::optional& maybe_type_info = - namespace_visitor_.GetGlobalInfo()->GetTypeInfo(node->type.type_id_.value()); - - if (!maybe_type_info.has_value()) { // TODO: add alias, abstract, ... types - error_handling::HandleInternalError("No any type found", "TypeCheckVisitor.TypeExpression"); - } - std::optional maybe_local_abstract_type = context_manager_.GetLocalAbstractType(node->type.type); if (node->path.size() == 0 && maybe_local_abstract_type.has_value()) { current_type_ = maybe_local_abstract_type.value(); - } + } else if (node->type.type_id_.has_value()) { // TODO: chack that names are different (always true ??) - Visitor::Visit(*maybe_type_info.value().value); - current_type_ = TypeInContext(current_type_, context); + std::optional maybe_type_info = + namespace_visitor_.GetGlobalInfo()->GetTypeInfo(node->type.type_id_.value()); + + if (!maybe_type_info.has_value()) { // TODO: add alias, abstract, ... types + error_handling::HandleInternalError("No AnyType found", "TypeCheckVisitor.TypeExpression"); + } + + Visitor::Visit(*maybe_type_info.value()->value); + current_type_ = TypeInContext(current_type_, context); + } else { + error_handling::HandleTypecheckError("Type not found", node->base); + } if (node->array_size.has_value()) { current_type_ = context_manager_.AddType( @@ -1330,6 +1349,12 @@ void TypeCheckVisitor::Visit(CharLiteral* node) { node->base.type_ = current_type_; } +void TypeCheckVisitor::Visit(UnitLiteral* node) { + current_type_ = context_manager_.AddType(info::type::InternalType::Unit, utils::ValueType::Tmp); + + node->base.type_ = current_type_; +} + // void TypeCheckVisitor::CollectTypeContext(const ParametrizedType& type, @@ -1338,14 +1363,14 @@ void TypeCheckVisitor::CollectTypeContext(const ParametrizedType& type, return; } - const std::optional& maybe_type_info = + std::optional maybe_type_info = namespace_visitor_.GetGlobalInfo()->GetTypeInfo(type.type_id_.value()); if (!maybe_type_info.has_value()) { error_handling::HandleInternalError("Wrong type id", "TypeCheckVisitor.CollectTypeContext"); } - const info::definition::AnyType& type_info = maybe_type_info.value(); + info::definition::AnyType& type_info = *maybe_type_info.value(); if (type_info.parameters.size() != type.parameters.size()) { error_handling::HandleTypecheckError("Wrong type parameters count", type.base); @@ -1372,7 +1397,7 @@ void TypeCheckVisitor::CollectTypeExpressionContext(const TypeExpression& type_e utils::IdType TypeCheckVisitor::TypeInContext(utils::IdType type, const std::unordered_map& context) { - info::type::Type type_in_context = info::type::Type(context_manager_.GetAnyType(type)); + info::type::Type type_in_context = *context_manager_.GetAnyType(type); type_in_context.InContext(context); return context_manager_.AddType(std::move(type_in_context), utils::ValueType::Tmp); } diff --git a/src/types.cpp b/src/types.cpp index 44cc612..97c662e 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -466,42 +466,5 @@ std::string Type::GetTypeName() const { return ""; // ?? } -// - -template -utils::IdType TypeManager::AddType(T&& type, utils::ValueType value_type) { - types_.emplace_back({std::forward(type), value_type}); - return types_.size() - 1; -} - -utils::IdType TypeManager::AddAnyType(Type&& type, utils::ValueType value_type) { - types_.push_back({std::move(type), value_type}); - return types_.size() - 1; -} - -template -std::optional TypeManager::GetType(utils::IdType type_id) { - if (!std::holds_alternative(types_.at(type_id).second)) { - return std::nullopt; - } - return &std::get(types_.at(type_id).second); -} - -Type* TypeManager::GetAnyType(utils::IdType type_id) { - return &types_.at(type_id).first; -} - -utils::ValueType TypeManager::GetValueType(utils::IdType type_id) { - return types_.at(type_id).second; -} - -bool TypeManager::EqualTypes(utils::IdType first_type, utils::IdType second_type) { - return GetAnyType(first_type)->Same(*GetAnyType(second_type)); -} - -bool TypeManager::AddTypeRequirement(utils::IdType type, utils::IdType requrement) { - return *GetAnyType(requrement) < *GetAnyType(type); -} - } // namespace info::type diff --git a/tests/default_constructors.lang b/tests/default_constructors.lang index 51a19c6..ca9b513 100644 --- a/tests/default_constructors.lang +++ b/tests/default_constructors.lang @@ -1,6 +1,6 @@ namespace Employee { decl gen_employee : Unit -> Employee - def gen_employee = { + def gen_employee : a = { return $Employee & name = "John" diff --git a/tests/match.lang b/tests/match.lang index c6af2ff..a45fb83 100644 --- a/tests/match.lang +++ b/tests/match.lang @@ -1,12 +1,8 @@ -================================================================================ -Match -================================================================================ - decl fruit_cost : Fruit -> Int def fruit_cost : fruit = { - return (match fruit with - | $Banana -> 11 - | $Apple | $Orange -> 7) + return (match fruit with + | $Banana -> 11 + | $Apple | $Orange -> 7) } decl amount_to_string : Int -> Bool -> String @@ -19,252 +15,3 @@ def amount_to_string : x is_zero_separated = { | _ -> "Lots" return ans } - --------------------------------------------------------------------------------- - -(source_file - (source_statement - (partition_statement - (namespace_statement - (function_declaration - (extended_name - (name_identifier)) - (function_type - (scoped_any_type - (type_expression - (parametrized_type - (type_identifier)))) - (scoped_any_type - (type_expression - (parametrized_type - (type_identifier))))))))) - (source_statement - (partition_statement - (namespace_statement - (function_definition_statement - (function_definition - (extended_name - (name_identifier)) - (extended_name - (name_identifier))) - (superexpression - (expression - (prefixed_expression - (block - (block_statement - (prefixed_expression - (return_expression - (expression - (subexpression - (subexpression_token - (scoped_statement - (superexpression - (flow_control - (match - (expression - (subexpression - (subexpression_token - (name_expression - (extended_name - (name_identifier)))))) - (match_case - (pattern - (type_constructor_pattern - (type_expression - (parametrized_type - (type_identifier))))) - (expression - (subexpression - (subexpression_token - (literal - (number_literal)))))) - (match_case - (pattern - (type_constructor_pattern - (type_expression - (parametrized_type - (type_identifier)))))) - (match_case - (pattern - (type_constructor_pattern - (type_expression - (parametrized_type - (type_identifier))))) - (expression - (subexpression - (subexpression_token - (literal - (number_literal)))))))))))))))))))))))) - (source_statement - (partition_statement - (namespace_statement - (function_declaration - (extended_name - (name_identifier)) - (function_type - (scoped_any_type - (type_expression - (parametrized_type - (type_identifier)))) - (scoped_any_type - (type_expression - (parametrized_type - (type_identifier)))) - (scoped_any_type - (type_expression - (parametrized_type - (type_identifier))))))))) - (source_statement - (partition_statement - (namespace_statement - (function_definition_statement - (function_definition - (extended_name - (name_identifier)) - (extended_name - (name_identifier)) - (extended_name - (name_identifier))) - (superexpression - (expression - (prefixed_expression - (block - (block_statement - (variable_definition_statement - (any_name - (annotated_name - (extended_name - (name_identifier)))) - (superexpression - (flow_control - (match - (expression - (subexpression - (subexpression_token - (name_expression - (extended_name - (name_identifier)))))) - (match_case - (pattern - (literal - (number_literal))) - (expression - (subexpression - (subexpression_token - (name_expression - (extended_name - (name_identifier)))))) - (expression - (subexpression - (subexpression_token - (literal - (string_literal)))))) - (match_case - (pattern - (literal - (number_literal)))) - (match_case - (pattern - (literal - (number_literal)))) - (match_case - (pattern - (literal - (number_literal)))) - (match_case - (pattern - (literal - (number_literal)))) - (match_case - (pattern - (literal - (number_literal))) - (expression - (subexpression - (subexpression_token - (literal - (string_literal)))))) - (match_case - (pattern - (extended_name - (name_identifier))) - (expression - (subexpression - (function_call_expression - (subexpression_token - (scoped_statement - (superexpression - (expression - (subexpression - (binary_operator_expression - (subexpression - (subexpression_token - (literal - (number_literal)))) - (operator) - (subexpression - (subexpression_token - (literal - (number_literal)))))))))) - (extended_name - (name_identifier)) - (subexpression_token - (name_expression - (extended_name - (name_identifier))))))) - (expression - (subexpression - (subexpression_token - (literal - (string_literal)))))) - (match_case - (pattern - (extended_name - (name_identifier))) - (expression - (subexpression - (function_call_expression - (subexpression_token - (scoped_statement - (superexpression - (expression - (subexpression - (binary_operator_expression - (subexpression - (subexpression_token - (literal - (number_literal)))) - (operator) - (subexpression - (subexpression_token - (literal - (number_literal)))))))))) - (extended_name - (name_identifier)) - (subexpression_token - (name_expression - (extended_name - (name_identifier))))))) - (expression - (subexpression - (subexpression_token - (literal - (string_literal)))))) - (match_case - (pattern - (extended_name - (name_identifier))) - (expression - (subexpression - (subexpression_token - (literal - (string_literal))))))))))) - (block_statement - (prefixed_expression - (return_expression - (expression - (subexpression - (subexpression_token - (name_expression - (extended_name - (name_identifier)))))))))))))))))) diff --git a/tests/test_code.lang b/tests/test_code.lang new file mode 100644 index 0000000..2f258d2 --- /dev/null +++ b/tests/test_code.lang @@ -0,0 +1,11 @@ +basic String +basic Int +basic Unit + +decl print : String -> Unit + +decl func : String -> Int +def func : s = { + ; print: s + return 5 +} diff --git a/tests/types.lang b/tests/types.lang index 5177be2..f6ce429 100644 --- a/tests/types.lang +++ b/tests/types.lang @@ -1,7 +1,3 @@ -================================================================================ -Types -================================================================================ - alias T1 = Int abstract (T2 : #A #B #C) @@ -10,50 +6,3 @@ abstract (T2 : #A #B #C) let T2 = Int let T2 = Float let T2 = Complex - --------------------------------------------------------------------------------- - -(source_file - (source_statement - (partition_statement - (namespace_statement - (alias_definition_statement - (type_identifier) - (type_expression - (parametrized_type - (type_identifier))))))) - (source_statement - (partition_statement - (abstract_type_definition_statement - (annotated_type - (type_identifier) - (parametrized_typeclass - (typeclass_identifier)) - (parametrized_typeclass - (typeclass_identifier)) - (parametrized_typeclass - (typeclass_identifier)))))) - (source_statement - (partition_statement - (namespace_statement - (alias_definition_statement - (type_identifier) - (type_expression - (parametrized_type - (type_identifier))))))) - (source_statement - (partition_statement - (namespace_statement - (alias_definition_statement - (type_identifier) - (type_expression - (parametrized_type - (type_identifier))))))) - (source_statement - (partition_statement - (namespace_statement - (alias_definition_statement - (type_identifier) - (type_expression - (parametrized_type - (type_identifier))))))))