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