This commit is contained in:
ProgramSnail 2023-05-18 01:02:54 +03:00
parent 3abac1b643
commit b901078956
6 changed files with 291 additions and 155 deletions

View file

@ -356,11 +356,13 @@ public:
std::vector<utils::IdType> std::vector<utils::IdType>
GetAnnotatedTypeTypeclassesVector(interpreter::tokens::AnnotatedType* node); GetAnnotatedTypeTypeclassesVector(interpreter::tokens::AnnotatedType* node);
std::unordered_map<std::string, TypeclassGraph::FunctionInfo*> std::unordered_map<std::string, TypeclassGraph::FunctionInfo>
GetAnnotatedTypeFunctionsMap(interpreter::tokens::AnnotatedType* node); GetAnnotatedTypeFunctionsMap(interpreter::tokens::AnnotatedType* node,
const interpreter::tokens::BaseNode& base_node);
std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo*>> std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo>>
GetAnnotatedTypeFunctionsVector(interpreter::tokens::AnnotatedType* node); GetAnnotatedTypeFunctionsVector(interpreter::tokens::AnnotatedType* node,
const interpreter::tokens::BaseNode& base_node);
std::unordered_map<std::string, utils::IdType>* ChooseNamespaces( std::unordered_map<std::string, utils::IdType>* ChooseNamespaces(
utils::ClassInternalsModifier modifier, utils::ClassInternalsModifier modifier,

View file

@ -30,7 +30,8 @@ public:
return &std::get<T>(value); return &std::get<T>(value);
} }
std::optional<utils::IdType> GetFieldValue(const std::string& name); bool Same(const InternalValue& value) const;
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
public: public:
std::variant<double, std::variant<double,
long long, long long,
@ -48,7 +49,8 @@ public:
ValueManager* value_manager) ValueManager* value_manager)
: fields(std::move(fields)), value_manager_(value_manager) {} : fields(std::move(fields)), value_manager_(value_manager) {}
std::optional<utils::IdType> GetFieldValue(const std::string& name); bool Same(const TupleValue& other_value) const;
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
public: public:
std::vector<std::pair<std::optional<std::string>, utils::IdType>> fields; std::vector<std::pair<std::optional<std::string>, utils::IdType>> fields;
@ -67,7 +69,8 @@ public:
TupleValue value; TupleValue value;
size_t current_constructor; size_t current_constructor;
std::optional<utils::IdType> GetFieldValue(const std::string& name); bool Same(const VariantValue& other_value) const;
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
}; };
struct ReferenceToValue { struct ReferenceToValue {
@ -83,7 +86,9 @@ public:
std::vector<utils::ReferenceModifier> references; std::vector<utils::ReferenceModifier> references;
utils::IdType value; utils::IdType value;
std::optional<utils::IdType> GetFieldValue(const std::string& name); bool Same(const ReferenceToValue& other_value) const;
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
private: private:
ValueManager* value_manager_ = nullptr; ValueManager* value_manager_ = nullptr;
}; };
@ -100,7 +105,9 @@ public:
std::variant<interpreter::tokens::FunctionDeclaration*, std::variant<interpreter::tokens::FunctionDeclaration*,
interpreter::tokens::LambdaFunction*> function; interpreter::tokens::LambdaFunction*> function;
std::optional<utils::IdType> GetFieldValue(const std::string& name); bool Same(const FunctionValue& other_value) const;
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
private: private:
ValueManager* value_manager_ = nullptr; ValueManager* value_manager_ = nullptr;
}; };
@ -119,7 +126,9 @@ public:
std::vector<utils::IdType> elements; std::vector<utils::IdType> elements;
bool is_constant_size = false; bool is_constant_size = false;
std::optional<utils::IdType> GetFieldValue(const std::string& name); bool Same(const ArrayValue& other_value) const;
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
private: private:
ValueManager* value_manager_ = nullptr; ValueManager* value_manager_ = nullptr;
}; };
@ -131,7 +140,9 @@ public:
OptionalValue(std::optional<utils::IdType> value, ValueManager* value_manager) OptionalValue(std::optional<utils::IdType> value, ValueManager* value_manager)
: value(value), value_manager_(value_manager) {} : value(value), value_manager_(value_manager) {}
std::optional<utils::IdType> GetFieldValue(const std::string& name); bool Same(const OptionalValue& other_value) const;
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
public: public:
std::optional<utils::IdType> value; std::optional<utils::IdType> value;
@ -146,7 +157,9 @@ public:
template<typename T> template<typename T>
explicit Value(const T& value) : value(value) {} // move ?? explicit Value(const T& value) : value(value) {} // move ??
std::optional<utils::IdType> GetFieldValue(const std::string& name); bool Same(const Value& other_value) const;
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
public: public:
std::variant<InternalValue, std::variant<InternalValue,
TupleValue, TupleValue,
@ -186,7 +199,9 @@ public:
return values_.at(value_id).second; return values_.at(value_id).second;
} }
bool EqualValues(utils::IdType first_value, utils::IdType second_value) = delete; // TODO bool EqualValues(utils::IdType first_value, utils::IdType second_value) {
return GetAnyValue(first_value)->Same(*GetAnyValue(second_value));
}
bool AddValueRequirement(utils::IdType value, utils::IdType requrement) = delete; bool AddValueRequirement(utils::IdType value, utils::IdType requrement) = delete;

