type structs -> type classes

This commit is contained in:
ProgramSnail 2023-05-02 15:18:08 +03:00
parent a512a92f92
commit 648f78afa3
14 changed files with 638 additions and 383 deletions

275
src/types.cpp Normal file
View file

@ -0,0 +1,275 @@
// for clangd
#include "../include/types.hpp"
namespace info::type {
bool AbstractType::Same(const AbstractType& type) const {
return name_ == type.name_;
}
bool AbstractType::operator<(const AbstractType& type) const {
for (auto& typeclass : requirements_) {
if (type.requirements_.count(typeclass) == 0) {
return false;
}
}
return true;
}
bool AbstractType::operator>(const AbstractType& type) const {
return type < *this;
}
//
bool DefinedType::Same(const DefinedType& type) const {
return type_id_ == type.type_id_
&& type_manager_->GetAnyType(type_).value()->Same(*type_manager_->GetAnyType(type.type_).value());
}
bool DefinedType::operator<(const DefinedType& type) const {
return type_id_ == type.type_id_
&& *type_manager_->GetAnyType(type_).value() < *type_manager_->GetAnyType(type.type_).value();
}
bool DefinedType::operator>(const DefinedType& type) const {
return type < *this;
}
//
bool TupleType::Same(const TupleType& type) const {
if (fields_.size() != type.fields_.size()) {
return false;
}
for (size_t i = 0; i < fields_.size(); ++i) {
if (!type_manager_->GetAnyType(fields_[i].second).value()->Same(*type_manager_->GetAnyType(type.fields_[i].second).value())) {
return false;
}
}
return true;
}
bool TupleType::operator<(const TupleType& type) const {
if (fields_.size() != type.fields_.size()) {
return false;
}
for (size_t i = 0; i < fields_.size(); ++i) {
if (!(*type_manager_->GetAnyType(fields_[i].second).value() < *type_manager_->GetAnyType(type.fields_[i].second).value())) {
return false;
}
}
return true;
}
bool TupleType::operator>(const TupleType& type) const {
return type < *this;
}
//
bool VariantType::Same(const VariantType& type) const {
if (constructors_.size() != type.constructors_.size()) {
return false;
}
for (size_t i = 0; i < constructors_.size(); ++i) {
if (!constructors_[i].Same(constructors_[i])) {
return false;
}
}
return true;
}
bool VariantType::operator<(const VariantType& type) const {
if (constructors_.size() != type.constructors_.size()) {
return false;
}
for (size_t i = 0; i < constructors_.size(); ++i) {
if (!(constructors_[i] < constructors_[i])) {
return false;
}
}
return true;
}
bool VariantType::operator>(const VariantType& type) const {
return type < *this;
}
//
bool OptionalType::Same(const OptionalType& type) const {
return type_manager_->GetAnyType(type_).value()->Same(*type_manager_->GetAnyType(type.type_).value());
}
bool OptionalType::operator<(const OptionalType& type) const {
return *type_manager_->GetAnyType(type_).value() < *type_manager_->GetAnyType(type.type_).value();
}
bool OptionalType::operator>(const OptionalType& type) const {
return type < *this;
}
//
bool ReferenceToType::Same(const ReferenceToType& type) const {
return references_ == type.references_ && type_manager_->GetAnyType(type_).value()->Same(*type_manager_->GetAnyType(type.type_).value());
}
bool ReferenceToType::operator<(const ReferenceToType& type) const {
return references_ == type.references_ && *type_manager_->GetAnyType(type_).value() < *type_manager_->GetAnyType(type.type_).value();
}
bool ReferenceToType::operator>(const ReferenceToType& type) const {
return type < *this;
}
//
bool FunctionType::Same(const FunctionType& type) const {
if (argument_types_.size() != type.argument_types_.size()) {
return false;
}
for (size_t i = 0; i < argument_types_.size(); ++i) {
if (!type_manager_->GetAnyType(argument_types_[i]).value()->Same(*type_manager_->GetAnyType(type.argument_types_[i]).value())) {
return false;
}
}
return true;
}
bool FunctionType::operator<(const FunctionType& type) const {
if (argument_types_.size() != type.argument_types_.size()) {
return false;
}
for (size_t i = 0; i < argument_types_.size(); ++i) {
if (!(*type_manager_->GetAnyType(argument_types_[i]).value() < *type_manager_->GetAnyType(type.argument_types_[i]).value())) {
return false;
}
}
return true;
}
bool FunctionType::operator>(const FunctionType& type) const {
return type < *this;
}
//
bool ArrayType::Same(const ArrayType& type) const {
return size_ == type.size_ && type_manager_->GetAnyType(elements_type_).value()->Same(*type_manager_->GetAnyType(type.elements_type_).value());
}
bool ArrayType::operator<(const ArrayType& type) const {
return size_ == type.size_ && *type_manager_->GetAnyType(elements_type_).value() < *type_manager_->GetAnyType(type.elements_type_).value();
}
bool ArrayType::operator>(const ArrayType& type) const {
return type < *this;
}
//
bool Type::Same(const Type& type) const {
size_t this_index = type_.index();
size_t type_index = type.type_.index();
if (this_index == type_index) {
switch (this_index) {
case 0:
return std::get<AbstractType>(type_).Same(std::get<AbstractType>(type.type_));
case 1:
return std::get<DefinedType>(type_).Same(std::get<DefinedType>(type.type_));
case 2:
return std::get<InternalType>(type_) == std::get<InternalType>(type.type_);
case 3:
return std::get<TupleType>(type_).Same(std::get<TupleType>(type.type_));
case 4:
return std::get<VariantType>(type_).Same(std::get<VariantType>(type.type_));
case 5:
return std::get<ReferenceToType>(type_).Same(std::get<ReferenceToType>(type.type_));
case 6:
return std::get<FunctionType>(type_).Same(std::get<FunctionType>(type.type_));
case 7:
return std::get<ArrayType>(type_).Same(std::get<ArrayType>(type.type_));
default:
// error
break;
}
}
return false;
} // some rule exceptions ??
bool Type::operator<(const Type& type) const {
size_t this_index = type_.index();
size_t type_index = type.type_.index();
if (this_index == type_index) {
switch (this_index) {
case 0:
return std::get<AbstractType>(type_) < std::get<AbstractType>(type.type_);
case 1:
return std::get<DefinedType>(type_) < std::get<DefinedType>(type.type_);
case 2:
return std::get<InternalType>(type_) == std::get<InternalType>(type.type_);
case 3:
return std::get<TupleType>(type_) < std::get<TupleType>(type.type_);
case 4:
return std::get<VariantType>(type_) < std::get<VariantType>(type.type_);
case 5:
return std::get<ReferenceToType>(type_) < std::get<ReferenceToType>(type.type_);
case 6:
return std::get<FunctionType>(type_) < std::get<FunctionType>(type.type_);
case 7:
return std::get<ArrayType>(type_) < std::get<ArrayType>(type.type_);
default:
// error
break;
}
}
return false;
} // TODO: some rule exceptions ??
bool Type::operator>(const Type& type) const {
return type < *this;
}
//
template<typename T>
utils::IdType TypeManager::AddType(const T&& type) {
types_.emplace_back(std::forward(type));
return types_.size() - 1;
}
template<typename T>
std::optional<T*> TypeManager::GetType(utils::IdType type_id) {
if (!std::holds_alternative<T>(types_.at(type_id))) {
return std::nullopt;
}
return &std::get<T>(types_.at(type_id));
}
std::optional<Type*> TypeManager::GetAnyType(utils::IdType type_id) {
return &types_.at(type_id);
}
void TypeManager::AddTypeRequirement(utils::IdType type, utils::IdType requrement) {} // TODO
void TypeManager::EqualTypes(utils::IdType first_type, utils::IdType second_type) {} // TODO
} // namespace info::type