123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445 |
- #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(void *va, void *vb)
- {
- char **a = va;
- char **b = 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->fmt);
- if(l->v->comt)
- Bprint(bout, " complex %s", l->v->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, "%lld", n->ival);
- break;
- case TFLOAT:
- Bprint(bout, "%g", n->fval);
- break;
- case TSTRING:
- pstr(n->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[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->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, '"');
- }
|