acid
This commit is contained in:
parent
22a7368ef2
commit
564ca709d0
14 changed files with 6578 additions and 0 deletions
446
src/cmd/acid/print.c
Normal file
446
src/cmd/acid/print.c
Normal file
|
|
@ -0,0 +1,446 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <bio.h>
|
||||
#include <ctype.h>
|
||||
#include <mach.h>
|
||||
#define Extern extern
|
||||
#include "acid.h"
|
||||
|
||||
static char *binop[] =
|
||||
{
|
||||
[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[] =
|
||||
{
|
||||
[TINT] "integer",
|
||||
[TFLOAT] "float",
|
||||
[TSTRING] "string",
|
||||
[TLIST] "list",
|
||||
[TCODE] "code",
|
||||
};
|
||||
|
||||
int
|
||||
cmp(const void *va, const void *vb)
|
||||
{
|
||||
char **a = (char**)va;
|
||||
char **b = (char**)vb;
|
||||
|
||||
return strcmp(*a, *b);
|
||||
}
|
||||
|
||||
void
|
||||
fundefs(void)
|
||||
{
|
||||
Lsym *l;
|
||||
char **vec;
|
||||
int i, j, n, max, col, f, g, s;
|
||||
|
||||
max = 0;
|
||||
f = 0;
|
||||
g = 100;
|
||||
vec = malloc(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->store.fmt);
|
||||
if(l->v->store.comt)
|
||||
Bprint(bout, " complex %s",
|
||||
l->v->store.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");
|
||||
if(r && r->op == OELSE) {
|
||||
slist(r->left, d);
|
||||
Bprint(bout, "%.*selse\n", d-1, tabs);
|
||||
slist(r->right, d);
|
||||
}
|
||||
else
|
||||
slist(r, d);
|
||||
break;
|
||||
case OWHILE:
|
||||
Bprint(bout, "%.*swhile ", d, tabs);
|
||||
pexpr(l);
|
||||
d++;
|
||||
Bprint(bout, " do\n");
|
||||
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->store.u.ival);
|
||||
break;
|
||||
case TFLOAT:
|
||||
Bprint(bout, "%g", n->store.u.fval);
|
||||
break;
|
||||
case TSTRING:
|
||||
pstr(n->store.u.string);
|
||||
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[(uchar)n->op]);
|
||||
pexpr(r);
|
||||
Bputc(bout, ')');
|
||||
break;
|
||||
case OASGN:
|
||||
pexpr(l);
|
||||
Bprint(bout, binop[(uchar)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->store.u.ival);
|
||||
break;
|
||||
case OEVAL:
|
||||
Bprint(bout, "eval ");
|
||||
pexpr(l);
|
||||
break;
|
||||
case OWHAT:
|
||||
Bprint(bout, "whatis");
|
||||
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, '"');
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue