lang_2023/include/types.hpp

240 lines
6.9 KiB
C++
Raw Normal View History

#pragma once
#include <optional>
#include <string>
#include <variant>
#include <memory>
2023-05-02 15:18:08 +03:00
#include <unordered_set>
2023-05-03 15:03:57 +03:00
#include <unordered_map>
2023-04-17 11:14:33 +03:00
// for clangd
#include "utils.hpp"
2023-04-17 11:14:33 +03:00
namespace info::type {
2023-04-17 11:14:33 +03:00
2023-05-02 15:18:08 +03:00
// TODO: move in constructors
2023-04-17 11:14:33 +03:00
2023-05-02 15:18:08 +03:00
class TypeManager;
class AbstractType { // later will be found in context
public:
AbstractType() = default;
AbstractType(utils::AbstractTypeModifier modifier,
const std::string& name,
const std::vector<utils::IdType>& requirements) : modifier_(modifier), name_(name) {
2023-05-02 15:18:08 +03:00
for (auto& typeclass : requirements) {
requirements_.insert(typeclass);
}
}
2023-05-03 15:03:57 +03:00
std::optional<utils::IdType> InContext(const std::unordered_map<std::string, utils::IdType>& context);
2023-05-02 15:18:08 +03:00
bool Same(const AbstractType& type) const;
bool operator<(const AbstractType& type) const;
bool operator>(const AbstractType& type) const;
private:
utils::AbstractTypeModifier modifier_;
2023-05-02 15:18:08 +03:00
std::string name_;
std::unordered_set<utils::IdType> requirements_; // TODO: all typeclasses from tree
};
class DefinedType {
public:
DefinedType() = default;
DefinedType(utils::IdType type_id,
utils::IdType type,
TypeManager* type_manager)
: type_id_(type_id), type_(type), type_manager_(type_manager) {}
2023-05-03 15:03:57 +03:00
std::optional<utils::IdType> InContext(const std::unordered_map<std::string, utils::IdType>& context);
2023-05-02 15:18:08 +03:00
bool Same(const DefinedType& type) const;
bool operator<(const DefinedType& type) const;
bool operator>(const DefinedType& type) const;
2023-05-03 15:03:57 +03:00
2023-05-04 16:11:25 +03:00
utils::IdType GetTypeId() const {
2023-05-03 15:03:57 +03:00
return type_id_;
}
2023-05-04 16:11:25 +03:00
utils::IdType GetType() const {
return type_;
}
2023-05-02 15:18:08 +03:00
private:
utils::IdType type_id_; // in defined types
utils::IdType type_; // in types manager, created using context types (if specific type)
TypeManager* type_manager_ = nullptr;
2023-04-17 11:14:33 +03:00
};
enum class InternalType {
2023-05-02 15:18:08 +03:00
Float = 0,
Int = 1,
String = 2,
Char = 3,
Bool = 4,
Unit = 5,
};
2023-04-17 11:14:33 +03:00
2023-05-02 15:18:08 +03:00
class TupleType {
public:
TupleType() = default;
TupleType(const std::optional<std::string>& name,
const std::vector<std::pair<std::optional<std::string>, utils::IdType>>& fields,
TypeManager* type_manager)
: name_(name), fields_(fields), type_manager_(type_manager) {}
2023-05-03 15:03:57 +03:00
std::optional<utils::IdType> InContext(const std::unordered_map<std::string, utils::IdType>& context);
2023-05-02 15:18:08 +03:00
bool Same(const TupleType& type) const;
bool operator<(const TupleType& type) const;
bool operator>(const TupleType& type) const;
2023-05-03 15:03:57 +03:00
const std::vector<std::pair<std::optional<std::string>, utils::IdType>>& GetFields() const {
return fields_;
}
2023-05-04 16:11:25 +03:00
2023-05-02 15:18:08 +03:00
private:
std::optional<std::string> name_;
std::vector<std::pair<std::optional<std::string>, utils::IdType>> fields_;
TypeManager* type_manager_ = nullptr;
2023-04-17 11:14:33 +03:00
};
2023-05-02 15:18:08 +03:00
class VariantType {
public:
VariantType() = default;
VariantType(const std::optional<std::string>& name,
const std::vector<TupleType>& constructors)
: name_(name), constructors_(constructors){}
2023-05-03 15:03:57 +03:00
std::optional<utils::IdType> InContext(const std::unordered_map<std::string, utils::IdType>& context);
2023-05-02 15:18:08 +03:00
bool Same(const VariantType& type) const;
bool operator<(const VariantType& type) const;
bool operator>(const VariantType& type) const;
2023-05-03 15:03:57 +03:00
const std::vector<TupleType>& GetConstructors() const {
return constructors_;
}
2023-05-04 16:11:25 +03:00
2023-05-02 15:18:08 +03:00
private:
std::optional<std::string> name_;
std::vector<TupleType> constructors_;
};
class OptionalType {
public:
OptionalType() = default;
OptionalType(utils::IdType type,
TypeManager* type_manager)
: type_(type), type_manager_(type_manager) {}
2023-05-03 15:03:57 +03:00
std::optional<utils::IdType> InContext(const std::unordered_map<std::string, utils::IdType>& context);
2023-05-02 15:18:08 +03:00
bool Same(const OptionalType& type) const;
bool operator<(const OptionalType& type) const;
bool operator>(const OptionalType& type) const;
2023-05-04 16:11:25 +03:00
2023-05-02 15:18:08 +03:00
private:
utils::IdType type_;
TypeManager* type_manager_ = nullptr;
2023-04-17 11:14:33 +03:00
};
2023-05-02 15:18:08 +03:00
class ReferenceToType {
public:
ReferenceToType() = default;
ReferenceToType(const std::vector<utils::ReferenceModifier>& references,
2023-05-02 15:18:08 +03:00
utils::IdType type,
TypeManager* type_manager)
: references_(references), type_(type), type_manager_(type_manager) {}
2023-05-03 15:03:57 +03:00
std::optional<utils::IdType> InContext(const std::unordered_map<std::string, utils::IdType>& context);
2023-05-02 15:18:08 +03:00
bool Same(const ReferenceToType& type) const;
bool operator<(const ReferenceToType& type) const;
bool operator>(const ReferenceToType& type) const;
2023-05-04 16:11:25 +03:00
2023-05-02 15:18:08 +03:00
private:
std::vector<utils::ReferenceModifier> references_;
2023-05-02 15:18:08 +03:00
utils::IdType type_;
TypeManager* type_manager_ = nullptr;
2023-04-22 19:30:16 +03:00
};
2023-05-02 15:18:08 +03:00
/////////////////////////////
class FunctionType {
public:
FunctionType() = default;
FunctionType(const std::vector<utils::IdType>& argument_types,
utils::IdType return_type,
TypeManager* type_manager)
: argument_types_(argument_types), return_type_(return_type), type_manager_(type_manager) {}
2023-05-03 15:03:57 +03:00
std::optional<utils::IdType> InContext(const std::unordered_map<std::string, utils::IdType>& context);
2023-05-02 15:18:08 +03:00
bool Same(const FunctionType& type) const;
bool operator<(const FunctionType& type) const;
bool operator>(const FunctionType& type) const;
2023-05-04 16:11:25 +03:00
2023-05-02 15:18:08 +03:00
private:
std::vector<utils::IdType> argument_types_;
utils::IdType return_type_;
TypeManager* type_manager_ = nullptr;
};
2023-04-17 11:14:33 +03:00
2023-05-02 15:18:08 +03:00
class ArrayType {
public:
ArrayType() = default;
ArrayType(size_t size,
utils::IdType elements_type,
TypeManager* type_manager)
: size_(size), elements_type_(elements_type), type_manager_(type_manager) {}
2023-05-03 15:03:57 +03:00
std::optional<utils::IdType> InContext(const std::unordered_map<std::string, utils::IdType>& context);
2023-05-02 15:18:08 +03:00
bool Same(const ArrayType& type) const;
bool operator<(const ArrayType& type) const;
bool operator>(const ArrayType& type) const;
2023-05-03 15:03:57 +03:00
utils::IdType GetElementsType() {
return elements_type_;
}
2023-05-04 16:11:25 +03:00
2023-05-02 15:18:08 +03:00
private:
size_t size_; // = 0 for dynamic
utils::IdType elements_type_;
TypeManager* type_manager_ = nullptr;
2023-04-17 11:14:33 +03:00
};
2023-05-02 15:18:08 +03:00
class Type {
public:
template<typename T>
explicit Type(T&& type) : type_(std::forward(type)) {}
2023-05-03 15:03:57 +03:00
std::optional<utils::IdType> InContext(const std::unordered_map<std::string, utils::IdType>& context);
bool Same(const Type& type) const;
bool operator<(const Type& type) const; // TODO: rule exceptions
2023-05-02 15:18:08 +03:00
bool operator>(const Type& type) const;
2023-05-04 16:11:25 +03:00
2023-05-02 15:18:08 +03:00
private:
std::variant<AbstractType,
DefinedType,
InternalType,
TupleType,
VariantType,
ReferenceToType,
FunctionType,
ArrayType> type_;
2023-04-17 11:14:33 +03:00
};
2023-05-02 15:18:08 +03:00
class TypeManager {
public:
template<typename T>
utils::IdType AddType(const T&& type);
template<typename T>
std::optional<T*> GetType(utils::IdType type_id);
2023-05-03 15:03:57 +03:00
Type* GetAnyType(utils::IdType type_id);
2023-05-02 15:18:08 +03:00
2023-05-03 15:03:57 +03:00
bool AddTypeRequirement(utils::IdType type, utils::IdType requrement);
bool EqualTypes(utils::IdType first_type, utils::IdType second_type);
2023-05-04 16:11:25 +03:00
2023-05-02 15:18:08 +03:00
private:
std::vector<info::type::Type> types_;
};
} // namespace info::type
2023-05-02 15:18:08 +03:00