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