print.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  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", l->v->comt->base->name);
  102. Bputc(bout, '\n');
  103. def = 1;
  104. }
  105. if(l->lt) {
  106. Bprint(bout, "complex %s {\n", l->name);
  107. for(ti = l->lt; ti; ti = ti->next) {
  108. if(ti->type) {
  109. if(ti->fmt == 'a') {
  110. Bprint(bout, "\t%s %d %s;\n",
  111. ti->type->name, ti->offset,
  112. ti->tag->name);
  113. }
  114. else {
  115. Bprint(bout, "\t'%c' %s %d %s;\n",
  116. ti->fmt, ti->type->name, ti->offset,
  117. ti->tag->name);
  118. }
  119. }
  120. else
  121. Bprint(bout, "\t'%c' %d %s;\n",
  122. ti->fmt, ti->offset, ti->tag->name);
  123. }
  124. Bprint(bout, "};\n");
  125. def = 1;
  126. }
  127. if(l->proc) {
  128. Bprint(bout, "defn %s(", l->name);
  129. pexpr(l->proc->left);
  130. Bprint(bout, ") {\n");
  131. pcode(l->proc->right, 1);
  132. Bprint(bout, "}\n");
  133. def = 1;
  134. }
  135. if(l->builtin) {
  136. Bprint(bout, "builtin function\n");
  137. def = 1;
  138. }
  139. if(def == 0)
  140. Bprint(bout, "%s is undefined\n", l->name);
  141. }
  142. void
  143. slist(Node *n, int d)
  144. {
  145. if(n == 0)
  146. return;
  147. if(n->op == OLIST)
  148. Bprint(bout, "%.*s{\n", d-1, tabs);
  149. pcode(n, d);
  150. if(n->op == OLIST)
  151. Bprint(bout, "%.*s}\n", d-1, tabs);
  152. }
  153. void
  154. pcode(Node *n, int d)
  155. {
  156. Node *r, *l;
  157. if(n == 0)
  158. return;
  159. r = n->right;
  160. l = n->left;
  161. switch(n->op) {
  162. default:
  163. Bprint(bout, "%.*s", d, tabs);
  164. pexpr(n);
  165. Bprint(bout, ";\n");
  166. break;
  167. case OLIST:
  168. pcode(n->left, d);
  169. pcode(n->right, d);
  170. break;
  171. case OLOCAL:
  172. Bprint(bout, "%.*slocal", d, tabs);
  173. while(l) {
  174. Bprint(bout, " %s", l->sym->name);
  175. l = l->left;
  176. if(l == 0)
  177. Bprint(bout, ";\n");
  178. else
  179. Bprint(bout, ",");
  180. }
  181. break;
  182. case OCOMPLEX:
  183. Bprint(bout, "%.*scomplex %s %s;\n", d, tabs, n->sym->name, l->sym->name);
  184. break;
  185. case OIF:
  186. Bprint(bout, "%.*sif ", d, tabs);
  187. pexpr(l);
  188. d++;
  189. Bprint(bout, " then\n");
  190. if(r && r->op == OELSE) {
  191. slist(r->left, d);
  192. Bprint(bout, "%.*selse\n", d-1, tabs);
  193. slist(r->right, d);
  194. }
  195. else
  196. slist(r, d);
  197. break;
  198. case OWHILE:
  199. Bprint(bout, "%.*swhile ", d, tabs);
  200. pexpr(l);
  201. d++;
  202. Bprint(bout, " do\n");
  203. slist(r, d);
  204. break;
  205. case ORET:
  206. Bprint(bout, "%.*sreturn ", d, tabs);
  207. pexpr(l);
  208. Bprint(bout, ";\n");
  209. break;
  210. case ODO:
  211. Bprint(bout, "%.*sloop ", d, tabs);
  212. pexpr(l->left);
  213. Bprint(bout, ", ");
  214. pexpr(l->right);
  215. Bprint(bout, " do\n");
  216. slist(r, d+1);
  217. }
  218. }
  219. void
  220. pexpr(Node *n)
  221. {
  222. Node *r, *l;
  223. if(n == 0)
  224. return;
  225. r = n->right;
  226. l = n->left;
  227. switch(n->op) {
  228. case ONAME:
  229. Bprint(bout, "%s", n->sym->name);
  230. break;
  231. case OCONST:
  232. switch(n->type) {
  233. case TINT:
  234. Bprint(bout, "%lld", n->ival);
  235. break;
  236. case TFLOAT:
  237. Bprint(bout, "%g", n->fval);
  238. break;
  239. case TSTRING:
  240. pstr(n->string);
  241. break;
  242. case TLIST:
  243. break;
  244. }
  245. break;
  246. case OMUL:
  247. case ODIV:
  248. case OMOD:
  249. case OADD:
  250. case OSUB:
  251. case ORSH:
  252. case OLSH:
  253. case OLT:
  254. case OGT:
  255. case OLEQ:
  256. case OGEQ:
  257. case OEQ:
  258. case ONEQ:
  259. case OLAND:
  260. case OXOR:
  261. case OLOR:
  262. case OCAND:
  263. case OCOR:
  264. Bputc(bout, '(');
  265. pexpr(l);
  266. Bprint(bout, binop[n->op]);
  267. pexpr(r);
  268. Bputc(bout, ')');
  269. break;
  270. case OASGN:
  271. pexpr(l);
  272. Bprint(bout, binop[n->op]);
  273. pexpr(r);
  274. break;
  275. case OINDM:
  276. Bprint(bout, "*");
  277. pexpr(l);
  278. break;
  279. case OEDEC:
  280. Bprint(bout, "--");
  281. pexpr(l);
  282. break;
  283. case OEINC:
  284. Bprint(bout, "++");
  285. pexpr(l);
  286. break;
  287. case OPINC:
  288. pexpr(l);
  289. Bprint(bout, "++");
  290. break;
  291. case OPDEC:
  292. pexpr(l);
  293. Bprint(bout, "--");
  294. break;
  295. case ONOT:
  296. Bprint(bout, "!");
  297. pexpr(l);
  298. break;
  299. case OLIST:
  300. pexpr(l);
  301. if(r) {
  302. Bprint(bout, ",");
  303. pexpr(r);
  304. }
  305. break;
  306. case OCALL:
  307. pexpr(l);
  308. Bprint(bout, "(");
  309. pexpr(r);
  310. Bprint(bout, ")");
  311. break;
  312. case OCTRUCT:
  313. Bprint(bout, "{");
  314. pexpr(l);
  315. Bprint(bout, "}");
  316. break;
  317. case OHEAD:
  318. Bprint(bout, "head ");
  319. pexpr(l);
  320. break;
  321. case OTAIL:
  322. Bprint(bout, "tail ");
  323. pexpr(l);
  324. break;
  325. case OAPPEND:
  326. Bprint(bout, "append ");
  327. pexpr(l);
  328. Bprint(bout, ",");
  329. pexpr(r);
  330. break;
  331. case ODELETE:
  332. Bprint(bout, "delete ");
  333. pexpr(l);
  334. Bprint(bout, ",");
  335. pexpr(r);
  336. break;
  337. case ORET:
  338. Bprint(bout, "return ");
  339. pexpr(l);
  340. break;
  341. case OINDEX:
  342. pexpr(l);
  343. Bprint(bout, "[");
  344. pexpr(r);
  345. Bprint(bout, "]");
  346. break;
  347. case OINDC:
  348. Bprint(bout, "@");
  349. pexpr(l);
  350. break;
  351. case ODOT:
  352. pexpr(l);
  353. Bprint(bout, ".%s", n->sym->name);
  354. break;
  355. case OFRAME:
  356. Bprint(bout, "%s:%s", n->sym->name, l->sym->name);
  357. break;
  358. case OCAST:
  359. Bprint(bout, "(%s)", n->sym->name);
  360. pexpr(l);
  361. break;
  362. case OFMT:
  363. pexpr(l);
  364. Bprint(bout, "\\%c", (int)r->ival);
  365. break;
  366. case OEVAL:
  367. Bprint(bout, "eval ");
  368. pexpr(l);
  369. break;
  370. case OWHAT:
  371. Bprint(bout, "whatis");
  372. if(n->sym)
  373. Bprint(bout, " %s", n->sym->name);
  374. break;
  375. }
  376. }
  377. void
  378. pstr(String *s)
  379. {
  380. int i, c;
  381. Bputc(bout, '"');
  382. for(i = 0; i < s->len; i++) {
  383. c = s->string[i];
  384. switch(c) {
  385. case '\0':
  386. c = '0';
  387. break;
  388. case '\n':
  389. c = 'n';
  390. break;
  391. case '\r':
  392. c = 'r';
  393. break;
  394. case '\t':
  395. c = 't';
  396. break;
  397. case '\b':
  398. c = 'b';
  399. break;
  400. case '\f':
  401. c = 'f';
  402. break;
  403. case '\a':
  404. c = 'a';
  405. break;
  406. case '\v':
  407. c = 'v';
  408. break;
  409. case '\\':
  410. c = '\\';
  411. break;
  412. case '"':
  413. c = '"';
  414. break;
  415. default:
  416. Bputc(bout, c);
  417. continue;
  418. }
  419. Bputc(bout, '\\');
  420. Bputc(bout, c);
  421. }
  422. Bputc(bout, '"');
  423. }