print.c (7127B)
1 #include <u.h> 2 #include <libc.h> 3 #include <bio.h> 4 #include <ctype.h> 5 #include <mach.h> 6 #define Extern extern 7 #include "acid.h" 8 9 static char *binop[NUMO]; 10 11 static void 12 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 } 34 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 }; 43 44 void 45 initprint(void) 46 { 47 initbinop(); 48 } 49 50 int 51 cmp(const void *va, const void *vb) 52 { 53 char **a = (char**)va; 54 char **b = (char**)vb; 55 56 return strcmp(*a, *b); 57 } 58 59 void 60 fundefs(void) 61 { 62 Lsym *l; 63 char **vec; 64 int i, j, n, max, col, f, g, s; 65 66 max = 0; 67 f = 0; 68 g = 100; 69 vec = malloc(sizeof(char*)*g); 70 if(vec == 0) 71 fatal("out of memory"); 72 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; 93 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 } 100 101 void 102 whatis(Lsym *l) 103 { 104 int t; 105 int def; 106 Type *ti; 107 108 if(l == 0) { 109 fundefs(); 110 return; 111 } 112 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 else 141 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 } 162 163 void 164 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 } 174 175 void 176 pcode(Node *n, int d) 177 { 178 Node *r, *l; 179 180 if(n == 0) 181 return; 182 183 r = n->right; 184 l = n->left; 185 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 else 204 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 else 221 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 } 244 245 void 246 pexpr(Node *n) 247 { 248 Node *r, *l; 249 250 if(n == 0) 251 return; 252 253 r = n->right; 254 l = n->left; 255 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 } 410 411 void 412 pstr(String *s) 413 { 414 int i, c; 415 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 }