cc_types.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. /* Copyright (C) 2016 Jeremiah Orians
  2. * This file is part of M2-Planet.
  3. *
  4. * M2-Planet is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * M2-Planet is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with M2-Planet. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include "cc.h"
  18. #include <stdint.h>
  19. void line_error();
  20. int numerate_string(char *a);
  21. /* Initialize default types */
  22. void initialize_types()
  23. {
  24. if(AMD64 == Architecture) register_size = 8;
  25. else register_size = 4;
  26. /* Define void */
  27. global_types = calloc(1, sizeof(struct type));
  28. global_types->name = "void";
  29. global_types->size = register_size;
  30. global_types->type = global_types;
  31. /* void* has the same properties as void */
  32. global_types->indirect = global_types;
  33. /* Define int */
  34. struct type* a = calloc(1, sizeof(struct type));
  35. a->name = "int";
  36. a->size = register_size;
  37. /* int* has the same properties as int */
  38. a->indirect = a;
  39. a->type = a;
  40. /* Define char* */
  41. struct type* b = calloc(1, sizeof(struct type));
  42. b->name = "char*";
  43. b->size = register_size;
  44. b->type = b;
  45. /* Define char */
  46. struct type* c = calloc(1, sizeof(struct type));
  47. c->name = "char";
  48. c->size = 1;
  49. c->type = c;
  50. /* Define char** */
  51. struct type* d = calloc(1, sizeof(struct type));
  52. d->name = "char**";
  53. d->size = register_size;
  54. d->type = b;
  55. d->indirect = d;
  56. /*fix up indrects for chars */
  57. c->indirect = b;
  58. b->indirect = d;
  59. /* Define FILE */
  60. struct type* e = calloc(1, sizeof(struct type));
  61. e->name = "FILE";
  62. e->size = register_size;
  63. e->type = e;
  64. /* FILE* has the same properties as FILE */
  65. e->indirect = e;
  66. /* Define FUNCTION */
  67. struct type* f = calloc(1, sizeof(struct type));
  68. f->name = "FUNCTION";
  69. f->size = register_size;
  70. f->type = f;
  71. /* FUNCTION* has the same properties as FUNCTION */
  72. f->indirect = f;
  73. /* Define UNSIGNED */
  74. struct type* g = calloc(1, sizeof(struct type));
  75. g->name = "unsigned";
  76. g->size = register_size;
  77. g->type = g;
  78. /* unsigned* has the same properties as unsigned */
  79. g->indirect = g;
  80. /* Custom type for mescc*/
  81. struct type* h = calloc(1, sizeof(struct type));
  82. h->name = "SCM";
  83. h->size = register_size;
  84. h->indirect = h;
  85. /* Finalize type list */
  86. g->next = h;
  87. f->next = g;
  88. e->next = f;
  89. d->next = e;
  90. c->next = e;
  91. a->next = c;
  92. global_types->next = a;
  93. prim_types = global_types;
  94. }
  95. struct type* lookup_type(char* s, struct type* start)
  96. {
  97. struct type* i;
  98. for(i = start; NULL != i; i = i->next)
  99. {
  100. if(match(i->name, s))
  101. {
  102. return i;
  103. }
  104. }
  105. return NULL;
  106. }
  107. struct type* lookup_member(struct type* parent, char* name)
  108. {
  109. struct type* i;
  110. for(i = parent->members; NULL != i; i = i->members)
  111. {
  112. if(match(i->name, name)) return i;
  113. }
  114. file_print("ERROR in lookup_member ", stderr);
  115. file_print(parent->name, stderr);
  116. file_print("->", stderr);
  117. file_print(global_token->s, stderr);
  118. file_print(" does not exist\n", stderr);
  119. line_error();
  120. file_print("\n", stderr);
  121. exit(EXIT_FAILURE);
  122. }
  123. struct type* type_name();
  124. void require_match(char* message, char* required);
  125. int member_size;
  126. struct type* build_member(struct type* last, int offset)
  127. {
  128. struct type* i = calloc(1, sizeof(struct type));
  129. i->members = last;
  130. i->offset = offset;
  131. struct type* member_type = type_name();
  132. i->type = member_type;
  133. i->name = global_token->s;
  134. global_token = global_token->next;
  135. /* Check to see if array */
  136. if(match( "[", global_token->s))
  137. {
  138. global_token = global_token->next;
  139. i->size = member_type->type->size * numerate_string(global_token->s);
  140. global_token = global_token->next;
  141. require_match("Struct only supports [num] form\n", "]");
  142. }
  143. else
  144. {
  145. i->size = member_type->size;
  146. }
  147. member_size = i->size;
  148. return i;
  149. }
  150. struct type* build_union(struct type* last, int offset)
  151. {
  152. int size = 0;
  153. global_token = global_token->next;
  154. require_match("ERROR in build_union\nMissing {\n", "{");
  155. while('}' != global_token->s[0])
  156. {
  157. last = build_member(last, offset);
  158. if(member_size > size)
  159. {
  160. size = member_size;
  161. }
  162. require_match("ERROR in build_union\nMissing ;\n", ";");
  163. }
  164. member_size = size;
  165. global_token = global_token->next;
  166. return last;
  167. }
  168. void create_struct()
  169. {
  170. int offset = 0;
  171. member_size = 0;
  172. struct type* head = calloc(1, sizeof(struct type));
  173. struct type* i = calloc(1, sizeof(struct type));
  174. head->name = global_token->s;
  175. i->name = global_token->s;
  176. head->indirect = i;
  177. i->indirect = head;
  178. head->next = global_types;
  179. global_types = head;
  180. global_token = global_token->next;
  181. i->size = register_size;
  182. require_match("ERROR in create_struct\n Missing {\n", "{");
  183. struct type* last = NULL;
  184. while('}' != global_token->s[0])
  185. {
  186. if(match(global_token->s, "union"))
  187. {
  188. last = build_union(last, offset);
  189. }
  190. else
  191. {
  192. last = build_member(last, offset);
  193. }
  194. offset = offset + member_size;
  195. require_match("ERROR in create_struct\n Missing ;\n", ";");
  196. }
  197. global_token = global_token->next;
  198. require_match("ERROR in create_struct\n Missing ;\n", ";");
  199. head->size = offset;
  200. head->members = last;
  201. i->members = last;
  202. }
  203. /*
  204. * type-name:
  205. * char *
  206. * int
  207. * struct
  208. * FILE
  209. * void
  210. */
  211. struct type* type_name()
  212. {
  213. struct type* ret;
  214. if(match("struct", global_token->s))
  215. {
  216. global_token = global_token->next;
  217. ret = lookup_type(global_token->s, global_types);
  218. if(NULL == ret)
  219. {
  220. create_struct();
  221. return NULL;
  222. }
  223. }
  224. else
  225. {
  226. ret = lookup_type(global_token->s, global_types);
  227. if(NULL == ret)
  228. {
  229. file_print("Unknown type ", stderr);
  230. file_print(global_token->s, stderr);
  231. file_print("\n", stderr);
  232. line_error();
  233. exit(EXIT_FAILURE);
  234. }
  235. }
  236. global_token = global_token->next;
  237. while(global_token->s[0] == '*')
  238. {
  239. ret = ret->indirect;
  240. global_token = global_token->next;
  241. }
  242. return ret;
  243. }