#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", */}; intcmp(const void *a, const void *b){ return strcmp(*(char**)a, *(char**)b);} voidfundefs(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"); }} voidwhatis(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);} voidslist(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);} voidpcode(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); }} voidpexpr(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; }} voidpstr(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, '"');}
#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, '"');
}