From b90107895661be7d8e08d0296d23b515f1f9a8c6 Mon Sep 17 00:00:00 2001 From: ProgramSnail Date: Thu, 18 May 2023 01:02:54 +0300 Subject: [PATCH] fixes --- include/global_info.hpp | 10 +- include/values.hpp | 33 ++++-- src/global_info.cpp | 29 +++-- src/type_check_visitor.cpp | 8 +- src/types.cpp | 210 ++++++++++++++++++------------------- src/values.cpp | 156 ++++++++++++++++++++++----- 6 files changed, 291 insertions(+), 155 deletions(-) diff --git a/include/global_info.hpp b/include/global_info.hpp index 6d48585..2678cb3 100644 --- a/include/global_info.hpp +++ b/include/global_info.hpp @@ -356,11 +356,13 @@ public: std::vector GetAnnotatedTypeTypeclassesVector(interpreter::tokens::AnnotatedType* node); - std::unordered_map - GetAnnotatedTypeFunctionsMap(interpreter::tokens::AnnotatedType* node); + std::unordered_map + GetAnnotatedTypeFunctionsMap(interpreter::tokens::AnnotatedType* node, + const interpreter::tokens::BaseNode& base_node); - std::vector> - GetAnnotatedTypeFunctionsVector(interpreter::tokens::AnnotatedType* node); + std::vector> + GetAnnotatedTypeFunctionsVector(interpreter::tokens::AnnotatedType* node, + const interpreter::tokens::BaseNode& base_node); std::unordered_map* ChooseNamespaces( utils::ClassInternalsModifier modifier, diff --git a/include/values.hpp b/include/values.hpp index c6570b1..e7ef2d2 100644 --- a/include/values.hpp +++ b/include/values.hpp @@ -30,7 +30,8 @@ public: return &std::get(value); } - std::optional GetFieldValue(const std::string& name); + bool Same(const InternalValue& value) const; + std::optional GetFieldValue(const std::string& name) const; public: std::variant GetFieldValue(const std::string& name); + bool Same(const TupleValue& other_value) const; + std::optional GetFieldValue(const std::string& name) const; public: std::vector, utils::IdType>> fields; @@ -67,7 +69,8 @@ public: TupleValue value; size_t current_constructor; - std::optional GetFieldValue(const std::string& name); + bool Same(const VariantValue& other_value) const; + std::optional GetFieldValue(const std::string& name) const; }; struct ReferenceToValue { @@ -83,7 +86,9 @@ public: std::vector references; utils::IdType value; - std::optional GetFieldValue(const std::string& name); + bool Same(const ReferenceToValue& other_value) const; + std::optional GetFieldValue(const std::string& name) const; + private: ValueManager* value_manager_ = nullptr; }; @@ -100,7 +105,9 @@ public: std::variant function; - std::optional GetFieldValue(const std::string& name); + bool Same(const FunctionValue& other_value) const; + std::optional GetFieldValue(const std::string& name) const; + private: ValueManager* value_manager_ = nullptr; }; @@ -119,7 +126,9 @@ public: std::vector elements; bool is_constant_size = false; - std::optional GetFieldValue(const std::string& name); + bool Same(const ArrayValue& other_value) const; + std::optional GetFieldValue(const std::string& name) const; + private: ValueManager* value_manager_ = nullptr; }; @@ -131,7 +140,9 @@ public: OptionalValue(std::optional value, ValueManager* value_manager) : value(value), value_manager_(value_manager) {} - std::optional GetFieldValue(const std::string& name); + bool Same(const OptionalValue& other_value) const; + std::optional GetFieldValue(const std::string& name) const; + public: std::optional value; @@ -146,7 +157,9 @@ public: template explicit Value(const T& value) : value(value) {} // move ?? - std::optional GetFieldValue(const std::string& name); + bool Same(const Value& other_value) const; + std::optional GetFieldValue(const std::string& name) const; + public: std::variantSame(*GetAnyValue(second_value)); + } bool AddValueRequirement(utils::IdType value, utils::IdType requrement) = delete; diff --git a/src/global_info.cpp b/src/global_info.cpp index 62a4c60..456e460 100644 --- a/src/global_info.cpp +++ b/src/global_info.cpp @@ -492,28 +492,41 @@ std::vector return typeclasses_vector; } -std::unordered_map - GlobalInfo::GetAnnotatedTypeFunctionsMap(interpreter::tokens::AnnotatedType* node) { +std::unordered_map // TODO: optimize, cache + GlobalInfo::GetAnnotatedTypeFunctionsMap(interpreter::tokens::AnnotatedType* node, + const interpreter::tokens::BaseNode& base_node) { - std::unordered_map functions; + std::unordered_map functions; for (auto& typeclass : node->typeclasses) { utils::IdType graph_id = typeclasses_[typeclass->typeclass_id_].graph_id_; auto requirements = typeclass_graph_.GetTypeclassFunctions(graph_id); for (auto& requirement : requirements) { - functions[requirement.first] = requirement.second; + auto requirement_iter = functions.find(requirement.first); + if (requirement_iter == functions.end()) { + functions[requirement.first] = *requirement.second; + } else { + if (requirement_iter->second.definition.has_value()) { + if (requirement.second->definition.has_value()) { + error_handling::HandleTypecheckError("Function defined more then in one type requirement", base_node); + } + } else { + requirement_iter->second.definition = requirement.second->definition; + } + } } } return functions; } -std::vector> - GlobalInfo::GetAnnotatedTypeFunctionsVector(interpreter::tokens::AnnotatedType* node) { +std::vector> // TODO: optimize, cache + GlobalInfo::GetAnnotatedTypeFunctionsVector(interpreter::tokens::AnnotatedType* node, + const interpreter::tokens::BaseNode& base_node) { - std::unordered_map functions_set = GetAnnotatedTypeFunctionsMap(node); + auto functions_set = GetAnnotatedTypeFunctionsMap(node, base_node); - std::vector> functions_vector; + std::vector> functions_vector; functions_vector.reserve(functions_vector.size()); for (auto& typeclass : functions_set) { functions_vector.push_back(typeclass); diff --git a/src/type_check_visitor.cpp b/src/type_check_visitor.cpp index a184dd9..3cdee93 100644 --- a/src/type_check_visitor.cpp +++ b/src/type_check_visitor.cpp @@ -269,18 +269,18 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) { void TypeCheckVisitor::Visit(TypeDefinitionStatement* node) { is_in_statement_ = true; - std::unordered_map required_functions = - global_info_.GetAnnotatedTypeFunctionsMap(node->definition->type.get()); + std::unordered_map required_functions = + global_info_.GetAnnotatedTypeFunctionsMap(node->definition->type.get(), node->base); std::string& type_name = node->definition->type->type; for (auto& function : required_functions) { // TODO: optimize - if (function.second->definition.has_value()) { // TODO: check + if (function.second.definition.has_value()) { // TODO: check continue; } std::unordered_map* current_namespaces = - global_info_.ChooseNamespaces(function.second->modifier, namespace_visitor_.GetCurrentNamespace()); + global_info_.ChooseNamespaces(function.second.modifier, namespace_visitor_.GetCurrentNamespace()); auto& type_functions = global_info_.GetNamespaceInfo((*current_namespaces)[type_name]).functions; diff --git a/src/types.cpp b/src/types.cpp index 6ffcc6c..2e449f9 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -320,27 +320,27 @@ std::optional Type::InContext(const std::unordered_map(type_).InContext(context); - case 1: - return std::get(type_).InContext(context); - case 2: - return std::nullopt; - case 3: - return std::get(type_).InContext(context); - case 4: - return std::get(type_).InContext(context); - case 5: - return std::get(type_).InContext(context); - case 6: - return std::get(type_).InContext(context); - case 7: - return std::get(type_).InContext(context); - case 8: - return std::get(type_).InContext(context); - default: - // error - break; + case 0: + return std::get(type_).InContext(context); + case 1: + return std::get(type_).InContext(context); + case 2: + return std::nullopt; + case 3: + return std::get(type_).InContext(context); + case 4: + return std::get(type_).InContext(context); + case 5: + return std::get(type_).InContext(context); + case 6: + return std::get(type_).InContext(context); + case 7: + return std::get(type_).InContext(context); + case 8: + return std::get(type_).InContext(context); + default: + // error + break; } return std::nullopt; @@ -352,27 +352,27 @@ bool Type::Same(const Type& type) const { if (this_index == type_index) { switch (this_index) { - case 0: - return std::get(type_).Same(std::get(type.type_)); - case 1: - return std::get(type_).Same(std::get(type.type_)); - case 2: - return std::get(type_) == std::get(type.type_); - case 3: - return std::get(type_).Same(std::get(type.type_)); - case 4: - return std::get(type_).Same(std::get(type.type_)); - case 5: - return std::get(type_).Same(std::get(type.type_)); - case 6: - return std::get(type_).Same(std::get(type.type_)); - case 7: - return std::get(type_).Same(std::get(type.type_)); - case 8: - return std::get(type_).Same(std::get(type.type_)); - default: - // error - break; + case 0: + return std::get(type_).Same(std::get(type.type_)); + case 1: + return std::get(type_).Same(std::get(type.type_)); + case 2: + return std::get(type_) == std::get(type.type_); + case 3: + return std::get(type_).Same(std::get(type.type_)); + case 4: + return std::get(type_).Same(std::get(type.type_)); + case 5: + return std::get(type_).Same(std::get(type.type_)); + case 6: + return std::get(type_).Same(std::get(type.type_)); + case 7: + return std::get(type_).Same(std::get(type.type_)); + case 8: + return std::get(type_).Same(std::get(type.type_)); + default: + // error + break; } } @@ -385,27 +385,27 @@ bool Type::operator<(const Type& type) const { if (this_index == type_index) { switch (this_index) { - case 0: - return std::get(type_) < std::get(type.type_); - case 1: - return std::get(type_) < std::get(type.type_); - case 2: - return std::get(type_) == std::get(type.type_); - case 3: - return std::get(type_) < std::get(type.type_); - case 4: - return std::get(type_) < std::get(type.type_); - case 5: - return std::get(type_) < std::get(type.type_); - case 6: - return std::get(type_) < std::get(type.type_); - case 7: - return std::get(type_) < std::get(type.type_); - case 8: - return std::get(type_) < std::get(type.type_); - default: - // error - break; + case 0: + return std::get(type_) < std::get(type.type_); + case 1: + return std::get(type_) < std::get(type.type_); + case 2: + return std::get(type_) == std::get(type.type_); + case 3: + return std::get(type_) < std::get(type.type_); + case 4: + return std::get(type_) < std::get(type.type_); + case 5: + return std::get(type_) < std::get(type.type_); + case 6: + return std::get(type_) < std::get(type.type_); + case 7: + return std::get(type_) < std::get(type.type_); + case 8: + return std::get(type_) < std::get(type.type_); + default: + // error + break; } } @@ -421,27 +421,27 @@ std::optional Type::GetFieldType(const std::string& name, size_t index = type_.index(); switch (index) { - case 0: - return std::get(type_).GetFieldType(name, type_namespaces); - case 1: - return std::get(type_).GetFieldType(name, type_namespaces); - case 2: - return std::nullopt; - case 3: - return std::get(type_).GetFieldType(name, type_namespaces); - case 4: - return std::get(type_).GetFieldType(name, type_namespaces); - case 5: - return std::get(type_).GetFieldType(name, type_namespaces); - case 6: - return std::get(type_).GetFieldType(name, type_namespaces); - case 7: - return std::get(type_).GetFieldType(name, type_namespaces); - case 8: - return std::get(type_).GetFieldType(name, type_namespaces); - default: - // error - break; + case 0: + return std::get(type_).GetFieldType(name, type_namespaces); + case 1: + return std::get(type_).GetFieldType(name, type_namespaces); + case 2: + return std::nullopt; + case 3: + return std::get(type_).GetFieldType(name, type_namespaces); + case 4: + return std::get(type_).GetFieldType(name, type_namespaces); + case 5: + return std::get(type_).GetFieldType(name, type_namespaces); + case 6: + return std::get(type_).GetFieldType(name, type_namespaces); + case 7: + return std::get(type_).GetFieldType(name, type_namespaces); + case 8: + return std::get(type_).GetFieldType(name, type_namespaces); + default: + // error + break; } return std::nullopt; @@ -451,27 +451,27 @@ 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; + 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 ""; // ?? diff --git a/src/values.cpp b/src/values.cpp index bd30b9e..af8b4cb 100644 --- a/src/values.cpp +++ b/src/values.cpp @@ -3,13 +3,30 @@ namespace info::value { -std::optional InternalValue::GetFieldValue(const std::string& name) { +bool InternalValue::Same(const InternalValue& other_value) const { + +} + +std::optional InternalValue::GetFieldValue(const std::string& name) const { return std::nullopt; } // -std::optional TupleValue::GetFieldValue(const std::string& name) { +bool TupleValue::Same(const TupleValue& other_value) const { + // TODO: check, that type is same + if (fields.size() != other_value.fields.size()) { + return false; + } + for (size_t i = 0; i < fields.size(); ++i) { + if (!) { + return false; + } + } + return true; +} + +std::optional TupleValue::GetFieldValue(const std::string& name) const { for (size_t i = 0; i < fields.size(); ++i) { // TODO: optimize?? if (fields[i].first.has_value() && fields[i].first.value() == name) { return fields[i].second; @@ -20,57 +37,146 @@ std::optional TupleValue::GetFieldValue(const std::string& name) // -std::optional VariantValue::GetFieldValue(const std::string& name) { +bool VariantValue::Same(const VariantValue& other_value) const { + // TODO: check, that type is same + +} + +std::optional VariantValue::GetFieldValue(const std::string& name) const { return value.GetFieldValue(name); } // -std::optional ReferenceToValue::GetFieldValue(const std::string& name) { +bool ReferenceToValue::Same(const ReferenceToValue& other_value) const { + if (references.size() != other_value.references.size()) { + return false; + } + for (size_t i = 0; i < references.size(); ++i) { + if (references[i] != other_value.references[i]) { + return false; + } + } + return value_manager_->GetAnyValue(value)->Same(*value_manager_->GetAnyValue(other_value.value)); +} + +std::optional ReferenceToValue::GetFieldValue(const std::string& name) const { return value_manager_->GetAnyValue(value)->GetFieldValue(name); } // -std::optional FunctionValue::GetFieldValue(const std::string& name) { +bool FunctionValue::Same(const FunctionValue& other_value) const { + size_t this_index = function.index(); + size_t other_index = other_value.function.index(); + + if (this_index == other_index) { + switch (this_index) { + case 0: + return std::get(function) == std::get(other_value.function); + case 1: + return std::get(function) == std::get(other_value.function); + default: + // error + break; + } + } + + return false; +} + +std::optional FunctionValue::GetFieldValue(const std::string& name) const { return std::nullopt; } // -std::optional ArrayValue::GetFieldValue(const std::string& name) { +bool ArrayValue::Same(const ArrayValue& other_value) const { + if (is_constant_size != other_value.is_constant_size + || elements.size() != other_value.elements.size()) { + return false; + } + for (size_t i = 0; i < elements.size(); ++i) { + if (!value_manager_->GetAnyValue(elements[i])->Same(*value_manager_->GetAnyValue(other_value.elements[i]))) { + return false; + } + } + return true; +} + +std::optional ArrayValue::GetFieldValue(const std::string& name) const { return std::nullopt; } // -std::optional OptionalValue::GetFieldValue(const std::string& name) { +bool OptionalValue::Same(const OptionalValue& other_value) const { + if (value.has_value() != other_value.value.has_value()) { + return false; + } + if (value.has_value()) { // => other_value.value.has_value() + return value_manager_->GetAnyValue(value.value())->Same(*value_manager_->GetAnyValue(other_value.value.value())); + } + + return true; +} + +std::optional OptionalValue::GetFieldValue(const std::string& name) const { return std::nullopt; } // -std::optional Value::GetFieldValue(const std::string& name) { +bool Value::Same(const Value& other_value) const { + size_t this_index = value.index(); + size_t other_index = other_value.value.index(); + + if (this_index == other_index) { + switch (this_index) { + case 0: + return std::get(value).Same(std::get(other_value.value)); + case 1: + return std::get(value).Same(std::get(other_value.value)); + case 2: + return std::get(value).Same(std::get(other_value.value)); + case 3: + return std::get(value).Same(std::get(other_value.value)); + case 4: + return std::get(value).Same(std::get(other_value.value)); + case 5: + return std::get(value).Same(std::get(other_value.value)); + case 6: + return std::get(value).Same(std::get(other_value.value)); + default: + // error + break; + } + } + + return false; +} + +std::optional Value::GetFieldValue(const std::string& name) const { size_t index = value.index(); switch (index) { - case 0: - return std::get(value).GetFieldValue(name); - case 1: - return std::get(value).GetFieldValue(name); - case 2: - return std::get(value).GetFieldValue(name); - case 3: - return std::get(value).GetFieldValue(name); - case 4: - return std::get(value).GetFieldValue(name); - case 5: - return std::get(value).GetFieldValue(name); - case 6: - return std::get(value).GetFieldValue(name); - default: - // error - break; + case 0: + return std::get(value).GetFieldValue(name); + case 1: + return std::get(value).GetFieldValue(name); + case 2: + return std::get(value).GetFieldValue(name); + case 3: + return std::get(value).GetFieldValue(name); + case 4: + return std::get(value).GetFieldValue(name); + case 5: + return std::get(value).GetFieldValue(name); + case 6: + return std::get(value).GetFieldValue(name); + default: + // error + break; } return std::nullopt;