View file

@ -492,28 +492,41 @@ std::vector<utils::IdType>
return typeclasses_vector; return typeclasses_vector;
} }
std::unordered_map<std::string, TypeclassGraph::FunctionInfo*> std::unordered_map<std::string, TypeclassGraph::FunctionInfo> // TODO: optimize, cache
GlobalInfo::GetAnnotatedTypeFunctionsMap(interpreter::tokens::AnnotatedType* node) { GlobalInfo::GetAnnotatedTypeFunctionsMap(interpreter::tokens::AnnotatedType* node,
const interpreter::tokens::BaseNode& base_node) {
std::unordered_map<std::string, TypeclassGraph::FunctionInfo*> functions; std::unordered_map<std::string, TypeclassGraph::FunctionInfo> functions;
for (auto& typeclass : node->typeclasses) { for (auto& typeclass : node->typeclasses) {
utils::IdType graph_id = typeclasses_[typeclass->typeclass_id_].graph_id_; utils::IdType graph_id = typeclasses_[typeclass->typeclass_id_].graph_id_;
auto requirements = typeclass_graph_.GetTypeclassFunctions(graph_id); auto requirements = typeclass_graph_.GetTypeclassFunctions(graph_id);
for (auto& requirement : requirements) { 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; return functions;
} }
std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo*>> std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo>> // TODO: optimize, cache
GlobalInfo::GetAnnotatedTypeFunctionsVector(interpreter::tokens::AnnotatedType* node) { GlobalInfo::GetAnnotatedTypeFunctionsVector(interpreter::tokens::AnnotatedType* node,
const interpreter::tokens::BaseNode& base_node) {
std::unordered_map<std::string, TypeclassGraph::FunctionInfo*> functions_set = GetAnnotatedTypeFunctionsMap(node); auto functions_set = GetAnnotatedTypeFunctionsMap(node, base_node);
std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo*>> functions_vector; std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo>> functions_vector;
functions_vector.reserve(functions_vector.size()); functions_vector.reserve(functions_vector.size());
for (auto& typeclass : functions_set) { for (auto& typeclass : functions_set) {
functions_vector.push_back(typeclass); functions_vector.push_back(typeclass);

View file

@ -269,18 +269,18 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) {
void TypeCheckVisitor::Visit(TypeDefinitionStatement* node) { void TypeCheckVisitor::Visit(TypeDefinitionStatement* node) {
is_in_statement_ = true; is_in_statement_ = true;
std::unordered_map<std::string, info::TypeclassGraph::FunctionInfo*> required_functions = std::unordered_map<std::string, info::TypeclassGraph::FunctionInfo> required_functions =
global_info_.GetAnnotatedTypeFunctionsMap(node->definition->type.get()); global_info_.GetAnnotatedTypeFunctionsMap(node->definition->type.get(), node->base);
std::string& type_name = node->definition->type->type; std::string& type_name = node->definition->type->type;
for (auto& function : required_functions) { // TODO: optimize for (auto& function : required_functions) { // TODO: optimize
if (function.second->definition.has_value()) { // TODO: check if (function.second.definition.has_value()) { // TODO: check
continue; continue;
} }
std::unordered_map<std::string, utils::IdType>* current_namespaces = std::unordered_map<std::string, utils::IdType>* 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; auto& type_functions = global_info_.GetNamespaceInfo((*current_namespaces)[type_name]).functions;

View file

@ -320,27 +320,27 @@ std::optional<utils::IdType> Type::InContext(const std::unordered_map<std::strin
size_t this_index = type_.index(); size_t this_index = type_.index();
switch (this_index) { switch (this_index) {
case 0: case 0:
return std::get<AbstractType>(type_).InContext(context); return std::get<AbstractType>(type_).InContext(context);
case 1: case 1:
return std::get<DefinedType>(type_).InContext(context); return std::get<DefinedType>(type_).InContext(context);
case 2: case 2:
return std::nullopt; return std::nullopt;
case 3: case 3:
return std::get<TupleType>(type_).InContext(context); return std::get<TupleType>(type_).InContext(context);
case 4: case 4:
return std::get<VariantType>(type_).InContext(context); return std::get<VariantType>(type_).InContext(context);
case 5: case 5:
return std::get<ReferenceToType>(type_).InContext(context); return std::get<ReferenceToType>(type_).InContext(context);
case 6: case 6:
return std::get<FunctionType>(type_).InContext(context); return std::get<FunctionType>(type_).InContext(context);
case 7: case 7:
return std::get<ArrayType>(type_).InContext(context); return std::get<ArrayType>(type_).InContext(context);
case 8: case 8:
return std::get<OptionalType>(type_).InContext(context); return std::get<OptionalType>(type_).InContext(context);
default: default:
// error // error
break; break;
} }
return std::nullopt; return std::nullopt;
@ -352,27 +352,27 @@ bool Type::Same(const Type& type) const {
if (this_index == type_index) { if (this_index == type_index) {
switch (this_index) { switch (this_index) {
case 0: case 0:
return std::get<AbstractType>(type_).Same(std::get<AbstractType>(type.type_)); return std::get<AbstractType>(type_).Same(std::get<AbstractType>(type.type_));
case 1: case 1:
return std::get<DefinedType>(type_).Same(std::get<DefinedType>(type.type_)); return std::get<DefinedType>(type_).Same(std::get<DefinedType>(type.type_));
case 2: case 2:
return std::get<InternalType>(type_) == std::get<InternalType>(type.type_); return std::get<InternalType>(type_) == std::get<InternalType>(type.type_);
case 3: case 3:
return std::get<TupleType>(type_).Same(std::get<TupleType>(type.type_)); return std::get<TupleType>(type_).Same(std::get<TupleType>(type.type_));
case 4: case 4:
return std::get<VariantType>(type_).Same(std::get<VariantType>(type.type_)); return std::get<VariantType>(type_).Same(std::get<VariantType>(type.type_));
case 5: case 5:
return std::get<ReferenceToType>(type_).Same(std::get<ReferenceToType>(type.type_)); return std::get<ReferenceToType>(type_).Same(std::get<ReferenceToType>(type.type_));
case 6: case 6:
return std::get<FunctionType>(type_).Same(std::get<FunctionType>(type.type_)); return std::get<FunctionType>(type_).Same(std::get<FunctionType>(type.type_));
case 7: case 7:
return std::get<ArrayType>(type_).Same(std::get<ArrayType>(type.type_)); return std::get<ArrayType>(type_).Same(std::get<ArrayType>(type.type_));
case 8: case 8:
return std::get<OptionalType>(type_).Same(std::get<OptionalType>(type.type_)); return std::get<OptionalType>(type_).Same(std::get<OptionalType>(type.type_));
default: default:
// error // error
break; break;
} }
} }
@ -385,27 +385,27 @@ bool Type::operator<(const Type& type) const {
if (this_index == type_index) { if (this_index == type_index) {
switch (this_index) { switch (this_index) {
case 0: case 0:
return std::get<AbstractType>(type_) < std::get<AbstractType>(type.type_); return std::get<AbstractType>(type_) < std::get<AbstractType>(type.type_);
case 1: case 1:
return std::get<DefinedType>(type_) < std::get<DefinedType>(type.type_); return std::get<DefinedType>(type_) < std::get<DefinedType>(type.type_);
case 2: case 2:
return std::get<InternalType>(type_) == std::get<InternalType>(type.type_); return std::get<InternalType>(type_) == std::get<InternalType>(type.type_);
case 3: case 3:
return std::get<TupleType>(type_) < std::get<TupleType>(type.type_); return std::get<TupleType>(type_) < std::get<TupleType>(type.type_);
case 4: case 4:
return std::get<VariantType>(type_) < std::get<VariantType>(type.type_); return std::get<VariantType>(type_) < std::get<VariantType>(type.type_);
case 5: case 5:
return std::get<ReferenceToType>(type_) < std::get<ReferenceToType>(type.type_); return std::get<ReferenceToType>(type_) < std::get<ReferenceToType>(type.type_);
case 6: case 6:
return std::get<FunctionType>(type_) < std::get<FunctionType>(type.type_); return std::get<FunctionType>(type_) < std::get<FunctionType>(type.type_);
case 7: case 7:
return std::get<ArrayType>(type_) < std::get<ArrayType>(type.type_); return std::get<ArrayType>(type_) < std::get<ArrayType>(type.type_);
case 8: case 8:
return std::get<OptionalType>(type_) < std::get<OptionalType>(type.type_); return std::get<OptionalType>(type_) < std::get<OptionalType>(type.type_);
default: default:
// error // error
break; break;
} }
} }
@ -421,27 +421,27 @@ std::optional<utils::IdType> Type::GetFieldType(const std::string& name,
size_t index = type_.index(); size_t index = type_.index();
switch (index) { switch (index) {
case 0: case 0:
return std::get<AbstractType>(type_).GetFieldType(name, type_namespaces); return std::get<AbstractType>(type_).GetFieldType(name, type_namespaces);
case 1: case 1:
return std::get<DefinedType>(type_).GetFieldType(name, type_namespaces); return std::get<DefinedType>(type_).GetFieldType(name, type_namespaces);
case 2: case 2:
return std::nullopt; return std::nullopt;
case 3: case 3:
return std::get<TupleType>(type_).GetFieldType(name, type_namespaces); return std::get<TupleType>(type_).GetFieldType(name, type_namespaces);
case 4: case 4:
return std::get<VariantType>(type_).GetFieldType(name, type_namespaces); return std::get<VariantType>(type_).GetFieldType(name, type_namespaces);
case 5: case 5:
return std::get<ReferenceToType>(type_).GetFieldType(name, type_namespaces); return std::get<ReferenceToType>(type_).GetFieldType(name, type_namespaces);
case 6: case 6:
return std::get<FunctionType>(type_).GetFieldType(name, type_namespaces); return std::get<FunctionType>(type_).GetFieldType(name, type_namespaces);
case 7: case 7:
return std::get<ArrayType>(type_).GetFieldType(name, type_namespaces); return std::get<ArrayType>(type_).GetFieldType(name, type_namespaces);
case 8: case 8:
return std::get<OptionalType>(type_).GetFieldType(name, type_namespaces); return std::get<OptionalType>(type_).GetFieldType(name, type_namespaces);
default: default:
// error // error
break; break;
} }
return std::nullopt; return std::nullopt;
@ -451,27 +451,27 @@ std::string Type::GetTypeName() const {
size_t index = type_.index(); size_t index = type_.index();
switch (index) { switch (index) {
case 0: case 0:
return "AbstractType"; return "AbstractType";
case 1: case 1:
return "DefinedType"; return "DefinedType";
case 2: case 2:
return "Builtin"; return "Builtin";
case 3: case 3:
return "TupleType"; return "TupleType";
case 4: case 4:
return "VariantType"; return "VariantType";
case 5: case 5:
return "ReferenceToType"; return "ReferenceToType";
case 6: case 6:
return "FunctionType"; return "FunctionType";
case 7: case 7:
return "ArrayType"; return "ArrayType";
case 8: case 8:
return "OptionalType"; return "OptionalType";
default: default:
// error // error
break; break;
} }
return ""; // ?? return ""; // ??

View file

@ -3,13 +3,30 @@
namespace info::value { namespace info::value {
std::optional<utils::IdType> InternalValue::GetFieldValue(const std::string& name) { bool InternalValue::Same(const InternalValue& other_value) const {
}
std::optional<utils::IdType> InternalValue::GetFieldValue(const std::string& name) const {
return std::nullopt; return std::nullopt;
} }
// //
std::optional<utils::IdType> 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<utils::IdType> TupleValue::GetFieldValue(const std::string& name) const {
for (size_t i = 0; i < fields.size(); ++i) { // TODO: optimize?? for (size_t i = 0; i < fields.size(); ++i) { // TODO: optimize??
if (fields[i].first.has_value() && fields[i].first.value() == name) { if (fields[i].first.has_value() && fields[i].first.value() == name) {
return fields[i].second; return fields[i].second;
@ -20,57 +37,146 @@ std::optional<utils::IdType> TupleValue::GetFieldValue(const std::string& name)
// //
std::optional<utils::IdType> VariantValue::GetFieldValue(const std::string& name) { bool VariantValue::Same(const VariantValue& other_value) const {
// TODO: check, that type is same
}
std::optional<utils::IdType> VariantValue::GetFieldValue(const std::string& name) const {
return value.GetFieldValue(name); return value.GetFieldValue(name);
} }
// //
std::optional<utils::IdType> 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<utils::IdType> ReferenceToValue::GetFieldValue(const std::string& name) const {
return value_manager_->GetAnyValue(value)->GetFieldValue(name); return value_manager_->GetAnyValue(value)->GetFieldValue(name);
} }
// //
std::optional<utils::IdType> 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<interpreter::tokens::FunctionDeclaration*>(function) == std::get<interpreter::tokens::FunctionDeclaration*>(other_value.function);
case 1:
return std::get<interpreter::tokens::LambdaFunction*>(function) == std::get<interpreter::tokens::LambdaFunction*>(other_value.function);
default:
// error
break;
}
}
return false;
}
std::optional<utils::IdType> FunctionValue::GetFieldValue(const std::string& name) const {
return std::nullopt; return std::nullopt;
} }
// //
std::optional<utils::IdType> 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<utils::IdType> ArrayValue::GetFieldValue(const std::string& name) const {
return std::nullopt; return std::nullopt;
} }
// //
std::optional<utils::IdType> 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<utils::IdType> OptionalValue::GetFieldValue(const std::string& name) const {
return std::nullopt; return std::nullopt;
} }
// //
std::optional<utils::IdType> 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<InternalValue>(value).Same(std::get<InternalValue>(other_value.value));
case 1:
return std::get<TupleValue>(value).Same(std::get<TupleValue>(other_value.value));
case 2:
return std::get<VariantValue>(value).Same(std::get<VariantValue>(other_value.value));
case 3:
return std::get<ReferenceToValue>(value).Same(std::get<ReferenceToValue>(other_value.value));
case 4:
return std::get<FunctionValue>(value).Same(std::get<FunctionValue>(other_value.value));
case 5:
return std::get<ArrayValue>(value).Same(std::get<ArrayValue>(other_value.value));
case 6:
return std::get<OptionalValue>(value).Same(std::get<OptionalValue>(other_value.value));
default:
// error
break;
}
}
return false;
}
std::optional<utils::IdType> Value::GetFieldValue(const std::string& name) const {
size_t index = value.index(); size_t index = value.index();
switch (index) { switch (index) {
case 0: case 0:
return std::get<InternalValue>(value).GetFieldValue(name); return std::get<InternalValue>(value).GetFieldValue(name);
case 1: case 1:
return std::get<TupleValue>(value).GetFieldValue(name); return std::get<TupleValue>(value).GetFieldValue(name);
case 2: case 2:
return std::get<VariantValue>(value).GetFieldValue(name); return std::get<VariantValue>(value).GetFieldValue(name);
case 3: case 3:
return std::get<ReferenceToValue>(value).GetFieldValue(name); return std::get<ReferenceToValue>(value).GetFieldValue(name);
case 4: case 4:
return std::get<FunctionValue>(value).GetFieldValue(name); return std::get<FunctionValue>(value).GetFieldValue(name);
case 5: case 5:
return std::get<ArrayValue>(value).GetFieldValue(name); return std::get<ArrayValue>(value).GetFieldValue(name);
case 6: case 6:
return std::get<OptionalValue>(value).GetFieldValue(name); return std::get<OptionalValue>(value).GetFieldValue(name);
default: default:
// error // error
break; break;
} }
return std::nullopt; return std::nullopt;