#include #include #include #include #include #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"; static char *type[] = { [TINT] "integer", [TFLOAT] "float", [TSTRING] "string", [TLIST] "list", }; void whatis(Lsym *l) { int t; int def; Type *ti; def = 0; if(l->v->set) { t = l->v->type; Bprint(bout, "%s variable", type[t]); if(t == TINT || t == TFLOAT) Bprint(bout, " format %c", l->v->fmt); Bputc(bout, '\n'); def = 1; } if(l->lt) { Bprint(bout, "complex {\n"); for(ti = l->lt; ti; ti = ti->next) Bprint(bout, "\t%s %s\n", ti->type, ti->name); Bprint(bout, "}\n"); def = 1; } if(l->proc) { Bprint(bout, "defn %s(", l->name); pexpr(l->proc->left); Bprint(bout, ")\n{\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 %s;\n", d, tabs, n->sym->name); 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", 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: 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 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: fatal("dot"); case OFRAME: Bprint(bout, "%s:%s", n->sym->name, r->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, '"'); }