123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335 |
- #ifndef QLOW_SEM_TYPE_H
- #define QLOW_SEM_TYPE_H
- #include <variant>
- #include <memory>
- #include <string>
- #include <limits>
- namespace llvm {
- class Value;
- class Type;
- class LLVMContext;
- }
- namespace qlow::sem
- {
- struct SemanticObject;
- class Type;
-
- using TypeId = size_t;
- const TypeId NO_TYPE = std::numeric_limits<TypeId>::max();
- // forward declarations to other files
- struct Class;
- class TypeScope;
- class Context;
- }
- struct qlow::sem::SemanticObject
- {
- Context& context;
- inline SemanticObject(Context& context) :
- context{ context } {}
- virtual ~SemanticObject(void);
-
- /**
- * \brief converts the object to a readable string for debugging purposes.
- */
- virtual std::string toString(void) const;
- };
- /*
- class qlow::sem::TypeId
- {
- Context& context;
- size_t id;
- public:
- inline TypeId(Context& context, size_t id) :
- context{ context }, id{ id } {}
- inline TypeId(Context& context) :
- context{ context }, id{ std::numeric_limits<size_t>::max() } {}
- inline Context& getContext(void) const { return context; }
- inline size_t getId(void) const { return id; }
- TypeId toPointer(void) const;
- TypeId toArray(void) const;
- };
- */
- class qlow::sem::Type
- {
- friend class Context;
- public:
- enum class Kind
- {
- NATIVE,
- CLASS,
- POINTER,
- ARRAY
- };
- enum class Native
- {
- VOID,
- BOOLEAN,
- INTEGER,
- };
- private:
- std::string name;
- std::unique_ptr<TypeScope> typeScope;
- struct NativeType
- {
- Native type;
- inline bool operator==(const NativeType& other) const { return type == other.type; }
- };
- struct ClassType
- {
- Class* classType;
- inline bool operator==(const ClassType& other) const { return classType == other.classType; }
- };
- struct PointerType
- {
- TypeId targetType;
- inline bool operator==(const PointerType& other) const { return targetType == other.targetType; }
- };
- struct ArrayType
- {
- TypeId targetType;
- inline bool operator==(const ArrayType& other) const { return targetType == other.targetType; }
- };
- using Union = std::variant<NativeType, ClassType, PointerType, ArrayType>;
- Union type;
- inline Type(Context& context, Union type);
- inline Type(Context& context, Union type, std::string name);
- public:
- ~Type(void);
- Type(const Type& other) = delete;
- Type(Type&& other) = default;
- void operator = (const Type& other) = delete;
- Type& operator = (Type&& other) = default;
- Kind getKind(void) const;
- std::string asString(void) const;
- size_t hash(void) const;
- bool operator == (const Type& other) const;
- /**
- * @brief return the class of this type if it is a class type,
- * <code>nullptr</code> otherwise.
- * @post ensures that if <code>this->getKind() == Kind::CLASS</code>,
- * it will not return a <code>nullptr</code>
- */
- Class* getClass(void) const;
-
- /**
- * @brief returns the type scope of this type if the type
- * is native, <code>nullptr</code> otherwise.
- */
- const TypeScope& getTypeScope(void) const;
- llvm::Type* getLLVMType(llvm::LLVMContext* context);
- static Type createNativeType(Context& c, std::string name, Native type);
- static Type createClassType(Context& c, Class* classType);
- static Type createPointerType(Context& c, TypeId pointsTo);
- static Type createArrayType(Context& c, TypeId pointsTo);
- };
-
- #if 0
- #include "Scope.h"
- #include <memory>
- #include <string>
- namespace llvm {
- class Value;
- class Type;
- class LLVMContext;
- }
- namespace qlow
- {
- namespace sem
- {
- // forward declarations
- struct Class;
-
- class Scope;
-
- struct NativeMethod;
- }
- namespace sem
- {
- struct SemanticObject;
-
- class Type;
-
- class PointerType;
- class ClassType;
- class ArrayType;
- class NativeType;
- }
- }
- class qlow::sem::Type : public SemanticObject
- {
- public:
- virtual ~Type(void);
- /// \returns false by default
- virtual inline bool isPointerType(void) const { return false; }
-
- /// \returns false by default
- virtual inline bool isClassType(void) const { return false; }
-
- /// \returns false by default
- virtual inline bool isNativeType(void) const { return false; }
-
- /// \returns false by default
- virtual inline bool isArrayType(void) const { return false; }
- virtual std::string asString(void) const = 0;
- virtual Scope& getScope(void) = 0;
-
- virtual y = 0;
-
- virtual bool equals(const Type& other) const;
- virtual size_t hash(void) const;
-
- // static TypeId VOID;
- // static TypeId INTEGER;
- // static TypeId BOOLEAN;
- };
- class qlow::sem::PointerType : public Type
- {
- TypeId derefType;
- sem::TypeScope scope;
- public:
- inline PointerType(TypeId derefType) :
- derefType{ derefType },
- scope{ *this }
- {
- }
-
- const TypeId& getDerefType(void) const { return derefType; }
-
- inline bool isPointerType(void) const override { return true; }
-
- virtual std::string asString(void) const override;
- virtual Scope& getScope(void) override;
-
- virtual llvm::Type* getLlvmType(llvm::LLVMContext& context) const override;
-
- virtual bool equals(const Type& other) const override;
- };
- class qlow::sem::ClassType : public Type
- {
- sem::Class* classType;
- sem::TypeScope scope;
- public:
- inline ClassType(sem::Class* classType) :
- classType{ classType },
- scope{ *this }
- {
- }
-
- inline bool isClassType(void) const override { return true; }
-
- std::string asString(void) const override;
- Scope& getScope(void) override;
-
- virtual llvm::Type* getLlvmType(llvm::LLVMContext& context) const override;
- inline sem::Class* getClassType(void) { return classType; }
- virtual bool equals(const Type& other) const override;
- };
- class qlow::sem::ArrayType : public Type
- {
- std::shared_ptr<sem::Type> arrayType;
- TypeScope scope;
- public:
-
- inline ArrayType(std::shared_ptr<sem::Type> arrayType) :
- arrayType{ std::move(arrayType) },
- scope{ *this }
- {
- }
-
- inline bool isArrayType(void) const override { return true; }
-
- std::string asString(void) const override;
- Scope& getScope(void) override;
-
- virtual llvm::Type* getLlvmType(llvm::LLVMContext& context) const override;
- inline std::shared_ptr<sem::Type> getArrayType(void) { return arrayType; }
- virtual bool equals(const Type& other) const override;
- };
- class qlow::sem::NativeType : public Type
- {
- NativeTypeScope scope;
- public:
- enum Type {
- VOID,
- INTEGER,
- BOOLEAN,
- CHAR,
- STRING,
- INT8, INT16, INT32, INT64, INT128,
- UINT8, UINT16, UINT32, UINT64, UINT128,
- FLOAT32, FLOAT64, FLOAT128,
- };
-
- Type type;
-
- SymbolTable<NativeMethod> nativeMethods;
-
- inline NativeType(Type type) :
- scope{ *this },
- type{ type }
- {
- }
-
- inline bool isNativeType(void) const override { return true; }
-
- std::string asString(void) const override;
- Scope& getScope(void) override;
-
- bool isIntegerType(void) const;
-
- llvm::Type* getLlvmType(llvm::LLVMContext& context) const override;
- virtual bool equals(const sem::Type& other) const override;
-
- /// cast an llvm::Value from another native type to this one
- llvm::Value* generateImplicitCast(llvm::Value* value);
- };
- #endif
- #endif // QLOW_SEM_TYPE_H
|