print.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <bio.h>
  4. #include <ctype.h>
  5. #include <mach.h>
  6. #define Extern extern
  7. #include "acid.h"
  8. static char *binop[] =
  9. {
  10. [OMUL] "*",
  11. [ODIV] "/",
  12. [OMOD] "%",
  13. [OADD] "+",
  14. [OSUB] "-",
  15. [ORSH] ">>",
  16. [OLSH] "<<",
  17. [OLT] "<",
  18. [OGT] ">",
  19. [OLEQ] "<=",
  20. [OGEQ] ">=",
  21. [OEQ] "==",
  22. [ONEQ] "!=",
  23. [OLAND] "&",
  24. [OXOR] "^",
  25. [OLOR] "|",
  26. [OCAND] "&&",
  27. [OCOR] "||",
  28. [OASGN] " = ",
  29. };
  30. static char *tabs = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
  31. char *typenames[] =
  32. {
  33. [TINT] "integer",
  34. [TFLOAT] "float",
  35. [TSTRING] "string",
  36. [TLIST] "list",
  37. [TCODE] "code",
  38. };
  39. int
  40. cmp(void *va, void *vb)
  41. {
  42. char **a = va;
  43. char **b = vb;
  44. return strcmp(*a, *b);
  45. }
  46. void
  47. fundefs(void)
  48. {
  49. Lsym *l;
  50. char **vec;
  51. int i, j, n, max, col, f, g, s;
  52. max = 0;
  53. f = 0;
  54. g = 100;
  55. vec = malloc(sizeof(char*)*g);
  56. if(vec == 0)
  57. fatal("out of memory");
  58. for(i = 0; i < Hashsize; i++) {
  59. for(l = hash[i]; l; l = l->hash) {
  60. if(l->proc == 0 && l->builtin == 0)
  61. continue;
  62. n = strlen(l->name);
  63. if(n > max)
  64. max = n;
  65. if(f >= g) {
  66. g *= 2;
  67. vec = realloc(vec, sizeof(char*)*g);
  68. if(vec == 0)
  69. fatal("out of memory");
  70. }
  71. vec[f++] = l->name;
  72. }
  73. }
  74. qsort(vec, f, sizeof(char*), cmp);
  75. max++;
  76. col = 60/max;
  77. s = (f+col-1)/col;
  78. for(i = 0; i < s; i++) {
  79. for(j = i; j < f; j += s)
  80. Bprint(bout, "%-*s", max, vec[j]);
  81. Bprint(bout, "\n");
  82. }
  83. }
  84. void
  85. whatis(Lsym *l)
  86. {
  87. int t;
  88. int def;
  89. Type *ti;
  90. if(l == 0) {
  91. fundefs();
  92. return;
  93. }
  94. def = 0;
  95. if(l->v->set) {
  96. t = l->v->type;
  97. Bprint(bout, "%s variable", typenames[t]);
  98. if(t == TINT || t == TFLOAT)
  99. Bprint(bout, " format %c", l->v->fmt);
  100. if(l->v->comt)
  101. Bprint(bout, " complex %s",
  102. l->v->comt->base->name);
  103. Bputc(bout, '\n');
  104. def = 1;
  105. }
  106. if(l->lt) {
  107. Bprint(bout, "complex %s {\n", l->name);
  108. for(ti = l->lt; ti; ti = ti->next) {
  109. if(ti->type) {
  110. if(ti->fmt == 'a') {
  111. Bprint(bout, "\t%s %d %s;\n",
  112. ti->type->name, ti->offset,
  113. ti->tag->name);
  114. }
  115. else {
  116. Bprint(bout, "\t'%c' %s %d %s;\n",
  117. ti->fmt, ti->type->name, ti->offset,
  118. ti->tag->name);
  119. }
  120. }
  121. else
  122. Bprint(bout, "\t'%c' %d %s;\n",
  123. ti->fmt, ti->offset, ti->tag->name);
  124. }
  125. Bprint(bout, "};\n");
  126. def = 1;
  127. }
  128. if(l->proc) {
  129. Bprint(bout, "defn %s(", l->name);
  130. pexpr(l->proc->left);
  131. Bprint(bout, ") {\n");
  132. pcode(l->proc->right, 1);
  133. Bprint(bout, "}\n");
  134. def = 1;
  135. }
  136. if(l->builtin) {
  137. Bprint(bout, "builtin function\n");
  138. def = 1;
  139. }
  140. if(def == 0)
  141. Bprint(bout, "%s is undefined\n", l->name);
  142. }
  143. void
  144. slist(Node *n, int d)
  145. {
  146. if(n == 0)
  147. return;
  148. if(n->op == OLIST)
  149. Bprint(bout, "%.*s{\n", d-1, tabs);
  150. pcode(n, d);
  151. if(n->op == OLIST)
  152. Bprint(bout, "%.*s}\n", d-1, tabs);
  153. }
  154. void
  155. pcode(Node *n, int d)
  156. {
  157. Node *r, *l;
  158. if(n == 0)
  159. return;
  160. r = n->right;
  161. l = n->left;
  162. switch(n->op) {
  163. default:
  164. Bprint(bout, "%.*s", d, tabs);
  165. pexpr(n);
  166. Bprint(bout, ";\n");
  167. break;
  168. case OLIST:
  169. pcode(n->left, d);
  170. pcode(n->right, d);
  171. break;
  172. case OLOCAL:
  173. Bprint(bout, "%.*slocal", d, tabs);
  174. while(l) {
  175. Bprint(bout, " %s", l->sym->name);
  176. l = l->left;
  177. if(l == 0)
  178. Bprint(bout, ";\n");
  179. else
  180. Bprint(bout, ",");
  181. }
  182. break;
  183. case OCOMPLEX:
  184. Bprint(bout, "%.*scomplex %s %s;\n", d, tabs, n->sym->name, l->sym->name);
  185. break;
  186. case OIF:
  187. Bprint(bout, "%.*sif ", d, tabs);
  188. pexpr(l);
  189. d++;
  190. Bprint(bout, " then\n");
  191. if(r && r->op == OELSE) {
  192. slist(r->left, d);
  193. Bprint(bout, "%.*selse\n", d-1, tabs);
  194. slist(r->right, d);
  195. }
  196. else
  197. slist(r, d);
  198. break;
  199. case OWHILE:
  200. Bprint(bout, "%.*swhile ", d, tabs);
  201. pexpr(l);
  202. d++;
  203. Bprint(bout, " do\n");
  204. slist(r, d);
  205. break;
  206. case ORET:
  207. Bprint(bout, "%.*sreturn ", d, tabs);
  208. pexpr(l);
  209. Bprint(bout, ";\n");
  210. break;
  211. case ODO:
  212. Bprint(bout, "%.*sloop ", d, tabs);
  213. pexpr(l->left);
  214. Bprint(bout, ", ");
  215. pexpr(l->right);
  216. Bprint(bout, " do\n");
  217. slist(r, d+1);
  218. }
  219. }
  220. void
  221. pexpr(Node *n)
  222. {
  223. Node *r, *l;
  224. if(n == 0)
  225. return;
  226. r = n->right;
  227. l = n->left;
  228. switch(n->op) {
  229. case ONAME:
  230. Bprint(bout, "%s", n->sym->name);
  231. break;
  232. case OCONST:
  233. switch(n->type) {
  234. case TINT:
  235. Bprint(bout, "%d", (int)n->ival);
  236. break;
  237. case TFLOAT:
  238. Bprint(bout, "%g", n->fval);
  239. break;
  240. case TSTRING:
  241. pstr(n->string);
  242. break;
  243. case TLIST:
  244. break;
  245. }
  246. break;
  247. case OMUL:
  248. case ODIV:
  249. case OMOD:
  250. case OADD:
  251. case OSUB:
  252. case ORSH:
  253. case OLSH:
  254. case OLT:
  255. case OGT:
  256. case OLEQ:
  257. case OGEQ:
  258. case OEQ:
  259. case ONEQ:
  260. case OLAND:
  261. case OXOR:
  262. case OLOR:
  263. case OCAND:
  264. case OCOR:
  265. Bputc(bout, '(');
  266. pexpr(l);
  267. Bprint(bout, binop[n->op]);
  268. pexpr(r);
  269. Bputc(bout, ')');
  270. break;
  271. case OASGN:
  272. pexpr(l);
  273. Bprint(bout, binop[n->op]);
  274. pexpr(r);
  275. break;
  276. case OINDM:
  277. Bprint(bout, "*");
  278. pexpr(l);
  279. break;
  280. case OEDEC:
  281. Bprint(bout, "--");
  282. pexpr(l);
  283. break;
  284. case OEINC:
  285. Bprint(bout, "++");
  286. pexpr(l);
  287. break;
  288. case OPINC:
  289. pexpr(l);
  290. Bprint(bout, "++");
  291. break;
  292. case OPDEC:
  293. pexpr(l);
  294. Bprint(bout, "--");
  295. break;
  296. case ONOT:
  297. Bprint(bout, "!");
  298. pexpr(l);
  299. break;
  300. case OLIST:
  301. pexpr(l);
  302. if(r) {
  303. Bprint(bout, ",");
  304. pexpr(r);
  305. }
  306. break;
  307. case OCALL:
  308. pexpr(l);
  309. Bprint(bout, "(");
  310. pexpr(r);
  311. Bprint(bout, ")");
  312. break;
  313. case OCTRUCT:
  314. Bprint(bout, "{");
  315. pexpr(l);
  316. Bprint(bout, "}");
  317. break;
  318. case OHEAD:
  319. Bprint(bout, "head ");
  320. pexpr(l);
  321. break;
  322. case OTAIL:
  323. Bprint(bout, "tail ");
  324. pexpr(l);
  325. break;
  326. case OAPPEND:
  327. Bprint(bout, "append ");
  328. pexpr(l);
  329. Bprint(bout, ",");
  330. pexpr(r);
  331. break;
  332. case ODELETE:
  333. Bprint(bout, "delete ");
  334. pexpr(l);
  335. Bprint(bout, ",");
  336. pexpr(r);
  337. break;
  338. case ORET:
  339. Bprint(bout, "return ");
  340. pexpr(l);
  341. break;
  342. case OINDEX:
  343. pexpr(l);
  344. Bprint(bout, "[");
  345. pexpr(r);
  346. Bprint(bout, "]");
  347. break;
  348. case OINDC:
  349. Bprint(bout, "@");
  350. pexpr(l);
  351. break;
  352. case ODOT:
  353. pexpr(l);
  354. Bprint(bout, ".%s", n->sym->name);
  355. break;
  356. case OFRAME:
  357. Bprint(bout, "%s:%s", n->sym->name, l->sym->name);
  358. break;
  359. case OCAST:
  360. Bprint(bout, "(%s)", n->sym->name);
  361. pexpr(l);
  362. break;
  363. case OFMT:
  364. pexpr(l);
  365. Bprint(bout, "\\%c", (int)r->ival);
  366. break;
  367. case OEVAL:
  368. Bprint(bout, "eval ");
  369. pexpr(l);
  370. break;
  371. case OWHAT:
  372. Bprint(bout, "whatis");
  373. if(n->sym)
  374. Bprint(bout, " %s", n->sym->name);
  375. break;
  376. }
  377. }
  378. void
  379. pstr(String *s)
  380. {
  381. int i, c;
  382. Bputc(bout, '"');
  383. for(i = 0; i < s->len; i++) {
  384. c = s->string[i];
  385. switch(c) {
  386. case '\0':
  387. c = '0';
  388. break;
  389. case '\n':
  390. c = 'n';
  391. break;
  392. case '\r':
  393. c = 'r';
  394. break;
  395. case '\t':
  396. c = 't';
  397. break;
  398. case '\b':
  399. c = 'b';
  400. break;
  401. case '\f':
  402. c = 'f';
  403. break;
  404. case '\a':
  405. c = 'a';
  406. break;
  407. case '\v':
  408. c = 'v';
  409. break;
  410. case '\\':
  411. c = '\\';
  412. break;
  413. case '"':
  414. c = '"';
  415. break;
  416. default:
  417. Bputc(bout, c);
  418. continue;
  419. }
  420. Bputc(bout, '\\');
  421. Bputc(bout, c);
  422. }
  423. Bputc(bout, '"');
  424. }