DataType.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "DataType.h"
  5. #define ARRAY_NAME 256
  6. static int typeNameIndex = 0;
  7. static int typeNameSwap = 0;
  8. static char typeName[2][ARRAY_NAME];
  9. static bool useGlobals = false;
  10. static Structs globalStructs;
  11. const char* vtGetName(ValueType vt) {
  12. switch(vt) {
  13. case VT_INVALID: return "invalid";
  14. case VT_NOT_SET: return "?";
  15. case VT_INT: return "int";
  16. case VT_FLOAT: return "float";
  17. case VT_POINTER: return "pointer";
  18. case VT_ARRAY: return "array";
  19. case VT_LAST: return "invalid";
  20. }
  21. return "invalid";
  22. }
  23. #define VALUE_TYPE_MASK ((1u << VALUE_TYPE_BIT_SIZE) - 1u)
  24. #define VALUE_MAX_OFFSET ((1u << (32 - VALUE_TYPE_BIT_SIZE)) - 1u)
  25. ValueType vGetType(Value v) {
  26. uint32 type = v.typeAndOffset & VALUE_TYPE_MASK;
  27. if(type >= VT_LAST) {
  28. return VT_INVALID;
  29. }
  30. return (ValueType)type;
  31. }
  32. bool vSetType(Value* v, ValueType vt) {
  33. if(v == NULL || vt < 0 || vt >= VT_LAST) {
  34. return true;
  35. }
  36. v->typeAndOffset = (v->typeAndOffset & ~VALUE_TYPE_MASK) | vt;
  37. return false;
  38. }
  39. uint32 vGetOffset(Value v) {
  40. return v.typeAndOffset >> VALUE_TYPE_BIT_SIZE;
  41. }
  42. bool vSetOffset(Value* v, uint32 offset) {
  43. if(v == NULL || offset > VALUE_MAX_OFFSET) {
  44. return true;
  45. }
  46. v->typeAndOffset =
  47. (v->typeAndOffset & VALUE_TYPE_MASK) | (offset << VALUE_TYPE_BIT_SIZE);
  48. return false;
  49. }
  50. static void dtAppend(const char* s) {
  51. int index = 0;
  52. while(typeNameIndex < (ARRAY_NAME - 1) && s[index] != '\0') {
  53. typeName[typeNameSwap][typeNameIndex] = s[index];
  54. index++;
  55. typeNameIndex++;
  56. }
  57. typeName[typeNameSwap][typeNameIndex] = '\0';
  58. }
  59. const char* dtGetName(const Structs* sts, DataType dt) {
  60. typeNameSwap = !typeNameSwap;
  61. typeNameIndex = 0;
  62. switch(dt.type) {
  63. case DT_INT: dtAppend("int"); break;
  64. case DT_FLOAT: dtAppend("float"); break;
  65. case DT_STRUCT: {
  66. Struct* s = dtGetStruct(sts, dt);
  67. if(s != NULL) {
  68. dtAppend(s->name);
  69. } else {
  70. dtAppend("?-struct");
  71. }
  72. break;
  73. }
  74. case DT_VOID: dtAppend("void"); break;
  75. default: dtAppend("unknown");
  76. }
  77. if(dt.array != 0) {
  78. dtAppend("[]");
  79. }
  80. if(dt.pointer != 0) {
  81. dtAppend("*");
  82. }
  83. return typeName[typeNameSwap];
  84. }
  85. int dtGetSize(DataType dt, const Structs* sts) {
  86. if(dt.pointer != 0) {
  87. return 1;
  88. }
  89. switch(dt.type) {
  90. case DT_INT: return 1;
  91. case DT_FLOAT: return 1;
  92. case DT_STRUCT: {
  93. int size = 0;
  94. Struct* st = dtGetStruct(sts, dt);
  95. if(st == NULL) {
  96. return 0;
  97. }
  98. for(int i = 0; i < st->amount; i++) {
  99. size += dtGetSize(st->vars[i].type, sts);
  100. }
  101. return size;
  102. }
  103. default: return 0;
  104. }
  105. }
  106. DataType dtInt(void) {
  107. DataType dt = {DT_INT, 0, 0, 0};
  108. return dt;
  109. }
  110. DataType dtFloat(void) {
  111. DataType dt = {DT_FLOAT, 0, 0, 0};
  112. return dt;
  113. }
  114. DataType dtVoid(void) {
  115. DataType dt = {DT_VOID, 0, 0, 0};
  116. return dt;
  117. }
  118. DataType dtStruct(const Struct* st) {
  119. DataType dt = {DT_STRUCT, 0, 0, st->id};
  120. return dt;
  121. }
  122. DataType dtText(void) {
  123. DataType dt = {DT_INT, 0, 1, 0};
  124. return dt;
  125. }
  126. DataType dtToArray(DataType dt) {
  127. dt.array = 1;
  128. return dt;
  129. }
  130. DataType dtRemoveArray(DataType dt) {
  131. dt.array = 0;
  132. return dt;
  133. }
  134. DataType dtToPointer(DataType dt) {
  135. dt.pointer = 1;
  136. return dt;
  137. }
  138. bool dtRemovePointer(DataType* dt) {
  139. if(dt->pointer != 0) {
  140. dt->pointer = 0;
  141. return true;
  142. }
  143. return false;
  144. }
  145. bool dtCompare(DataType a, DataType b) {
  146. return a.array == b.array && a.structId == b.structId && a.type == b.type &&
  147. a.pointer == b.pointer;
  148. }
  149. bool dtIsInt(DataType dt) {
  150. return dtCompare(dt, dtInt());
  151. }
  152. bool dtIsFloat(DataType dt) {
  153. return dtCompare(dt, dtFloat());
  154. }
  155. bool dtIsVoid(DataType dt) {
  156. return dtCompare(dt, dtVoid());
  157. }
  158. bool dtIsArray(DataType dt) {
  159. return dt.array != 0;
  160. }
  161. Struct* dtGetStruct(const Structs* sts, DataType dt) {
  162. if(dt.type != DT_STRUCT) {
  163. return NULL;
  164. }
  165. if(dt.structId & 1) {
  166. if(!useGlobals) {
  167. return NULL;
  168. }
  169. return globalStructs.data + (dt.structId >> 1);
  170. }
  171. return sts->data + (dt.structId >> 1);
  172. }
  173. void stAddVariable(Struct* st, const char* name, DataType type) {
  174. int index = st->amount;
  175. st->amount++;
  176. st->vars = (StructVariable*)realloc(st->vars, sizeof(StructVariable) *
  177. (size_t)st->amount);
  178. st->vars[index].name = name;
  179. st->vars[index].type = type;
  180. }
  181. void stsInit(Structs* sts) {
  182. sts->capacity = 4;
  183. sts->entries = 0;
  184. sts->data = (Struct*)malloc(sizeof(Struct) * (size_t)sts->capacity);
  185. }
  186. void stsDelete(Structs* sts) {
  187. for(int i = 0; i < sts->entries; i++) {
  188. free(sts->data[i].vars);
  189. }
  190. free(sts->data);
  191. }
  192. static Struct* stsInternSearch(Structs* sts, const char* name) {
  193. for(int i = 0; i < sts->entries; i++) {
  194. if(strcmp(sts->data[i].name, name) == 0) {
  195. return sts->data + i;
  196. }
  197. }
  198. return NULL;
  199. }
  200. Struct* stsSearch(Structs* sts, const char* name) {
  201. if(useGlobals) {
  202. Struct* st = stsInternSearch(&globalStructs, name);
  203. if(st != NULL) {
  204. return st;
  205. }
  206. }
  207. return stsInternSearch(sts, name);
  208. }
  209. Struct* stsAdd(Structs* sts, const char* name) {
  210. if(sts->entries >= sts->capacity) {
  211. sts->capacity *= 2;
  212. sts->data =
  213. (Struct*)realloc(sts->data, sizeof(Struct) * (size_t)sts->capacity);
  214. }
  215. uint16 index = (uint16)sts->entries++;
  216. sts->data[index].id = (uint16)(index << 1);
  217. sts->data[index].amount = 0;
  218. sts->data[index].name = name;
  219. sts->data[index].vars = NULL;
  220. return sts->data + index;
  221. }
  222. void gstsInit(void) {
  223. stsInit(&globalStructs);
  224. useGlobals = true;
  225. }
  226. void gstsDelete(void) {
  227. stsDelete(&globalStructs);
  228. useGlobals = false;
  229. }
  230. Structs* gstsGet(void) {
  231. return &globalStructs;
  232. }
  233. Struct* gstsAdd(const char* name) {
  234. Struct* st = stsAdd(&globalStructs, name);
  235. st->id |= 1;
  236. return st;
  237. }