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