acid.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. #include "cc.h"
  2. static char *kwd[] =
  3. {
  4. "$adt", "$aggr", "$append", "$builtin", "$complex", "$defn",
  5. "$delete", "$do", "$else", "$eval", "$head", "$if",
  6. "$local", "$loop", "$return", "$tail", "$then",
  7. "$union", "$whatis", "$while",
  8. };
  9. char*
  10. amap(char *s)
  11. {
  12. int i, bot, top, new;
  13. bot = 0;
  14. top = bot + nelem(kwd) - 1;
  15. while(bot <= top){
  16. new = bot + (top - bot)/2;
  17. i = strcmp(kwd[new]+1, s);
  18. if(i == 0)
  19. return kwd[new];
  20. if(i < 0)
  21. bot = new + 1;
  22. else
  23. top = new - 1;
  24. }
  25. return s;
  26. }
  27. Sym*
  28. acidsue(Type *t)
  29. {
  30. int h;
  31. Sym *s;
  32. if(t != T)
  33. for(h=0; h<nelem(hash); h++)
  34. for(s = hash[h]; s != S; s = s->link)
  35. if(s->suetag && s->suetag->link == t)
  36. return s;
  37. return 0;
  38. }
  39. Sym*
  40. acidfun(Type *t)
  41. {
  42. int h;
  43. Sym *s;
  44. for(h=0; h<nelem(hash); h++)
  45. for(s = hash[h]; s != S; s = s->link)
  46. if(s->type == t)
  47. return s;
  48. return 0;
  49. }
  50. char acidchar[NTYPE];
  51. Init acidcinit[] =
  52. {
  53. TCHAR, 'C', 0,
  54. TUCHAR, 'b', 0,
  55. TSHORT, 'd', 0,
  56. TUSHORT, 'u', 0,
  57. TLONG, 'D', 0,
  58. TULONG, 'U', 0,
  59. TVLONG, 'V', 0,
  60. TUVLONG, 'W', 0,
  61. TFLOAT, 'f', 0,
  62. TDOUBLE, 'F', 0,
  63. TARRAY, 'a', 0,
  64. TIND, 'X', 0,
  65. -1, 0, 0,
  66. };
  67. static void
  68. acidinit(void)
  69. {
  70. Init *p;
  71. for(p=acidcinit; p->code >= 0; p++)
  72. acidchar[p->code] = p->value;
  73. acidchar[TINT] = acidchar[TLONG];
  74. acidchar[TUINT] = acidchar[TULONG];
  75. if(types[TINT]->width != types[TLONG]->width) {
  76. acidchar[TINT] = acidchar[TSHORT];
  77. acidchar[TUINT] = acidchar[TUSHORT];
  78. if(types[TINT]->width != types[TSHORT]->width)
  79. warn(Z, "acidmember int not long or short");
  80. }
  81. if(types[TIND]->width == types[TUVLONG]->width)
  82. acidchar[TIND] = 'Y';
  83. }
  84. void
  85. acidmember(Type *t, long off, int flag)
  86. {
  87. Sym *s, *s1;
  88. Type *l;
  89. static int acidcharinit = 0;
  90. if(acidcharinit == 0) {
  91. acidinit();
  92. acidcharinit = 1;
  93. }
  94. s = t->sym;
  95. switch(t->etype) {
  96. default:
  97. Bprint(&outbuf, " T%d\n", t->etype);
  98. break;
  99. case TIND:
  100. if(s == S)
  101. break;
  102. if(flag) {
  103. for(l=t; l->etype==TIND; l=l->link)
  104. ;
  105. if(typesu[l->etype]) {
  106. s1 = acidsue(l->link);
  107. if(s1 != S) {
  108. Bprint(&outbuf, " 'A' %s %ld %s;\n",
  109. amap(s1->name),
  110. t->offset+off, amap(s->name));
  111. break;
  112. }
  113. }
  114. } else {
  115. Bprint(&outbuf,
  116. "\tprint(\"\t%s\t\", addr.%s\\X, \"\\n\");\n",
  117. amap(s->name), amap(s->name));
  118. break;
  119. }
  120. case TINT:
  121. case TUINT:
  122. case TCHAR:
  123. case TUCHAR:
  124. case TSHORT:
  125. case TUSHORT:
  126. case TLONG:
  127. case TULONG:
  128. case TVLONG:
  129. case TUVLONG:
  130. case TFLOAT:
  131. case TDOUBLE:
  132. case TARRAY:
  133. if(s == S)
  134. break;
  135. if(flag) {
  136. Bprint(&outbuf, " '%c' %ld %s;\n",
  137. acidchar[t->etype], t->offset+off, amap(s->name));
  138. } else {
  139. Bprint(&outbuf, "\tprint(\"\t%s\t\", addr.%s, \"\\n\");\n",
  140. amap(s->name), amap(s->name));
  141. }
  142. break;
  143. case TSTRUCT:
  144. case TUNION:
  145. s1 = acidsue(t->link);
  146. if(s1 == S)
  147. break;
  148. if(flag) {
  149. if(s == S) {
  150. Bprint(&outbuf, " {\n");
  151. for(l = t->link; l != T; l = l->down)
  152. acidmember(l, t->offset+off, flag);
  153. Bprint(&outbuf, " };\n");
  154. } else {
  155. Bprint(&outbuf, " %s %ld %s;\n",
  156. amap(s1->name),
  157. t->offset+off, amap(s->name));
  158. }
  159. } else {
  160. if(s != S) {
  161. Bprint(&outbuf, "\tprint(\"%s %s {\\n\");\n",
  162. amap(s1->name), amap(s->name));
  163. Bprint(&outbuf, "\t%s(addr.%s);\n",
  164. amap(s1->name), amap(s->name));
  165. Bprint(&outbuf, "\tprint(\"}\\n\");\n");
  166. } else {
  167. Bprint(&outbuf, "\tprint(\"%s {\\n\");\n",
  168. amap(s1->name));
  169. Bprint(&outbuf, "\t\t%s(addr+%ld);\n",
  170. amap(s1->name), t->offset+off);
  171. Bprint(&outbuf, "\tprint(\"}\\n\");\n");
  172. }
  173. }
  174. break;
  175. }
  176. }
  177. void
  178. acidtype(Type *t)
  179. {
  180. Sym *s;
  181. Type *l;
  182. Io *i;
  183. int n;
  184. char *an;
  185. if(!debug['a'])
  186. return;
  187. if(debug['a'] > 1) {
  188. n = 0;
  189. for(i=iostack; i; i=i->link)
  190. n++;
  191. if(n > 1)
  192. return;
  193. }
  194. s = acidsue(t->link);
  195. if(s == S)
  196. return;
  197. switch(t->etype) {
  198. default:
  199. Bprint(&outbuf, "T%d\n", t->etype);
  200. return;
  201. case TUNION:
  202. case TSTRUCT:
  203. if(debug['s'])
  204. goto asmstr;
  205. an = amap(s->name);
  206. Bprint(&outbuf, "sizeof%s = %ld;\n", an, t->width);
  207. Bprint(&outbuf, "aggr %s\n{\n", an);
  208. for(l = t->link; l != T; l = l->down)
  209. acidmember(l, 0, 1);
  210. Bprint(&outbuf, "};\n\n");
  211. Bprint(&outbuf, "defn\n%s(addr) {\n\tcomplex %s addr;\n", an, an);
  212. for(l = t->link; l != T; l = l->down)
  213. acidmember(l, 0, 0);
  214. Bprint(&outbuf, "};\n\n");
  215. break;
  216. asmstr:
  217. if(s == S)
  218. break;
  219. for(l = t->link; l != T; l = l->down)
  220. if(l->sym != S)
  221. Bprint(&outbuf, "#define\t%s.%s\t%ld\n",
  222. s->name,
  223. l->sym->name,
  224. l->offset);
  225. break;
  226. }
  227. }
  228. void
  229. acidvar(Sym *s)
  230. {
  231. int n;
  232. Io *i;
  233. Type *t;
  234. Sym *s1, *s2;
  235. if(!debug['a'] || debug['s'])
  236. return;
  237. if(debug['a'] > 1) {
  238. n = 0;
  239. for(i=iostack; i; i=i->link)
  240. n++;
  241. if(n > 1)
  242. return;
  243. }
  244. t = s->type;
  245. while(t && t->etype == TIND)
  246. t = t->link;
  247. if(t == T)
  248. return;
  249. if(t->etype == TENUM) {
  250. Bprint(&outbuf, "%s = ", amap(s->name));
  251. if(!typefd[t->etype])
  252. Bprint(&outbuf, "%lld;\n", s->vconst);
  253. else
  254. Bprint(&outbuf, "%f\n;", s->fconst);
  255. return;
  256. }
  257. if(!typesu[t->etype])
  258. return;
  259. s1 = acidsue(t->link);
  260. if(s1 == S)
  261. return;
  262. switch(s->class) {
  263. case CAUTO:
  264. case CPARAM:
  265. s2 = acidfun(thisfn);
  266. if(s2)
  267. Bprint(&outbuf, "complex %s %s:%s;\n",
  268. amap(s1->name), amap(s2->name), amap(s->name));
  269. break;
  270. case CSTATIC:
  271. case CEXTERN:
  272. case CGLOBL:
  273. case CLOCAL:
  274. Bprint(&outbuf, "complex %s %s;\n",
  275. amap(s1->name), amap(s->name));
  276. break;
  277. }
  278. }