diff options
Diffstat (limited to 'utils/acid/print.c')
| -rw-r--r-- | utils/acid/print.c | 444 |
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, '"'); +} |
