Blob
1 #include <u.h>2 #include <libc.h>3 #include <bio.h>4 #include <ctype.h>5 #include <mach.h>6 #define Extern extern7 #include "acid.h"9 static char *binop[NUMO];11 static void12 initbinop(void)13 {14 binop[OMUL]= "*";15 binop[ODIV]= "/";16 binop[OMOD]= "%";17 binop[OADD]= "+";18 binop[OSUB]= "-";19 binop[ORSH]= ">>";20 binop[OLSH]= "<<";21 binop[OLT]= "<";22 binop[OGT]= ">";23 binop[OLEQ]= "<=";24 binop[OGEQ]= ">=";25 binop[OEQ]= "==";26 binop[ONEQ]= "!=";27 binop[OLAND]= "&";28 binop[OXOR]= "^";29 binop[OLOR]= "|";30 binop[OCAND]= "&&";31 binop[OCOR]= "||";32 binop[OASGN]= " = ";33 }35 static char *tabs = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";36 char *typenames[] = {37 "integer",38 "float",39 "string",40 "list",41 "code"42 };44 void45 initprint(void)46 {47 initbinop();48 }50 int51 cmp(const void *va, const void *vb)52 {53 char **a = (char**)va;54 char **b = (char**)vb;56 return strcmp(*a, *b);57 }59 void60 fundefs(void)61 {62 Lsym *l;63 char **vec;64 int i, j, n, max, col, f, g, s;66 max = 0;67 f = 0;68 g = 100;69 vec = malloc(sizeof(char*)*g);70 if(vec == 0)71 fatal("out of memory");73 for(i = 0; i < Hashsize; i++) {74 for(l = hash[i]; l; l = l->hash) {75 if(l->proc == 0 && l->builtin == 0)76 continue;77 n = strlen(l->name);78 if(n > max)79 max = n;80 if(f >= g) {81 g *= 2;82 vec = realloc(vec, sizeof(char*)*g);83 if(vec == 0)84 fatal("out of memory");85 }86 vec[f++] = l->name;87 }88 }89 qsort(vec, f, sizeof(char*), cmp);90 max++;91 col = 60/max;92 s = (f+col-1)/col;94 for(i = 0; i < s; i++) {95 for(j = i; j < f; j += s)96 Bprint(bout, "%-*s", max, vec[j]);97 Bprint(bout, "\n");98 }99 }101 void102 whatis(Lsym *l)103 {104 int t;105 int def;106 Type *ti;108 if(l == 0) {109 fundefs();110 return;111 }113 def = 0;114 if(l->v->set) {115 t = l->v->type;116 Bprint(bout, "%s variable", typenames[t]);117 if(t == TINT || t == TFLOAT)118 Bprint(bout, " format %c", l->v->store.fmt);119 if(l->v->store.comt)120 Bprint(bout, " complex %s",121 l->v->store.comt->base->name);122 Bputc(bout, '\n');123 def = 1;124 }125 if(l->lt) {126 Bprint(bout, "complex %s {\n", l->name);127 for(ti = l->lt; ti; ti = ti->next) {128 if(ti->type) {129 if(ti->fmt == 'a') {130 Bprint(bout, "\t%s %d %s;\n",131 ti->type->name, ti->offset,132 ti->tag->name);133 }134 else {135 Bprint(bout, "\t'%c' %s %d %s;\n",136 ti->fmt, ti->type->name, ti->offset,137 ti->tag->name);138 }139 }140 else141 Bprint(bout, "\t'%c' %d %s;\n",142 ti->fmt, ti->offset, ti->tag->name);143 }144 Bprint(bout, "};\n");145 def = 1;146 }147 if(l->proc) {148 Bprint(bout, "defn %s(", l->name);149 pexpr(l->proc->left);150 Bprint(bout, ") {\n");151 pcode(l->proc->right, 1);152 Bprint(bout, "}\n");153 def = 1;154 }155 if(l->builtin) {156 Bprint(bout, "builtin function\n");157 def = 1;158 }159 if(def == 0)160 Bprint(bout, "%s is undefined\n", l->name);161 }163 void164 slist(Node *n, int d)165 {166 if(n == 0)167 return;168 if(n->op == OLIST)169 Bprint(bout, "%.*s{\n", d-1, tabs);170 pcode(n, d);171 if(n->op == OLIST)172 Bprint(bout, "%.*s}\n", d-1, tabs);173 }175 void176 pcode(Node *n, int d)177 {178 Node *r, *l;180 if(n == 0)181 return;183 r = n->right;184 l = n->left;186 switch(n->op) {187 default:188 Bprint(bout, "%.*s", d, tabs);189 pexpr(n);190 Bprint(bout, ";\n");191 break;192 case OLIST:193 pcode(n->left, d);194 pcode(n->right, d);195 break;196 case OLOCAL:197 Bprint(bout, "%.*slocal", d, tabs);198 while(l) {199 Bprint(bout, " %s", l->sym->name);200 l = l->left;201 if(l == 0)202 Bprint(bout, ";\n");203 else204 Bprint(bout, ",");205 }206 break;207 case OCOMPLEX:208 Bprint(bout, "%.*scomplex %s %s;\n", d, tabs, n->sym->name, l->sym->name);209 break;210 case OIF:211 Bprint(bout, "%.*sif ", d, tabs);212 pexpr(l);213 d++;214 Bprint(bout, " then\n");215 if(r && r->op == OELSE) {216 slist(r->left, d);217 Bprint(bout, "%.*selse\n", d-1, tabs);218 slist(r->right, d);219 }220 else221 slist(r, d);222 break;223 case OWHILE:224 Bprint(bout, "%.*swhile ", d, tabs);225 pexpr(l);226 d++;227 Bprint(bout, " do\n");228 slist(r, d);229 break;230 case ORET:231 Bprint(bout, "%.*sreturn ", d, tabs);232 pexpr(l);233 Bprint(bout, ";\n");234 break;235 case ODO:236 Bprint(bout, "%.*sloop ", d, tabs);237 pexpr(l->left);238 Bprint(bout, ", ");239 pexpr(l->right);240 Bprint(bout, " do\n");241 slist(r, d+1);242 }243 }245 void246 pexpr(Node *n)247 {248 Node *r, *l;250 if(n == 0)251 return;253 r = n->right;254 l = n->left;256 switch(n->op) {257 case ONAME:258 Bprint(bout, "%s", n->sym->name);259 break;260 case OCONST:261 switch(n->type) {262 case TINT:263 Bprint(bout, "%d", (int)n->store.u.ival);264 break;265 case TFLOAT:266 Bprint(bout, "%g", n->store.u.fval);267 break;268 case TSTRING:269 pstr(n->store.u.string);270 break;271 case TLIST:272 break;273 }274 break;275 case OMUL:276 case ODIV:277 case OMOD:278 case OADD:279 case OSUB:280 case ORSH:281 case OLSH:282 case OLT:283 case OGT:284 case OLEQ:285 case OGEQ:286 case OEQ:287 case ONEQ:288 case OLAND:289 case OXOR:290 case OLOR:291 case OCAND:292 case OCOR:293 Bputc(bout, '(');294 pexpr(l);295 Bprint(bout, binop[(uchar)n->op]);296 pexpr(r);297 Bputc(bout, ')');298 break;299 case OASGN:300 pexpr(l);301 Bprint(bout, binop[(uchar)n->op]);302 pexpr(r);303 break;304 case OINDM:305 Bprint(bout, "*");306 pexpr(l);307 break;308 case OEDEC:309 Bprint(bout, "--");310 pexpr(l);311 break;312 case OEINC:313 Bprint(bout, "++");314 pexpr(l);315 break;316 case OPINC:317 pexpr(l);318 Bprint(bout, "++");319 break;320 case OPDEC:321 pexpr(l);322 Bprint(bout, "--");323 break;324 case ONOT:325 Bprint(bout, "!");326 pexpr(l);327 break;328 case OLIST:329 pexpr(l);330 if(r) {331 Bprint(bout, ",");332 pexpr(r);333 }334 break;335 case OCALL:336 pexpr(l);337 Bprint(bout, "(");338 pexpr(r);339 Bprint(bout, ")");340 break;341 case OCTRUCT:342 Bprint(bout, "{");343 pexpr(l);344 Bprint(bout, "}");345 break;346 case OHEAD:347 Bprint(bout, "head ");348 pexpr(l);349 break;350 case OTAIL:351 Bprint(bout, "tail ");352 pexpr(l);353 break;354 case OAPPEND:355 Bprint(bout, "append ");356 pexpr(l);357 Bprint(bout, ",");358 pexpr(r);359 break;360 case ODELETE:361 Bprint(bout, "delete ");362 pexpr(l);363 Bprint(bout, ",");364 pexpr(r);365 break;366 case ORET:367 Bprint(bout, "return ");368 pexpr(l);369 break;370 case OINDEX:371 pexpr(l);372 Bprint(bout, "[");373 pexpr(r);374 Bprint(bout, "]");375 break;376 case OINDC:377 Bprint(bout, "@");378 pexpr(l);379 break;380 case ODOT:381 pexpr(l);382 Bprint(bout, ".%s", n->sym->name);383 break;384 case OFRAME:385 Bprint(bout, "%s:%s", n->sym->name, l->sym->name);386 break;387 case OCAST:388 Bprint(bout, "(%s)", n->sym->name);389 pexpr(l);390 break;391 case OFMT:392 pexpr(l);393 Bprint(bout, "\\%c", (int)r->store.u.ival);394 break;395 case OEVAL:396 Bprint(bout, "eval ");397 pexpr(l);398 break;399 case OWHAT:400 Bprint(bout, "whatis");401 if(n->sym)402 Bprint(bout, " %s", n->sym->name);403 break;404 case OUPLUS:405 Bprint(bout, "+");406 pexpr(l);407 break;408 }409 }411 void412 pstr(String *s)413 {414 int i, c;416 Bputc(bout, '"');417 for(i = 0; i < s->len; i++) {418 c = s->string[i];419 switch(c) {420 case '\0':421 c = '0';422 break;423 case '\n':424 c = 'n';425 break;426 case '\r':427 c = 'r';428 break;429 case '\t':430 c = 't';431 break;432 case '\b':433 c = 'b';434 break;435 case '\f':436 c = 'f';437 break;438 case '\a':439 c = 'a';440 break;441 case '\v':442 c = 'v';443 break;444 case '\\':445 c = '\\';446 break;447 case '"':448 c = '"';449 break;450 default:451 Bputc(bout, c);452 continue;453 }454 Bputc(bout, '\\');455 Bputc(bout, c);456 }457 Bputc(bout, '"');458 }