acid.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. #include "cc.h"
  2. static char *kwd[] =
  3. {
  4. "$adt", "$aggr", "$append", "$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. }
  82. void
  83. acidmember(Type *t, long off, int flag)
  84. {
  85. Sym *s, *s1;
  86. Type *l;
  87. static int acidcharinit = 0;
  88. if(acidcharinit == 0) {
  89. acidinit();
  90. acidcharinit = 1;
  91. }
  92. s = t->sym;
  93. switch(t->etype) {
  94. default:
  95. Bprint(&outbuf, " T%d\n", t->etype);
  96. break;
  97. case TIND:
  98. if(s == S)
  99. break;
  100. if(flag) {
  101. for(l=t; l->etype==TIND; l=l->link)
  102. ;
  103. if(typesu[l->etype]) {
  104. s1 = acidsue(l->link);
  105. if(s1 != S) {
  106. Bprint(&outbuf, " 'A' %s %ld %s;\n",
  107. amap(s1->name),
  108. t->offset+off, amap(s->name));
  109. break;
  110. }
  111. }
  112. } else {
  113. Bprint(&outbuf,
  114. "\tprint(\"\t%s\t\", addr.%s\\X, \"\\n\");\n",
  115. amap(s->name), amap(s->name));
  116. break;
  117. }
  118. case TINT:
  119. case TUINT:
  120. case TCHAR:
  121. case TUCHAR:
  122. case TSHORT:
  123. case TUSHORT:
  124. case TLONG:
  125. case TULONG:
  126. case TVLONG:
  127. case TUVLONG:
  128. case TFLOAT:
  129. case TDOUBLE:
  130. case TARRAY:
  131. if(s == S)
  132. break;
  133. if(flag) {
  134. Bprint(&outbuf, " '%c' %ld %s;\n",
  135. acidchar[t->etype], t->offset+off, amap(s->name));
  136. } else {
  137. Bprint(&outbuf, "\tprint(\"\t%s\t\", addr.%s, \"\\n\");\n",
  138. amap(s->name), amap(s->name));
  139. }
  140. break;
  141. case TSTRUCT:
  142. case TUNION:
  143. s1 = acidsue(t->link);
  144. if(s1 == S)
  145. break;
  146. if(flag) {
  147. if(s == S) {
  148. Bprint(&outbuf, " {\n");
  149. for(l = t->link; l != T; l = l->down)
  150. acidmember(l, t->offset+off, flag);
  151. Bprint(&outbuf, " };\n");
  152. } else {
  153. Bprint(&outbuf, " %s %ld %s;\n",
  154. amap(s1->name),
  155. t->offset+off, amap(s->name));
  156. }
  157. } else {
  158. if(s != S) {
  159. Bprint(&outbuf, "\tprint(\"%s %s {\\n\");\n",
  160. amap(s1->name), amap(s->name));
  161. Bprint(&outbuf, "\t%s(addr.%s);\n",
  162. amap(s1->name), amap(s->name));
  163. Bprint(&outbuf, "\tprint(\"}\\n\");\n");
  164. } else {
  165. Bprint(&outbuf, "\tprint(\"%s {\\n\");\n",
  166. amap(s1->name));
  167. Bprint(&outbuf, "\t\t%s(addr+%ld);\n",
  168. amap(s1->name), t->offset+off);
  169. Bprint(&outbuf, "\tprint(\"}\\n\");\n");
  170. }
  171. }
  172. break;
  173. }
  174. }
  175. void
  176. acidtype(Type *t)
  177. {
  178. Sym *s;
  179. Type *l;
  180. Io *i;
  181. int n;
  182. char *an;
  183. if(!debug['a'])
  184. return;
  185. if(debug['a'] > 1) {
  186. n = 0;
  187. for(i=iostack; i; i=i->link)
  188. n++;
  189. if(n > 1)
  190. return;
  191. }
  192. s = acidsue(t->link);
  193. if(s == S)
  194. return;
  195. switch(t->etype) {
  196. default:
  197. Bprint(&outbuf, "T%d\n", t->etype);
  198. return;
  199. case TUNION:
  200. case TSTRUCT:
  201. if(debug['s'])
  202. goto asmstr;
  203. an = amap(s->name);
  204. Bprint(&outbuf, "sizeof%s = %ld;\n", an, t->width);
  205. Bprint(&outbuf, "aggr %s\n{\n", an);
  206. for(l = t->link; l != T; l = l->down)
  207. acidmember(l, 0, 1);
  208. Bprint(&outbuf, "};\n\n");
  209. Bprint(&outbuf, "defn\n%s(addr) {\n\tcomplex %s addr;\n", an, an);
  210. for(l = t->link; l != T; l = l->down)
  211. acidmember(l, 0, 0);
  212. Bprint(&outbuf, "};\n\n");
  213. break;
  214. asmstr:
  215. if(s == S)
  216. break;
  217. for(l = t->link; l != T; l = l->down)
  218. if(l->sym != S)
  219. Bprint(&outbuf, "#define\t%s.%s\t%ld\n",
  220. s->name,
  221. l->sym->name,
  222. l->offset);
  223. break;
  224. }
  225. }
  226. void
  227. acidvar(Sym *s)
  228. {
  229. int n;
  230. Io *i;
  231. Type *t;
  232. Sym *s1, *s2;
  233. if(!debug['a'] || debug['s'])
  234. return;
  235. if(debug['a'] > 1) {
  236. n = 0;
  237. for(i=iostack; i; i=i->link)
  238. n++;
  239. if(n > 1)
  240. return;
  241. }
  242. t = s->type;
  243. while(t && t->etype == TIND)
  244. t = t->link;
  245. if(t == T)
  246. return;
  247. if(t->etype == TENUM) {
  248. Bprint(&outbuf, "%s = ", amap(s->name));
  249. if(!typefd[t->etype])
  250. Bprint(&outbuf, "%lld;\n", s->vconst);
  251. else
  252. Bprint(&outbuf, "%f\n;", s->fconst);
  253. return;
  254. }
  255. if(!typesu[t->etype])
  256. return;
  257. s1 = acidsue(t->link);
  258. if(s1 == S)
  259. return;
  260. switch(s->class) {
  261. case CAUTO:
  262. case CPARAM:
  263. s2 = acidfun(thisfn);
  264. if(s2)
  265. Bprint(&outbuf, "complex %s %s:%s;\n",
  266. amap(s1->name), amap(s2->name), amap(s->name));
  267. break;
  268. case CSTATIC:
  269. case CEXTERN:
  270. case CGLOBL:
  271. case CLOCAL:
  272. Bprint(&outbuf, "complex %s %s;\n",
  273. amap(s1->name), amap(s->name));
  274. break;
  275. }
  276. }