Type.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. #include "Type.h"
  2. #include "Context.h"
  3. using qlow::sem::TypeId;
  4. using qlow::sem::Type;
  5. /*
  6. TypeId TypeId::toPointer(void) const
  7. {
  8. return context.addType(Type::createPointerType(context, *this));
  9. }
  10. TypeId TypeId::toArray(void) const
  11. {
  12. return context.addType(Type::createArrayType(context, *this));
  13. }
  14. */
  15. Type::Kind Type::getKind(void) const
  16. {
  17. switch(type.index()) {
  18. case 0: return Kind::NATIVE;
  19. case 1: return Kind::CLASS;
  20. case 2: return Kind::POINTER;
  21. case 3: return Kind::ARRAY;
  22. }
  23. }
  24. std::string Type::asString(void) const
  25. {
  26. return std::visit(
  27. [&] (const auto& t) -> std::string {
  28. using T = std::decay_t<decltype(t)>;
  29. if constexpr (std::is_same<T, NativeType>) {
  30. return this->name;
  31. }
  32. else if constexpr (std::is_same<T, ClassType>) {
  33. return this->name;
  34. }
  35. else if constexpr (std::is_same<T, PointerType>) {
  36. auto& context = t.targetType.getContext();
  37. return context.getType(t.targetType) + "*";
  38. }
  39. else if constexpr (std::is_same<T, ArrayType>) {
  40. auto& context = t.targetType.getContext();
  41. return "[" + context.getType(t.targetType) + "]";
  42. }
  43. }
  44. ,
  45. type
  46. );
  47. }
  48. bool Type::operator==(const Type& other) const
  49. {
  50. return this->name == other.name &&
  51. this->type == other.type;
  52. }
  53. Type Type::createClassType(Context& c, Class* classType)
  54. {
  55. return Type{ Union{ ClassType{ classType }}};
  56. }
  57. Type Type::createPointerType(Context& c, TypeId pointsTo)
  58. {
  59. return Type{ Union{ PointerType{ pointsTo }}};
  60. }
  61. Type Type::createArrayType(Context& c, TypeId pointsTo)
  62. {
  63. return Type{ Union{ ArrayType{ pointsTo }}};
  64. }
  65. #if 0
  66. #include "Semantic.h"
  67. #include "Builtin.h"
  68. #include <llvm/IR/DerivedTypes.h>
  69. #include <llvm/IR/Type.h>
  70. using namespace qlow;
  71. sem::Type::~Type(void)
  72. {
  73. }
  74. bool sem::Type::equals(const Type& other) const
  75. {
  76. return this == &other;
  77. }
  78. size_t sem::Type::hash(void) const
  79. {
  80. return std::hash<std::string>()(this->asString());
  81. }
  82. /*std::shared_ptr<sem::Type> sem::Type::VOID =
  83. std::make_shared<sem::NativeType>(sem::NativeType::Type::VOID);
  84. std::shared_ptr<sem::Type> sem::Type::INTEGER =
  85. std::make_shared<sem::NativeType>(sem::NativeType::Type::INTEGER);
  86. std::shared_ptr<sem::Type> sem::Type::BOOLEAN =
  87. std::make_shared<sem::NativeType>(sem::NativeType::Type::BOOLEAN);
  88. */
  89. std::string sem::PointerType::asString(void) const
  90. {
  91. return derefType->asString() + "*";
  92. }
  93. sem::Scope& sem::PointerType::getScope(void)
  94. {
  95. return scope;
  96. }
  97. llvm::Type* sem::PointerType::getLlvmType(llvm::LLVMContext& context) const
  98. {
  99. return derefType->getLlvmType(context)->getPointerTo();
  100. }
  101. bool sem::PointerType::equals(const Type& other) const
  102. {
  103. if (const PointerType* opt = dynamic_cast<const PointerType*>(&other); opt) {
  104. return derefType->equals(*opt->getDerefType());
  105. }
  106. else
  107. return false;
  108. }
  109. std::string sem::ClassType::asString(void) const
  110. {
  111. return classType->name;
  112. }
  113. sem::Scope& sem::ClassType::getScope(void)
  114. {
  115. return scope;
  116. }
  117. llvm::Type* sem::ClassType::getLlvmType (llvm::LLVMContext& context) const
  118. {
  119. return classType->llvmType;
  120. }
  121. bool sem::ClassType::equals(const Type& other) const
  122. {
  123. if (auto* oct = dynamic_cast<const ClassType*>(&other); oct) {
  124. return this->classType == oct->classType;
  125. }
  126. else {
  127. return false;
  128. }
  129. }
  130. std::string sem::ArrayType::asString(void) const
  131. {
  132. return std::string("[") + arrayType->asString() + "]";
  133. }
  134. sem::Scope& sem::ArrayType::getScope(void)
  135. {
  136. return scope;
  137. }
  138. llvm::Type* sem::ArrayType::getLlvmType (llvm::LLVMContext& context) const
  139. {
  140. // TODO implement
  141. return nullptr;
  142. }
  143. bool sem::ArrayType::equals(const Type& other) const
  144. {
  145. if (auto* oct = dynamic_cast<const ArrayType*>(&other); oct) {
  146. return this->arrayType->equals(*oct->arrayType);
  147. }
  148. else {
  149. return false;
  150. }
  151. }
  152. std::string sem::NativeType::asString(void) const
  153. {
  154. switch(type) {
  155. case VOID:
  156. return "Void";
  157. case INTEGER:
  158. return "Integer";
  159. case BOOLEAN:
  160. return "Boolean";
  161. case CHAR:
  162. return "Char";
  163. case INT8:
  164. return "Int8";
  165. case INT16:
  166. return "Int16";
  167. case INT32:
  168. return "Int32";
  169. case INT64:
  170. return "Int64";
  171. case INT128:
  172. return "Int128";
  173. case UINT8:
  174. return "UInt8";
  175. case UINT16:
  176. return "UInt16";
  177. case UINT32:
  178. return "UInt32";
  179. case UINT64:
  180. return "UInt64";
  181. case UINT128:
  182. return "UInt128";
  183. case FLOAT32:
  184. return "Float32";
  185. case FLOAT64:
  186. return "Float64";
  187. case FLOAT128:
  188. return "Float128";
  189. }
  190. }
  191. sem::Scope& sem::NativeType::getScope(void)
  192. {
  193. return scope;
  194. }
  195. bool sem::NativeType::isIntegerType(void) const
  196. {
  197. switch(type) {
  198. case INTEGER:
  199. case INT8:
  200. case INT16:
  201. case INT32:
  202. case INT64:
  203. case INT128:
  204. case UINT8:
  205. case UINT16:
  206. case UINT32:
  207. case UINT64:
  208. case UINT128:
  209. return true;
  210. default:
  211. return false;
  212. }
  213. }
  214. llvm::Type* sem::NativeType::getLlvmType(llvm::LLVMContext& context) const
  215. {
  216. switch (type) {
  217. case VOID:
  218. return llvm::Type::getVoidTy(context);
  219. case INTEGER:
  220. return llvm::Type::getInt32Ty(context);
  221. case BOOLEAN:
  222. return llvm::Type::getInt1Ty(context);
  223. case CHAR:
  224. return llvm::Type::getInt32Ty(context);
  225. case INT8:
  226. return llvm::Type::getInt8Ty(context);
  227. case INT16:
  228. return llvm::Type::getInt16Ty(context);
  229. case INT32:
  230. return llvm::Type::getInt32Ty(context);
  231. case INT64:
  232. return llvm::Type::getInt64Ty(context);
  233. case INT128:
  234. return llvm::Type::getInt128Ty(context);
  235. case UINT8:
  236. return llvm::Type::getInt8Ty(context);
  237. case UINT16:
  238. return llvm::Type::getInt16Ty(context);
  239. case UINT32:
  240. return llvm::Type::getInt32Ty(context);
  241. case UINT64:
  242. return llvm::Type::getInt64Ty(context);
  243. case UINT128:
  244. return llvm::Type::getInt128Ty(context);
  245. case FLOAT32:
  246. return llvm::Type::getFloatTy(context);
  247. case FLOAT64:
  248. return llvm::Type::getDoubleTy(context);
  249. case FLOAT128:
  250. return llvm::Type::getFP128Ty(context);
  251. default:
  252. return nullptr;
  253. }
  254. }
  255. bool sem::NativeType::equals(const sem::Type& other) const
  256. {
  257. if (auto* oct = dynamic_cast<const NativeType*>(&other); oct) {
  258. if (this->type == Type::INTEGER || this->type == Type::INT32) {
  259. if (oct->type == Type::INTEGER || oct->type == Type::INT32)
  260. // Int32 == Integer
  261. return true;
  262. }
  263. return this->type == oct->type;
  264. }
  265. else {
  266. return false;
  267. }
  268. }
  269. llvm::Value* sem::NativeType::generateImplicitCast(llvm::Value* value)
  270. {
  271. // TODO implement
  272. }
  273. #endif