summaryrefslogtreecommitdiff
path: root/utils/acid/print.c
diff options
context:
space:
mode:
authorCharles.Forsyth <devnull@localhost>2006-12-22 21:39:35 +0000
committerCharles.Forsyth <devnull@localhost>2006-12-22 21:39:35 +0000
commit74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a (patch)
treec6e220ba61db3a6ea4052e6841296d829654e664 /utils/acid/print.c
parent46439007cf417cbd9ac8049bb4122c890097a0fa (diff)
20060303
Diffstat (limited to 'utils/acid/print.c')
-rw-r--r--utils/acid/print.c444
1 files changed, 444 insertions, 0 deletions
diff --git a/utils/acid/print.c b/utils/acid/print.c
new file mode 100644
index 00000000..8043fcd7
--- /dev/null
+++ b/utils/acid/print.c
@@ -0,0 +1,444 @@
+#include <lib9.h>
+#include <bio.h>
+#include <ctype.h>
+#include "mach.h"
+#define Extern extern
+#include "acid.h"
+
+static char *binop[] =
+{
+ 0,
+ 0,
+ "*", /* [OMUL] "*", */
+ "/", /* [ODIV] "/", */
+ "%", /* [OMOD] "%", */
+ "+", /* [OADD] "+", */
+ "-", /* [OSUB] "-", */
+ ">>", /* [ORSH] ">>", */
+ "<<", /* [OLSH] "<<", */
+ "<", /* [OLT] "<", */
+ ">", /* [OGT] ">", */
+ "<=", /* [OLEQ] "<=", */
+ ">=", /* [OGEQ] ">=", */
+ "==", /* [OEQ] "==", */
+ "!=", /* [ONEQ] "!=", */
+ "&", /* [OLAND] "&", */
+ "^", /* [OXOR] "^", */
+ "|", /* [OLOR] "|", */
+ "&&", /* [OCAND] "&&", */
+ "||", /* [OCOR] "||", */
+ " = ", /* [OASGN] " = ", */
+};
+
+static char *tabs = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
+char *typenames[] =
+{
+ "integer", /* [TINT] "integer", */
+ "float", /* [TFLOAT] "float", */
+ "string", /* [TSTRING] "string", */
+ "list", /* [TLIST] "list", */
+ "code", /* [TCODE] "code", */
+};
+
+int
+cmp(const void *a, const void *b)
+{
+ return strcmp(*(char**)a, *(char**)b);
+}
+
+void
+fundefs(void)
+{
+ Lsym *l;
+ char **vec;
+ int i, j, n, max, col, f, g, s;
+
+ max = 0;
+ f = 0;
+ g = 100;
+ vec = gmalloc(sizeof(char*)*g);
+ if(vec == 0)
+ fatal("out of memory");
+
+ for(i = 0; i < Hashsize; i++) {
+ for(l = hash[i]; l; l = l->hash) {
+ if(l->proc == 0 && l->builtin == 0)
+ continue;
+ n = strlen(l->name);
+ if(n > max)
+ max = n;
+ if(f >= g) {
+ g *= 2;
+ vec = realloc(vec, sizeof(char*)*g);
+ if(vec == 0)
+ fatal("out of memory");
+ }
+ vec[f++] = l->name;
+ }
+ }
+ qsort(vec, f, sizeof(char*), cmp);
+ max++;
+ col = 60/max;
+ s = (f+col-1)/col;
+
+ for(i = 0; i < s; i++) {
+ for(j = i; j < f; j += s)
+ Bprint(bout, "%-*s", max, vec[j]);
+ Bprint(bout, "\n");
+ }
+}
+
+void
+whatis(Lsym *l)
+{
+ int t;
+ int def;
+ Type *ti;
+
+ if(l == 0) {
+ fundefs();
+ return;
+ }
+
+ def = 0;
+ if(l->v->set) {
+ t = l->v->type;
+ Bprint(bout, "%s variable", typenames[t]);
+ if(t == TINT || t == TFLOAT)
+ Bprint(bout, " format %c", l->v->vstore.fmt);
+ if(l->v->vstore.comt)
+ Bprint(bout, " complex %s",
+ l->v->vstore.comt->base->name);
+ Bputc(bout, '\n');
+ def = 1;
+ }
+ if(l->lt) {
+ Bprint(bout, "complex %s {\n", l->name);
+ for(ti = l->lt; ti; ti = ti->next) {
+ if(ti->type) {
+ if(ti->fmt == 'a') {
+ Bprint(bout, "\t%s %d %s;\n",
+ ti->type->name, ti->offset,
+ ti->tag->name);
+ }
+ else {
+ Bprint(bout, "\t'%c' %s %d %s;\n",
+ ti->fmt, ti->type->name, ti->offset,
+ ti->tag->name);
+ }
+ }
+ else
+ Bprint(bout, "\t'%c' %d %s;\n",
+ ti->fmt, ti->offset, ti->tag->name);
+ }
+ Bprint(bout, "};\n");
+ def = 1;
+ }
+ if(l->proc) {
+ Bprint(bout, "defn %s(", l->name);
+ pexpr(l->proc->left);
+ Bprint(bout, ") {\n");
+ pcode(l->proc->right, 1);
+ Bprint(bout, "}\n");
+ def = 1;
+ }
+ if(l->builtin) {
+ Bprint(bout, "builtin function\n");
+ def = 1;
+ }
+ if(def == 0)
+ Bprint(bout, "%s is undefined\n", l->name);
+}
+
+void
+slist(Node *n, int d)
+{
+ if(n == 0)
+ return;
+ if(n->op == OLIST)
+ Bprint(bout, "%.*s{\n", d-1, tabs);
+ pcode(n, d);
+ if(n->op == OLIST)
+ Bprint(bout, "%.*s}\n", d-1, tabs);
+}
+
+void
+pcode(Node *n, int d)
+{
+ Node *r, *l;
+
+ if(n == 0)
+ return;
+
+ r = n->right;
+ l = n->left;
+
+ switch(n->op) {
+ default:
+ Bprint(bout, "%.*s", d, tabs);
+ pexpr(n);
+ Bprint(bout, ";\n");
+ break;
+ case OLIST:
+ pcode(n->left, d);
+ pcode(n->right, d);
+ break;
+ case OLOCAL:
+ Bprint(bout, "%.*slocal", d, tabs);
+ while(l) {
+ Bprint(bout, " %s", l->sym->name);
+ l = l->left;
+ if(l == 0)
+ Bprint(bout, ";\n");
+ else
+ Bprint(bout, ",");
+ }
+ break;
+ case OCOMPLEX:
+ Bprint(bout, "%.*scomplex %s %s;\n", d, tabs, n->sym->name, l->sym->name);
+ break;
+ case OIF:
+ Bprint(bout, "%.*sif ", d, tabs);
+ pexpr(l);
+ d++;
+ Bprint(bout, " then\n", d, tabs);
+ if(r && r->op == OELSE) {
+ slist(r->left, d);
+ Bprint(bout, "%.*selse\n", d-1, tabs, d, tabs);
+ slist(r->right, d);
+ }
+ else
+ slist(r, d);
+ break;
+ case OWHILE:
+ Bprint(bout, "%.*swhile ", d, tabs);
+ pexpr(l);
+ d++;
+ Bprint(bout, " do\n", d, tabs);
+ slist(r, d);
+ break;
+ case ORET:
+ Bprint(bout, "%.*sreturn ", d, tabs);
+ pexpr(l);
+ Bprint(bout, ";\n");
+ break;
+ case ODO:
+ Bprint(bout, "%.*sloop ", d, tabs);
+ pexpr(l->left);
+ Bprint(bout, ", ");
+ pexpr(l->right);
+ Bprint(bout, " do\n");
+ slist(r, d+1);
+ }
+}
+
+void
+pexpr(Node *n)
+{
+ Node *r, *l;
+
+ if(n == 0)
+ return;
+
+ r = n->right;
+ l = n->left;
+
+ switch(n->op) {
+ case ONAME:
+ Bprint(bout, "%s", n->sym->name);
+ break;
+ case OCONST:
+ switch(n->type) {
+ case TINT:
+ Bprint(bout, "%d", (int)n->nstore.u0.sival);
+ break;
+ case TFLOAT:
+ Bprint(bout, "%g", n->nstore.u0.sfval);
+ break;
+ case TSTRING:
+ pstr(n->nstore.u0.sstring);
+ break;
+ case TLIST:
+ break;
+ }
+ break;
+ case OMUL:
+ case ODIV:
+ case OMOD:
+ case OADD:
+ case OSUB:
+ case ORSH:
+ case OLSH:
+ case OLT:
+ case OGT:
+ case OLEQ:
+ case OGEQ:
+ case OEQ:
+ case ONEQ:
+ case OLAND:
+ case OXOR:
+ case OLOR:
+ case OCAND:
+ case OCOR:
+ Bputc(bout, '(');
+ pexpr(l);
+ Bprint(bout, binop[n->op]);
+ pexpr(r);
+ Bputc(bout, ')');
+ break;
+ case OASGN:
+ pexpr(l);
+ Bprint(bout, binop[n->op]);
+ pexpr(r);
+ break;
+ case OINDM:
+ Bprint(bout, "*");
+ pexpr(l);
+ break;
+ case OEDEC:
+ Bprint(bout, "--");
+ pexpr(l);
+ break;
+ case OEINC:
+ Bprint(bout, "++");
+ pexpr(l);
+ break;
+ case OPINC:
+ pexpr(l);
+ Bprint(bout, "++");
+ break;
+ case OPDEC:
+ pexpr(l);
+ Bprint(bout, "--");
+ break;
+ case ONOT:
+ Bprint(bout, "!");
+ pexpr(l);
+ break;
+ case OLIST:
+ pexpr(l);
+ if(r) {
+ Bprint(bout, ",");
+ pexpr(r);
+ }
+ break;
+ case OCALL:
+ pexpr(l);
+ Bprint(bout, "(");
+ pexpr(r);
+ Bprint(bout, ")");
+ break;
+ case OCTRUCT:
+ Bprint(bout, "{");
+ pexpr(l);
+ Bprint(bout, "}");
+ break;
+ case OHEAD:
+ Bprint(bout, "head ");
+ pexpr(l);
+ break;
+ case OTAIL:
+ Bprint(bout, "tail ");
+ pexpr(l);
+ break;
+ case OAPPEND:
+ Bprint(bout, "append ");
+ pexpr(l);
+ Bprint(bout, ",");
+ pexpr(r);
+ break;
+ case ODELETE:
+ Bprint(bout, "delete ");
+ pexpr(l);
+ Bprint(bout, ",");
+ pexpr(r);
+ break;
+ case ORET:
+ Bprint(bout, "return ");
+ pexpr(l);
+ break;
+ case OINDEX:
+ pexpr(l);
+ Bprint(bout, "[");
+ pexpr(r);
+ Bprint(bout, "]");
+ break;
+ case OINDC:
+ Bprint(bout, "@");
+ pexpr(l);
+ break;
+ case ODOT:
+ pexpr(l);
+ Bprint(bout, ".%s", n->sym->name);
+ break;
+ case OFRAME:
+ Bprint(bout, "%s:%s", n->sym->name, l->sym->name);
+ break;
+ case OCAST:
+ Bprint(bout, "(%s)", n->sym->name);
+ pexpr(l);
+ break;
+ case OFMT:
+ pexpr(l);
+ Bprint(bout, "\\%c", (int)r->nstore.u0.sival);
+ break;
+ case OEVAL:
+ Bprint(bout, "eval ");
+ pexpr(l);
+ break;
+ case OWHAT:
+ Bprint(bout, "whatis", n->sym->name);
+ if(n->sym)
+ Bprint(bout, " %s", n->sym->name);
+ break;
+ }
+}
+
+void
+pstr(String *s)
+{
+ int i, c;
+
+ Bputc(bout, '"');
+ for(i = 0; i < s->len; i++) {
+ c = s->string[i];
+ switch(c) {
+ case '\0':
+ c = '0';
+ break;
+ case '\n':
+ c = 'n';
+ break;
+ case '\r':
+ c = 'r';
+ break;
+ case '\t':
+ c = 't';
+ break;
+ case '\b':
+ c = 'b';
+ break;
+ case '\f':
+ c = 'f';
+ break;
+ case '\a':
+ c = 'a';
+ break;
+ case '\v':
+ c = 'v';
+ break;
+ case '\\':
+ c = '\\';
+ break;
+ case '"':
+ c = '"';
+ break;
+ default:
+ Bputc(bout, c);
+ continue;
+ }
+ Bputc(bout, '\\');
+ Bputc(bout, c);
+ }
+ Bputc(bout, '"');
+}