Blob


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