Type.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. #ifndef QLOW_SEM_TYPE_H
  2. #define QLOW_SEM_TYPE_H
  3. #include <variant>
  4. #include <memory>
  5. #include <string>
  6. #include <limits>
  7. namespace llvm {
  8. class Value;
  9. class Type;
  10. class LLVMContext;
  11. }
  12. namespace qlow::sem
  13. {
  14. struct SemanticObject;
  15. class Type;
  16. using TypeId = size_t;
  17. const TypeId NO_TYPE = std::numeric_limits<TypeId>::max();
  18. // forward declarations to other files
  19. struct Class;
  20. class TypeScope;
  21. class Context;
  22. }
  23. struct qlow::sem::SemanticObject
  24. {
  25. Context& context;
  26. inline SemanticObject(Context& context) :
  27. context{ context } {}
  28. virtual ~SemanticObject(void);
  29. /**
  30. * \brief converts the object to a readable string for debugging purposes.
  31. */
  32. virtual std::string toString(void) const;
  33. };
  34. /*
  35. class qlow::sem::TypeId
  36. {
  37. Context& context;
  38. size_t id;
  39. public:
  40. inline TypeId(Context& context, size_t id) :
  41. context{ context }, id{ id } {}
  42. inline TypeId(Context& context) :
  43. context{ context }, id{ std::numeric_limits<size_t>::max() } {}
  44. inline Context& getContext(void) const { return context; }
  45. inline size_t getId(void) const { return id; }
  46. TypeId toPointer(void) const;
  47. TypeId toArray(void) const;
  48. };
  49. */
  50. class qlow::sem::Type
  51. {
  52. friend class Context;
  53. public:
  54. enum class Kind
  55. {
  56. NATIVE,
  57. CLASS,
  58. POINTER,
  59. ARRAY
  60. };
  61. enum class Native
  62. {
  63. VOID,
  64. BOOLEAN,
  65. INTEGER,
  66. };
  67. private:
  68. std::string name;
  69. std::unique_ptr<TypeScope> typeScope;
  70. struct NativeType
  71. {
  72. Native type;
  73. inline bool operator==(const NativeType& other) const { return type == other.type; }
  74. };
  75. struct ClassType
  76. {
  77. Class* classType;
  78. inline bool operator==(const ClassType& other) const { return classType == other.classType; }
  79. };
  80. struct PointerType
  81. {
  82. TypeId targetType;
  83. inline bool operator==(const PointerType& other) const { return targetType == other.targetType; }
  84. };
  85. struct ArrayType
  86. {
  87. TypeId targetType;
  88. inline bool operator==(const ArrayType& other) const { return targetType == other.targetType; }
  89. };
  90. using Union = std::variant<NativeType, ClassType, PointerType, ArrayType>;
  91. Union type;
  92. inline Type(Context& context, Union type);
  93. inline Type(Context& context, Union type, std::string name);
  94. public:
  95. ~Type(void);
  96. Type(const Type& other) = delete;
  97. Type(Type&& other) = default;
  98. void operator = (const Type& other) = delete;
  99. Type& operator = (Type&& other) = default;
  100. Kind getKind(void) const;
  101. std::string asString(void) const;
  102. size_t hash(void) const;
  103. bool operator == (const Type& other) const;
  104. /**
  105. * @brief return the class of this type if it is a class type,
  106. * <code>nullptr</code> otherwise.
  107. * @post ensures that if <code>this->getKind() == Kind::CLASS</code>,
  108. * it will not return a <code>nullptr</code>
  109. */
  110. Class* getClass(void) const;
  111. /**
  112. * @brief returns the type scope of this type if the type
  113. * is native, <code>nullptr</code> otherwise.
  114. */
  115. const TypeScope& getTypeScope(void) const;
  116. llvm::Type* getLLVMType(llvm::LLVMContext* context);
  117. static Type createNativeType(Context& c, std::string name, Native type);
  118. static Type createClassType(Context& c, Class* classType);
  119. static Type createPointerType(Context& c, TypeId pointsTo);
  120. static Type createArrayType(Context& c, TypeId pointsTo);
  121. };
  122. #if 0
  123. #include "Scope.h"
  124. #include <memory>
  125. #include <string>
  126. namespace llvm {
  127. class Value;
  128. class Type;
  129. class LLVMContext;
  130. }
  131. namespace qlow
  132. {
  133. namespace sem
  134. {
  135. // forward declarations
  136. struct Class;
  137. class Scope;
  138. struct NativeMethod;
  139. }
  140. namespace sem
  141. {
  142. struct SemanticObject;
  143. class Type;
  144. class PointerType;
  145. class ClassType;
  146. class ArrayType;
  147. class NativeType;
  148. }
  149. }
  150. class qlow::sem::Type : public SemanticObject
  151. {
  152. public:
  153. virtual ~Type(void);
  154. /// \returns false by default
  155. virtual inline bool isPointerType(void) const { return false; }
  156. /// \returns false by default
  157. virtual inline bool isClassType(void) const { return false; }
  158. /// \returns false by default
  159. virtual inline bool isNativeType(void) const { return false; }
  160. /// \returns false by default
  161. virtual inline bool isArrayType(void) const { return false; }
  162. virtual std::string asString(void) const = 0;
  163. virtual Scope& getScope(void) = 0;
  164. virtual y = 0;
  165. virtual bool equals(const Type& other) const;
  166. virtual size_t hash(void) const;
  167. // static TypeId VOID;
  168. // static TypeId INTEGER;
  169. // static TypeId BOOLEAN;
  170. };
  171. class qlow::sem::PointerType : public Type
  172. {
  173. TypeId derefType;
  174. sem::TypeScope scope;
  175. public:
  176. inline PointerType(TypeId derefType) :
  177. derefType{ derefType },
  178. scope{ *this }
  179. {
  180. }
  181. const TypeId& getDerefType(void) const { return derefType; }
  182. inline bool isPointerType(void) const override { return true; }
  183. virtual std::string asString(void) const override;
  184. virtual Scope& getScope(void) override;
  185. virtual llvm::Type* getLlvmType(llvm::LLVMContext& context) const override;
  186. virtual bool equals(const Type& other) const override;
  187. };
  188. class qlow::sem::ClassType : public Type
  189. {
  190. sem::Class* classType;
  191. sem::TypeScope scope;
  192. public:
  193. inline ClassType(sem::Class* classType) :
  194. classType{ classType },
  195. scope{ *this }
  196. {
  197. }
  198. inline bool isClassType(void) const override { return true; }
  199. std::string asString(void) const override;
  200. Scope& getScope(void) override;
  201. virtual llvm::Type* getLlvmType(llvm::LLVMContext& context) const override;
  202. inline sem::Class* getClassType(void) { return classType; }
  203. virtual bool equals(const Type& other) const override;
  204. };
  205. class qlow::sem::ArrayType : public Type
  206. {
  207. std::shared_ptr<sem::Type> arrayType;
  208. TypeScope scope;
  209. public:
  210. inline ArrayType(std::shared_ptr<sem::Type> arrayType) :
  211. arrayType{ std::move(arrayType) },
  212. scope{ *this }
  213. {
  214. }
  215. inline bool isArrayType(void) const override { return true; }
  216. std::string asString(void) const override;
  217. Scope& getScope(void) override;
  218. virtual llvm::Type* getLlvmType(llvm::LLVMContext& context) const override;
  219. inline std::shared_ptr<sem::Type> getArrayType(void) { return arrayType; }
  220. virtual bool equals(const Type& other) const override;
  221. };
  222. class qlow::sem::NativeType : public Type
  223. {
  224. NativeTypeScope scope;
  225. public:
  226. enum Type {
  227. VOID,
  228. INTEGER,
  229. BOOLEAN,
  230. CHAR,
  231. STRING,
  232. INT8, INT16, INT32, INT64, INT128,
  233. UINT8, UINT16, UINT32, UINT64, UINT128,
  234. FLOAT32, FLOAT64, FLOAT128,
  235. };
  236. Type type;
  237. SymbolTable<NativeMethod> nativeMethods;
  238. inline NativeType(Type type) :
  239. scope{ *this },
  240. type{ type }
  241. {
  242. }
  243. inline bool isNativeType(void) const override { return true; }
  244. std::string asString(void) const override;
  245. Scope& getScope(void) override;
  246. bool isIntegerType(void) const;
  247. llvm::Type* getLlvmType(llvm::LLVMContext& context) const override;
  248. virtual bool equals(const sem::Type& other) const override;
  249. /// cast an llvm::Value from another native type to this one
  250. llvm::Value* generateImplicitCast(llvm::Value* value);
  251. };
  252. #endif
  253. #endif // QLOW_SEM_TYPE_H