1 #define EXTERN 2 3 #include "cc.h" 4 5 /* 6 * locals, parameters, globals etc of the same name should work ok without having 7 * to duplicate Syms because the details are on the containing Nodes 8 */ 9 10 #define SZ_CHAR 1 11 #define SZ_SHORT 2 12 #define SZ_INT 4 13 #define SZ_LONG 4 14 #define SZ_FLOAT 4 15 #define SZ_IND 4 16 #define SZ_VLONG 8 17 #define SZ_DOUBLE 8 18 19 char buf[128], mbuf[128]; 20 static Sym *sysop, *bioop, *libcop; 21 static int again; 22 23 #define STAR 0x80 24 #define RET 0x80 25 26 #define LARR (-1729) 27 28 static void swalk(void); 29 static int isdec(Node*); 30 static int isconst(Node*, vlong); 31 static int cktype(Node*, Node*, int, int); 32 static void addnode(int, Node*); 33 static int argpos(Node*, Node*); 34 static void setdec(Sym*, Type*); 35 static Type* tcp(Type*); 36 static int isadt(Type*); 37 static void aargs(Node*); 38 static int iteq(Type*, Type*); 39 static Node* arg(Node*, int); 40 static void etgen2(Sym*); 41 static Node* ckneg(Node*); 42 static Sym* suename(Type*); 43 static int isnil(Node*); 44 static void sliceasgn(Node*); 45 static Node* lastn(Node*); 46 static char* hasm(void); 47 static void prn(Node*, int); 48 static int isfn(Type*); 49 50 schar ewidth[NTYPE] = 51 { 52 -1, /* [TXXX] */ 53 SZ_CHAR, /* [TCHAR] */ 54 SZ_CHAR, /* [TUCHAR] */ 55 SZ_SHORT, /* [TSHORT] */ 56 SZ_SHORT, /* [TUSHORT] */ 57 SZ_INT, /* [TINT] */ 58 SZ_INT, /* [TUINT] */ 59 SZ_LONG, /* [TLONG] */ 60 SZ_LONG, /* [TULONG] */ 61 SZ_VLONG, /* [TVLONG] */ 62 SZ_VLONG, /* [TUVLONG] */ 63 SZ_FLOAT, /* [TFLOAT] */ 64 SZ_DOUBLE, /* [TDOUBLE] */ 65 SZ_IND, /* [TIND] */ 66 0, /* [TFUNC] */ 67 -1, /* [TARRAY] */ 68 0, /* [TVOID] */ 69 -1, /* [TSTRUCT] */ 70 -1, /* [TUNION] */ 71 SZ_INT, /* [TENUM] */ 72 }; 73 74 long ncast[NTYPE] = 75 { 76 0, /* [TXXX] */ 77 BCHAR|BUCHAR, /* [TCHAR] */ 78 BCHAR|BUCHAR, /* [TUCHAR] */ 79 BSHORT|BUSHORT, /* [TSHORT] */ 80 BSHORT|BUSHORT, /* [TUSHORT] */ 81 BINT|BUINT|BLONG|BULONG|BIND, /* [TINT] */ 82 BINT|BUINT|BLONG|BULONG|BIND, /* [TUINT] */ 83 BINT|BUINT|BLONG|BULONG|BIND, /* [TLONG] */ 84 BINT|BUINT|BLONG|BULONG|BIND, /* [TULONG] */ 85 BVLONG|BUVLONG, /* [TVLONG] */ 86 BVLONG|BUVLONG, /* [TUVLONG] */ 87 BFLOAT, /* [TFLOAT] */ 88 BDOUBLE, /* [TDOUBLE] */ 89 BLONG|BULONG|BIND, /* [TIND] */ 90 0, /* [TFUNC] */ 91 0, /* [TARRAY] */ 92 0, /* [TVOID] */ 93 BSTRUCT, /* [TSTRUCT] */ 94 BUNION, /* [TUNION] */ 95 0, /* [TENUM] */ 96 }; 97 98 enum{ 99 TCFD = 1, 100 TCFC = 2, 101 TCPC = 4, 102 TCAR = 8, 103 TCIN = 16, 104 TCGEN = TCFD|TCFC|TCPC|TCAR, 105 TCALL = TCFD|TCFC|TCPC|TCAR|TCIN, 106 }; 107 108 enum{ 109 SGLOB, 110 SPARM, 111 SAUTO, 112 }; 113 114 typedef struct Scope Scope; 115 116 struct Scope{ 117 Node *n; 118 int k; 119 Scope *nxt; 120 }; 121 122 static void 123 prtyp(Type *t, char *s, int nl) 124 { 125 print("%s: ", s); 126 if(t == T){ 127 print("nil"); 128 if(nl) 129 print("\n"); 130 return; 131 } 132 while(t != T){ 133 print("%d(%d)[%x] ", t->etype, t->mark, (int)t); 134 if(isadt(t)) 135 break; 136 t = t->link; 137 } 138 if(nl) 139 print("\n"); 140 } 141 142 static Node* 143 func(Node *n) 144 { 145 while(n != Z && n->op != OFUNC) 146 n = n->left; 147 return n; 148 } 149 150 static void 151 setmain(Node *n) 152 { 153 inmain |= n->left->op == ONAME && strcmp(n->left->sym->name, "main") == 0; 154 } 155 156 static Node* 157 protoname(Node *n) 158 { 159 do 160 n = n->left; 161 while(n != Z && n->op != ONAME && n->op != ODOTDOT); 162 return n; 163 } 164 165 static Type* 166 prototype(Node *n, Type *t) 167 { 168 for( ; n != Z ; n = n->left){ 169 switch(n->op){ 170 case OARRAY: 171 t = typ(TARRAY, t); 172 t->width = 0; 173 break; 174 case OIND: 175 t = typ(TIND, t); 176 break; 177 case OFUNC: 178 t = typ(TFUNC, t); 179 t->down = fnproto(n); 180 break; 181 } 182 } 183 return t; 184 } 185 186 static Scope *scopes, *freescopes; 187 188 static void 189 pushdcl(Node *n, int c) 190 { 191 Sym *s; 192 193 if(passes){ 194 s = n->sym; 195 push1(s); 196 if(c != CAUTO || s->class != CSTATIC) 197 s->class = c; 198 s->type = n->type; 199 } 200 } 201 202 static void 203 pushparams(Node *n) 204 { 205 if(n == Z) 206 return; 207 if(passes){ 208 if(n->op == OLIST){ 209 pushparams(n->left); 210 pushparams(n->right); 211 } 212 else if(n->op == OPROTO){ 213 n = protoname(n); 214 if(n != Z && n->op == ONAME) 215 pushdcl(n, CPARAM); 216 } 217 else if(n->op == ONAME){ 218 addnode(OPROTO, n); 219 pushdcl(n, CPARAM); 220 } 221 else if(n->op != ODOTDOT) 222 diag(Z, "bad op in pushparams"); 223 } 224 } 225 226 static void 227 pushscope(Node *n, int k) 228 { 229 Scope *s; 230 231 if(freescopes != nil){ 232 s = freescopes; 233 freescopes = freescopes->nxt; 234 } 235 else 236 s = (Scope*)malloc(sizeof(Scope)); 237 s->n = n; 238 s->k = k; 239 s->nxt = scopes; 240 scopes = s; 241 if(passes && (k == SPARM || k == SAUTO)) 242 markdcl(); 243 if(k == SPARM) 244 pushparams(n->right); 245 } 246 247 static void 248 popscope(void) 249 { 250 int k; 251 Scope *s; 252 253 s = scopes; 254 k = s->k; 255 scopes = scopes->nxt; 256 s->nxt = freescopes; 257 freescopes = s; 258 if(passes && (k == SPARM || k == SAUTO)) 259 revertdcl(); 260 } 261 262 static Node* 263 curfn(void) 264 { 265 Scope *s; 266 267 for(s = scopes; s != nil; s = s->nxt) 268 if(s->k == SPARM) 269 return s->n; 270 return Z; 271 } 272 273 static void 274 marktype(Type *t, int tc) 275 { 276 t->mark = tc; 277 } 278 279 static int 280 marked(Type *t) 281 { 282 return t == T ? 0 : t->mark; 283 } 284 285 static Sym* 286 decsym(Node *n) 287 { 288 if(n == Z) 289 return S; 290 if(n->op == OFUNC){ 291 if(n->left->op == ONAME) 292 return n->left->sym; 293 return S; 294 } 295 if(n->op == ODAS) 296 return n->left->sym; 297 return n->sym; 298 } 299 300 static void 301 trep(Type *t1, Type *t) 302 { 303 int l; 304 Sym *s; 305 Type *t2; 306 307 if(t1 != T){ 308 l = t1->lineno; 309 s = t1->sym; 310 t2 = t1->down; 311 *t1 = *t; 312 t1->down = t2; 313 t1->sym = s; 314 t1->lineno = l; 315 } 316 } 317 318 static void 319 tind(Node *n) 320 { 321 if(n == Z) 322 return; 323 n = protoname(n); 324 if(n != Z && n->type != T){ 325 n->type = tcp(n->type->link); 326 marktype(n->type, TCIN); 327 } 328 } 329 330 static void 331 tcon(Node *n, Type *t) 332 { 333 Type *tt; 334 335 if(n->garb) 336 return; 337 n->garb = 1; 338 again = 1; 339 switch(n->op){ 340 case OCONST: 341 if(t->mark == TCFD && !isnil(n)) 342 addnode(OFILDES, n); 343 n->type = t; 344 break; 345 case OCAST: 346 tcon(n->left, t); 347 *n = *n->left; 348 n->type = t; 349 break; 350 case ONAME: 351 n->sym->type = t; 352 n->type = t; 353 setdec(n->sym, t); 354 break; 355 case ODOT: 356 case ODOTIND: 357 trep(n->type, t); 358 n->type = t; 359 break; 360 case OARRIND: 361 tt = n->left->type; 362 if(tt != T) 363 tt->link = t; 364 n->type = t; 365 break; 366 case OFUNC: 367 n->left->type->link = t; 368 if(n->left->op == ONAME) 369 n->left->sym->type->link = t; 370 n->type = t; 371 break; 372 } 373 } 374 375 static Node* 376 retval(Node *n) 377 { 378 int i; 379 Type *t; 380 Node *a, *l, *cf; 381 382 cf = curfn(); 383 t = cf->left->type->link; 384 if(t->mark&(TCPC|TCFC) && (n == Z || !(n->type->mark&(TCPC|TCFC)))){ 385 if(n == Z) 386 n = new1(ORETURN, Z, Z); 387 l = n->left; 388 for(i = 0; ; i++){ 389 a = arg(cf->right, i); 390 if(a == Z) 391 break; 392 a = protoname(a); 393 if(a == Z || a->op != ONAME) 394 break; 395 if(a->type->mark == TCIN){ 396 if(l == Z) 397 l = ncopy(a); 398 else 399 l = new1(OTUPLE, l, ncopy(a)); 400 } 401 } 402 n->left = l; 403 n->type = l->type = t; 404 } 405 return n; 406 } 407 408 static void 409 sube(Node *n) 410 { 411 Node *l, *r, *nn; 412 Type *tt; 413 static Node *gn; 414 int p; 415 416 if(n == Z) 417 return; 418 l = n->left; 419 r = n->right; 420 switch(n->op){ 421 default: 422 sube(l); 423 sube(r); 424 break; 425 case OIND: 426 if(l == Z) 427 return; 428 tt = l->type; 429 sube(l); 430 if(cktype(l, n, TCIN, 0) && iteq(tt, l->type)) 431 *n = *n->left; 432 break; 433 case OARRIND: 434 tt = l->type; 435 sube(l); 436 sube(r); 437 if(!isconst(r, 0)) 438 break; 439 if(cktype(l, n, TCIN, 0) && iteq(tt, l->type)) 440 *n = *n->left; 441 break; 442 case ONAME: 443 if(cktype(n, n, TCALL, 0)) 444 setdec(n->sym, n->type); 445 break; 446 case OCAST: 447 sube(l); 448 if(cktype(l, n, TCALL, 0)) 449 n->type = l->type; 450 break; 451 case OPROTO: 452 sube(l); 453 sube(r); 454 nn = protoname(n); 455 if(nn != Z && cktype(nn, n, TCALL, 0)){ 456 n->type = nn->type; 457 p = argpos(n, gn->right); 458 for(tt = gn->left->type->down; tt != T && p >= 0; tt = tt->down){ 459 if(p == 0){ 460 trep(tt, nn->type); 461 break; 462 } 463 --p; 464 } 465 } 466 break; 467 case OFUNC: 468 if(n->kind == KEXP) 469 aargs(n); 470 if(n->left->op == ONAME) 471 gn = n; 472 sube(l); 473 sube(r); 474 if(l != Z && cktype(n, n, TCGEN, 0)) 475 l->type->link = n->type; 476 break; 477 case OAS: 478 sube(l); 479 sube(r); 480 if(r->op == ORETV){ 481 n->left = new1(OTUPLE, l, r->right); 482 n->right = r->left; 483 n->left->type = n->type; 484 break; 485 } 486 if(cktype(r, n, TCGEN, 0)){ 487 tcon(l, r->type); 488 n->type = r->type; 489 } 490 if(cktype(l, n, TCGEN, 1)){ 491 tcon(r, l->type); 492 n->type = l->type; 493 } 494 break; 495 case OLT: 496 case OGE: 497 sube(l); 498 sube(r); 499 if(cktype(l, n, TCFD, 0) && isconst(r, 0)){ 500 n->op = n->op == OLT ? OEQ : ONE; 501 r->op = ONIL; 502 r->type = l->type; 503 } 504 break; 505 case OGT: 506 case OLE: 507 sube(l); 508 sube(r); 509 if(cktype(r, n, TCFD, 0) && isconst(l, 0)){ 510 n->op = n->op == OGT ? OEQ : ONE; 511 l->op = ONIL; 512 l->type = r->type; 513 } 514 break; 515 } 516 } 517 518 static void 519 subs(Node *n, int blk, int aut) 520 { 521 Node *l, *r; 522 523 if(n == Z) 524 return; 525 if(blk) 526 pushscope(n, SAUTO); 527 nearln = n->lineno; 528 l = n->left; 529 r = n->right; 530 switch(n->op){ 531 default: 532 sube(n); 533 break; 534 case ONAME: 535 if(aut && n->kind != KEXP) 536 pushdcl(n, CAUTO); 537 if(cktype(n, n, TCALL, 0)) 538 setdec(n->sym, n->type); 539 break; 540 case ODAS: 541 if(aut) 542 pushdcl(l, CAUTO); 543 subs(l, 0, aut); 544 if(cktype(l, n, TCALL, 0)) 545 tcon(r, l->type); 546 break; 547 case OSBREAK: 548 case ONUL: 549 case OLABEL: 550 case OGOTO: 551 case OCONTINUE: 552 case OBREAK: 553 case OSET: 554 case OUSED: 555 break; 556 case OBLK: 557 subs(l, 1, aut); 558 break; 559 case OCASE: 560 subs(r, 1, aut); 561 break; 562 case OLIST: 563 subs(l, 0, aut); 564 subs(r, 0, aut); 565 break; 566 case ORETURN: 567 sube(l); 568 if(l != Z && cktype(l, n, TCGEN, 0)){ 569 n->type = l->type; 570 tcon(curfn(), l->type); 571 } 572 retval(n); 573 break; 574 case OSWITCH: 575 case OWHILE: 576 case ODWHILE: 577 sube(l); 578 subs(r, 1, aut); 579 break; 580 case OIF: 581 sube(l); 582 subs(r->left, 1, aut); 583 subs(r->right, 1, aut); 584 break; 585 case OFOR: 586 sube(l->left); 587 sube(l->right->left); 588 sube(l->right->right); 589 subs(r, 1, aut); 590 break; 591 } 592 if(blk) 593 popscope(); 594 } 595 596 static Node* 597 finddec0(Sym *s, Node *n) 598 { 599 Node *nn; 600 601 if(n == Z) 602 return ZZ; 603 switch(n->op){ 604 case OLIST: 605 nn = finddec0(s, n->left); 606 if(nn != Z) 607 return nn; 608 return finddec0(s, n->right); 609 case OFUNC: 610 if(n->op != KEXP){ 611 if(s == decsym(n)) 612 return n; 613 return finddec0(s, n->right); 614 } 615 else 616 return ZZ; 617 case OPROTO: 618 case OIND: 619 case OARRAY: 620 return finddec0(s, n->left); 621 case ODOTDOT: 622 return ZZ; 623 case ONOOP: 624 case OPUSH: 625 case OPOP: 626 case OCODE: 627 case ODECE: 628 case ODECT: 629 return finddec0(s, n->right); 630 case ODECV: 631 case ODECF: 632 if(s == decsym(n->left) && !isfn(n->left->type)) 633 return n->left; 634 return finddec0(s, n->right); 635 } 636 if(isdec(n)){ 637 if(s == decsym(n) && !isfn(n->type)) 638 return n; 639 return Z; 640 } 641 return ZZ; 642 } 643 644 static Node* 645 finddec(Sym *s, int g) 646 { 647 Node *n; 648 Scope *sc; 649 650 for(sc = scopes; sc != nil; sc = sc->nxt){ 651 if(!g || sc->k == SGLOB){ 652 n = finddec0(s, sc->n); 653 if(n != Z && n != ZZ) 654 return n; 655 } 656 } 657 return Z; 658 } 659 660 static void 661 setdec(Sym *s, Type *t) 662 { 663 Node *n; 664 665 if((n = finddec(s, 0)) != Z){ 666 n->type = t; 667 if(n->op == ODAS){ 668 n = n->left; 669 n->type = t; 670 } 671 n->sym->type = t; 672 } 673 } 674 675 typedef struct Syml Syml; 676 677 struct Syml{ 678 Sym *sym; 679 Syml *nxt; 680 }; 681 682 typedef struct Symq Symq; 683 684 struct Symq{ 685 Syml *f; 686 Syml *r; 687 }; 688 689 typedef struct Modl Modl; 690 691 struct Modl{ 692 char *mod; 693 int ld; 694 Modl *nxt; 695 }; 696 697 static void 698 prn(Node *n, int i) 699 { 700 int j; 701 702 for(j = 0; j < i; j++) 703 print("\t"); 704 if(n == Z){ 705 print("Z\n"); 706 return; 707 } 708 print("%s", onames[n->op]); 709 if(n->blk) 710 print(" block"); 711 if(n->type == T) 712 print(" T"); 713 else 714 print(" %s", tnames[n->type->etype]); 715 if(n->op == OCONST) 716 print(" %d", (int)n->vconst); 717 else if(n->op == OSTRING) 718 print(" %s", n->cstring); 719 else if(n->op == ONAME) 720 print(" %s", n->sym->name); 721 print("\n"); 722 if(n->op != OLIST) 723 i++; 724 prn(n->left, i); 725 prn(n->right, i); 726 } 727 728 static int 729 isbigv(vlong v) 730 { 731 return v > 0xffffffff; 732 } 733 734 static int 735 islbigv(vlong v) 736 { 737 return v > 0x7fffffff || v < -0x7fffffff; 738 } 739 740 static int 741 isuintv(vlong v) 742 { 743 return !isbigv(v) && (v&0x80000000) != 0; 744 } 745 746 static int 747 isadt(Type *t) 748 { 749 return t != T && (t->etype == TSTRUCT || t->etype == TUNION); 750 } 751 752 static int 753 isreal(Type *t) 754 { 755 return t != T && (t->etype == TDOUBLE || t->etype == TFLOAT); 756 } 757 758 static int 759 isbyte(Type *t) 760 { 761 return t != T && (t->etype == TCHAR || t->etype == TUCHAR); 762 } 763 764 static int 765 isshort(Type *t) 766 { 767 return t != T && (t->etype == TSHORT || t->etype == TUSHORT); 768 } 769 770 static int 771 isint(Type *t) 772 { 773 return t != T && (t->etype == TINT || t->etype == TUINT); 774 } 775 776 static int 777 islong(Type *t) 778 { 779 return t != T && (t->etype == TLONG || t->etype == TULONG); 780 } 781 782 static int 783 isbig(Type *t) 784 { 785 return t != T && (t->etype == TVLONG || t->etype == TUVLONG); 786 } 787 788 static int 789 isinteger(Type *t) 790 { 791 return isbyte(t) || isshort(t) || isint(t) || islong(t) || isbig(t); 792 } 793 794 static int 795 isptr(Type *t) 796 { 797 return t != T && (t->etype == TIND || t->etype == TARRAY || t->etype == TFUNC); 798 } 799 800 static int 801 isscalar(Type *t) 802 { 803 return t != T && !isadt(t) && t->etype != TTUPLE; 804 } 805 806 static int 807 isvoid(Type *t) 808 { 809 return t == T || t->etype == TVOID; 810 } 811 812 static int 813 isnum(Type *t) 814 { 815 return t != T && isscalar(t) && !isptr(t) && !isvoid(t); 816 } 817 818 static int 819 isarray(Type *t) 820 { 821 return t != T && (t->etype == TARRAY || (t->etype == TIND && !isadt(t->link))); 822 } 823 824 static int 825 isstr(Type *t) 826 { 827 return t != T && (t->etype == TSTRING || isarray(t) && isbyte(t->link)); 828 } 829 830 static int 831 isfn(Type *t) 832 { 833 return t != T && t->etype == TFUNC; 834 } 835 836 static int 837 iscastable(Type *t, Type *tt) 838 { 839 return t != T && (!isptr(t) || isarray(t) && isbyte(t->link) && isstr(tt)); 840 } 841 842 static int 843 isname(Node *n) 844 { 845 return n->op == ONAME; 846 } 847 848 static int 849 isstring(Node *n) 850 { 851 return n->op == OSTRING || n->op == OLSTRING || n->op == ONAME && n->sym->tenum != T && n->sym->tenum->etype == TIND; 852 } 853 854 static int 855 isnil(Node *n) 856 { 857 if(!isptr(n->type)) 858 return 0; 859 while(n->op == OCAST) 860 n = n->left; 861 return n->op == OCONST && n->vconst == 0 || n->op == ONIL; 862 } 863 864 static int 865 isconst(Node *n, vlong v) 866 { 867 while(n->op == OCAST) 868 n = n->left; 869 return n->op == OCONST && n->vconst == v; 870 } 871 872 static Node* 873 cknil(Node *n) 874 { 875 if(isconst(n, 0)) 876 n->op = ONIL; 877 return n; 878 } 879 880 static int 881 cktype(Node *n, Node *t, int mask, int lev) 882 { 883 int g, m, m0; 884 885 g = t->garb > lev; 886 m = marked(n->type) & mask; 887 if(n->op == ONAME){ 888 m0 = marked(n->sym->type) & mask; 889 if(m && !m0){ 890 n->sym->type = n->type; 891 if(!g) 892 again = 1; 893 } 894 if(!m && m0){ 895 n->type = n->sym->type; 896 if(!g) 897 again = 1; 898 } 899 m |= m0; 900 } 901 if(m && t->garb < 2) 902 t->garb++; 903 return m && !g ? m : 0; 904 } 905 906 int 907 isconsym(Sym *s) 908 { 909 switch(s->class){ 910 case CXXX: 911 case CTYPEDEF: 912 return 1; 913 case CEXTERN: 914 case CGLOBL: 915 case CSTATIC: 916 case CLOCAL: 917 return s->type != T && s->type->etype == TENUM; 918 } 919 return -1; 920 } 921 922 static void genstart(void); 923 924 static char* 925 mprolog[] = 926 { 927 "%%: module", 928 "{", 929 "\tPATH: con \"%%%.dis\";", 930 "", 931 nil 932 }; 933 934 static char* 935 mepilog[] = 936 { 937 "};", 938 nil 939 }; 940 941 static char* 942 bprolog[] = 943 { 944 "implement %%;", 945 "", 946 "include \"draw.m\";", 947 "", 948 "%%: module", 949 "{", 950 " init: fn(nil: ref Draw->Context, argl: list of string);", 951 "};", 952 "", 953 nil 954 }; 955 956 static char* 957 bmprolog[] = 958 { 959 "implement %%;", 960 "", 961 "include \"draw.m\";", 962 "", 963 nil 964 }; 965 966 static char* 967 bepilog[] = 968 { 969 nil 970 }; 971 972 static void 973 pgen0(char **txt) 974 { 975 int sub; 976 char *b, *s, *t, **p; 977 978 p = txt; 979 for(;;){ 980 s = *p++; 981 if(s == nil) 982 break; 983 sub = 0; 984 for(t = s; *t != 0; t++){ 985 if(*t == '%' && *(t+1) == '%'){ 986 sub = 1; 987 break; 988 } 989 } 990 if(sub){ 991 strcpy(buf, s); 992 b = buf; 993 for(t = s; *t != 0; t++){ 994 if(*t == '%' && *(t+1) == '%'){ 995 if(*(t+2) == '%'){ 996 outmod(mbuf, 0); 997 t++; 998 } 999 else 1000 outmod(mbuf, 1); 1001 strcpy(b, mbuf); 1002 b += strlen(mbuf); 1003 t++; 1004 } 1005 else 1006 *b++ = *t; 1007 } 1008 *b = 0; 1009 prline(buf); 1010 } 1011 else 1012 prline(s); 1013 } 1014 } 1015 1016 static char* 1017 hasm() 1018 { 1019 outmod(mbuf, 0); 1020 strcat(mbuf, ".m"); 1021 if(exists(mbuf)) 1022 return mbuf; 1023 else if(domod){ 1024 outmod(buf, 0); 1025 strcat(buf, ".h"); 1026 if(exists(buf)) 1027 return mbuf; 1028 } 1029 return nil; 1030 } 1031 1032 void 1033 pgen(int b) 1034 { 1035 char **p; 1036 1037 if(!dolog()) 1038 return; 1039 if(b) 1040 p = hasm() ? bmprolog : bprolog; 1041 else 1042 p = mprolog; 1043 pgen0(p); 1044 if(b && passes) 1045 genstart(); 1046 if(!b) 1047 incind(); 1048 } 1049 1050 void 1051 epgen(int b) 1052 { 1053 char **p; 1054 1055 /* output(0x7fffffff, 1); */ /* INFINITY */ 1056 if(!dolog()) 1057 return; 1058 if(b){ 1059 if(!passes) 1060 genstart(); 1061 p = bepilog; 1062 } 1063 else 1064 p = mepilog; 1065 if(!b) 1066 decind(); 1067 pgen0(p); 1068 } 1069 1070 static int lastsec = 0; 1071 1072 #define ASSOC 1 1073 #define RASSOC 2 1074 #define POSTOP 4 1075 1076 #define LEFT 1 1077 #define RIGHT 2 1078 #define PRE 4 1079 #define POST 8 1080 1081 static int space[] = { 0, 0, 2, 0, 4, 5, 0, 0, 0, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0 }; 1082 1083 static struct{ 1084 char *name; 1085 int prec; 1086 int kind; 1087 } ops[] = { 1088 "", 0, 0, /* ONOOP */ 1089 "", 16, 0, /* OXXX, */ 1090 "+", 12, ASSOC, /* OADD, */ 1091 "&", 14, RASSOC, /* OADDR, */ 1092 "&", 8, ASSOC, /* OAND, */ 1093 "&&", 5, ASSOC, /* OANDAND, */ 1094 "", 16, 0, /* OARRAY, */ 1095 "=", 2, RASSOC, /* OAS, */ 1096 "=", 2, RASSOC, /* OASI, */ 1097 "+=", 2, RASSOC, /* OASADD, */ 1098 "&=", 2, RASSOC, /* OASAND, */ 1099 "<<=", 2, RASSOC, /* OASASHL, */ 1100 ">>=", 2, RASSOC, /* OASASHR, */ 1101 "/=", 2, RASSOC, /* OASDIV, */ 1102 "<<", 11, 0, /* OASHL, */ 1103 ">>", 11, 0, /* OASHR, */ 1104 "/=", 2, RASSOC, /* OASLDIV, */ 1105 "%=", 2, RASSOC, /* OASLMOD, */ 1106 "*=", 2, RASSOC, /* OASLMUL, */ 1107 ">>=", 2, RASSOC, /* OASLSHR, */ 1108 "%=", 2, RASSOC, /* OASMOD, */ 1109 "*=", 2, RASSOC, /* OASMUL, */ 1110 "|=", 2, RASSOC, /* OASOR, */ 1111 "-=", 2, RASSOC, /* OASSUB, */ 1112 "^=", 2, RASSOC, /* OASXOR, */ 1113 "", -1, 0, /* OBIT, */ 1114 "", -1, 0, /* OBREAK, */ 1115 "", -1, 0, /* OCASE, */ 1116 "", 14, RASSOC, /* OCAST, */ 1117 "", 1, ASSOC, /* OCOMMA, */ 1118 "", 3, RASSOC, /* OCOND, */ 1119 "", 16, 0, /* OCONST, */ 1120 "", -1, 0, /* OCONTINUE, */ 1121 "/", 13, 0, /* ODIV, */ 1122 ".", 15, 0, /* ODOT, */ 1123 "...", 16, 0, /* ODOTDOT, */ 1124 "", -1, 0, /* ODWHILE, */ 1125 "", -1, 0, /* OENUM, */ 1126 "==", 9, 0, /* OEQ, */ 1127 "", -1, 0, /* OFOR, */ 1128 "", 15, 0, /* OFUNC, */ 1129 ">=", 10, 0, /* OGE, */ 1130 "", -1, 0, /* OGOTO, */ 1131 ">", 10, 0, /* OGT, */ 1132 ">", 10, 0, /* OHI, */ 1133 ">=", 10, 0, /* OHS, */ 1134 "", -1, 0, /* OIF, */ 1135 "*", 14, RASSOC, /* OIND, */ 1136 "", -1, 0, /* OINDREG, */ 1137 "", 16, 0, /* OINIT, */ 1138 "", -1, 0, /* OLABEL, */ 1139 "/", 13, 0, /* OLDIV, */ 1140 "<=", 10, 0, /* OLE, */ 1141 "", 16, 0, /* OLIST, */ 1142 "%", 13, 0, /* OLMOD, */ 1143 "*", 13, ASSOC, /* OLMUL, */ 1144 "<", 10, 0, /* OLO, */ 1145 "<=", 10, 0, /* OLS, */ 1146 ">>", 11, 0, /* OLSHR, */ 1147 "<", 10, 0, /* OLT, */ 1148 "%", 13, 0, /* OMOD, */ 1149 "*", 13, ASSOC, /* OMUL, */ 1150 "", 16, 0, /* ONAME, */ 1151 "!=", 9, 0, /* ONE, */ 1152 "!", 14, RASSOC, /* ONOT, */ 1153 "|", 6, ASSOC, /* OOR, */ 1154 "||", 4, ASSOC, /* OOROR, */ 1155 "--", 14, RASSOC|POSTOP, /* OPOSTDEC, */ 1156 "++", 14, RASSOC|POSTOP, /* OPOSTINC, */ 1157 "--", 14, RASSOC, /* OPREDEC, */ 1158 "++", 14, RASSOC, /* OPREINC, */ 1159 "", 16, 0, /* OPROTO, */ 1160 "", -1, 0, /* OREGISTER, */ 1161 "", 0, 0, /* ORETURN, */ 1162 "SET", -1, 0, /* OSET, */ 1163 "signof", 14, RASSOC, /* OSIGN, */ 1164 "sizeof", 14, RASSOC, /* OSIZE, */ 1165 "", 16, 0, /* OSTRING, */ 1166 "", 16, 0, /* OLSTRING, */ 1167 "", 16, 0, /* OSTRUCT, */ 1168 "-", 12, 0, /* OSUB, */ 1169 "", -1, 0, /* OSWITCH, */ 1170 "", 16, 0, /* OUNION, */ 1171 "USED", -1, 0, /* OUSED, */ 1172 "", -1, 0, /* OWHILE, */ 1173 "^", 7, ASSOC, /* OXOR, */ 1174 "-", 14, RASSOC, /* ONEG, */ 1175 "~", 14, RASSOC, /* OCOM, */ 1176 "", 16, 0, /* OELEM, */ 1177 "", -1, 0, /* OTST, */ 1178 "", -1, 0, /* OINDEX, */ 1179 "", -1, 0, /* OFAS, */ 1180 "", -1, 0, /* OBLK */ 1181 "+", 14, RASSOC, /* OPOS */ 1182 "", -1, 0, /* ONUL */ 1183 ".", 15, 0, /* ODOTIND */ 1184 "", 15, 0, /* OARRIND */ 1185 "", -1, 0, /* ODAS */ 1186 ":=", 2, RASSOC, /* OASD */ 1187 "", 16, 0, /* OIOTA */ 1188 "", 14, RASSOC, /* OLEN */ 1189 "", 17, 0, /* OBRACKET */ 1190 "", 14, RASSOC, /* OREF */ 1191 "", 14, RASSOC, /* OARRAYOF */ 1192 "", 15, 0, /* OSLICE */ 1193 "&", 14, RASSOC, /* OSADDR, */ 1194 "", 16, 0, /* ONIL */ 1195 "", 16, 0, /* OS2AB */ 1196 "", 16, 0, /* OAB2S */ 1197 "", 16, 0, /* OFILDES */ 1198 ".", 15, 0, /* OFD */ 1199 "", 16, 0, /* OTUPLE */ 1200 ".", 15, 0, /* OT0 */ 1201 "", 15, 0, /* ORETV */ 1202 "+", 12, ASSOC, /* OCAT */ 1203 "", -1, 0, /* OSBREAK, */ 1204 ".", 15, 0, /* OLDOT */ 1205 "->", 15, 0, /* OMDOT */ 1206 nil, -1, 0, /* OCODE */ 1207 nil, -1, 0, /* ODECE */ 1208 nil, -1, 0, /* ODECT */ 1209 nil, -1, 0, /* ODECV */ 1210 nil, -1, 0, /* ODECF */ 1211 nil, -1, 0, /* OPUSH */ 1212 nil, -1, 0, /* OPOP */ 1213 "", -1, 0, /* OEND */ 1214 }; 1215 1216 #define COMPLEX 32 1217 1218 #define NOBR 2 1219 #define NOIN 4 1220 #define YESBR 8 1221 #define NONL 16 1222 #define NOENL 32 1223 1224 enum{ 1225 LNONE, 1226 LSTRLEN, 1227 LSTRCMP, 1228 LSTRCPY, 1229 LSTRCAT, 1230 LSTRNCMP, 1231 LSTRNCPY, 1232 LSTRNCAT, 1233 LSTRDUP, 1234 LMEMMOVE, 1235 LMALLOC, 1236 LFREE, 1237 LEXIT, 1238 LCLOSE, 1239 LATOI, 1240 LATOL, 1241 LATOF, 1242 LPRINT, 1243 LFPRINT, 1244 LSPRINT, 1245 LSELF, 1246 }; 1247 1248 static int tmp; 1249 1250 static void egen(Node*, int, int); 1251 static Node* buildcases(Node*); 1252 static void tdgen(Node *, int); 1253 static Node* cfind(Node*); 1254 static Node* cgen(Node*, Node*); 1255 static void cgen0(Node*, Node*); 1256 static int lteq(Type*, Type*); 1257 static Type* ntype(Node*); 1258 static int rewe(Node*, Type*, int); 1259 static void rewlc(Node*, int, Type*); 1260 static Node* con(vlong); 1261 static void clrbrk(Node*); 1262 static int hasbrk(Node*); 1263 static int isgen(char*); 1264 static int simple(Node*); 1265 static void pfmt(char*); 1266 static void lpfmt(Rune*); 1267 static int lline(Node*); 1268 static void args(Node*); 1269 static void addmodn(Sym*); 1270 static void scomplex(Node*); 1271 static void mset(Node*); 1272 1273 static Node *lastd; 1274 1275 static int 1276 rev(int op) 1277 { 1278 switch(op){ 1279 case OLT: return OGT; 1280 case OLE: return OGE; 1281 case OGT: return OLT; 1282 case OGE: return OLE; 1283 } 1284 return op; 1285 } 1286 1287 void 1288 newsec(int l) 1289 { 1290 if(l != 1 && lastd != Z){ 1291 tdgen(lastd, 1); 1292 lastd = Z; 1293 } 1294 if(l != 2) 1295 etgen2(nil); 1296 if(lastsec && l != lastsec) 1297 newline(); 1298 lastsec = l; 1299 } 1300 1301 static Node* 1302 defval(Type *t) 1303 { 1304 Node *n; 1305 1306 if(t == T) 1307 t = types[TINT]; 1308 n = con(0); 1309 n->type = types[TINT]; 1310 n->kind = KDEC; 1311 switch(t->etype){ 1312 case TFLOAT: 1313 case TDOUBLE: 1314 n->type = types[TDOUBLE]; 1315 n->fconst = 0.0; 1316 n->cstring = "0.0"; 1317 return n; 1318 default: 1319 break; 1320 case TIND: 1321 case TFUNC: 1322 case TARRAY: 1323 n->type = typ1(TIND, types[TVOID]); 1324 return n; 1325 case TVOID: 1326 case TSTRUCT: 1327 case TUNION: 1328 free(n); 1329 return Z; 1330 } 1331 if(!lteq(n->type, t)){ 1332 n = new1(OCAST, n, Z); 1333 n->type = t; 1334 } 1335 return n; 1336 } 1337 1338 static int 1339 teq(Type *t1, Type *t2) 1340 { 1341 if(t1 == t2) 1342 return 1; 1343 return sametype(t1, t2); 1344 /* 1345 if(t1->etype != t2->etype) 1346 return 0; 1347 switch(t1->etype){ 1348 case TARRAY: 1349 if(t1->width != t2->width) 1350 return 0; 1351 break; 1352 case TFUNC: 1353 if(!teq(t1->down, t2->down)) 1354 return 0; 1355 break; 1356 case TSTRUCT: 1357 case TUNION: 1358 return t1->link == t2->link; 1359 case TENUM: 1360 return 1; 1361 } 1362 return teq(t1->link, t2->link); 1363 */ 1364 } 1365 1366 static int 1367 tequiv(Type *t1, Type *t2) 1368 { 1369 if(!teq(t1, t2)) 1370 return 0; 1371 if(t1->etype == TSTRUCT || t1->etype == TUNION) 1372 return suename(t1) == suename(t2); 1373 return 1; 1374 } 1375 1376 static int 1377 iteq(Type *t1, Type *t2) 1378 { 1379 if(t1 == T || t2 == T) 1380 return 0; 1381 return t1->etype == TIND && (teq(t1->link, t2) || (t1->link->etype == TVOID && isnum(t2))); 1382 } 1383 1384 static Type * 1385 ltype(Type *t) 1386 { 1387 switch(t->etype){ 1388 case TUCHAR: 1389 return types[TCHAR]; 1390 case TSHORT: 1391 case TUSHORT: 1392 case TUINT: 1393 case TLONG: 1394 case TULONG: 1395 case TENUM: 1396 return types[TINT]; 1397 case TUVLONG: 1398 return types[TVLONG]; 1399 case TFLOAT: 1400 return types[TDOUBLE]; 1401 default: 1402 return t; 1403 } 1404 } 1405 1406 static int 1407 lteq(Type *t1, Type *t2) 1408 { 1409 if(t1 == T || t2 == T) 1410 return 0; 1411 if(t1 == t2) 1412 return 1; 1413 if(t1->etype == TIND && t2->etype == TIND) 1414 return lteq(t1->link, t2->link); 1415 return sametype(ltype(t1), ltype(t2)); 1416 } 1417 1418 static Type* 1419 tcp(Type *t) 1420 { 1421 Type *nt; 1422 1423 if(t == T) 1424 return T; 1425 nt = typ1(TXXX, T); 1426 *nt = *t; 1427 return nt; 1428 } 1429 1430 static Type* 1431 tuple(Type *t1, Type *t2) 1432 { 1433 Type *t, **at, *l; 1434 1435 if(t1 == T || t1->etype == TVOID) 1436 return tcp(t2); 1437 if(t2 == T || t2->etype == TVOID) 1438 return tcp(t1); 1439 if(t2->etype == TTUPLE) 1440 diag(Z, "bad tuple type"); 1441 t = typ1(TTUPLE, T); 1442 at = &t->link; 1443 if(t1->etype == TTUPLE){ 1444 for(l = t1->link; l != T; l = l->down){ 1445 *at = tcp(l); 1446 at = &(*at)->down; 1447 } 1448 } 1449 else{ 1450 *at = tcp(t1); 1451 at = &(*at)->down; 1452 } 1453 *at = tcp(t2); 1454 return t; 1455 } 1456 1457 static Sym* 1458 sue(Type *t) 1459 { 1460 int h; 1461 Sym *s; 1462 1463 if(t != T) 1464 for(h=0; h<nelem(hash); h++) 1465 for(s = hash[h]; s != S; s = s->link) 1466 if(s->suetag && s->suetag->link == t) 1467 return s; 1468 return S; 1469 } 1470 1471 static void 1472 pranon(int i) 1473 { 1474 prid("anon_"); 1475 prnum(i+1, KDEC, T); 1476 } 1477 1478 static int 1479 dotpath(Sym *s, Type *t, int pr) 1480 { 1481 int i; 1482 Type *t1; 1483 1484 if(t == T) 1485 return 0; 1486 for(t1 = t->link; t1 != T; t1 = t1->down){ 1487 if(t1->sym == s){ 1488 if(pr){ 1489 prdelim("."); 1490 prsym(s, 0); 1491 } 1492 return 1; 1493 } 1494 } 1495 i = 0; 1496 for(t1 = t->link; t1 != T; t1 = t1->down){ 1497 if(t1->sym == S){ 1498 i++; 1499 if(typesu[t1->etype] && sametype(s->type, t1)){ 1500 if(pr){ 1501 prdelim("."); 1502 pranon(i-1); 1503 } 1504 return 1; 1505 } 1506 } 1507 } 1508 i = 0; 1509 for(t1 = t->link; t1 != T; t1 = t1->down){ 1510 if(t1->sym == S){ 1511 i++; 1512 if(typesu[t1->etype] && dotpath(s, t1, 0)){ 1513 if(pr){ 1514 prdelim("."); 1515 pranon(i-1); 1516 dotpath(s, t1, 1); 1517 } 1518 return 1; 1519 } 1520 } 1521 } 1522 return 0; 1523 } 1524 1525 static Sym* 1526 suename(Type *t) 1527 { 1528 Sym *s; 1529 1530 s = sue(t->link); 1531 if(s != S) 1532 return s; 1533 else if(t->tag != S) 1534 return t->tag; 1535 else if(t->sym != S) 1536 return t->sym; 1537 return S; 1538 } 1539 1540 static int 1541 cycle(Type *t, Type *base) 1542 { 1543 int r; 1544 Type *l; 1545 1546 if(t->vis){ 1547 /* sametype() does structural comparison so have to check names */ 1548 if(t == base || tequiv(t, base)) 1549 return 1; 1550 return 0; 1551 } 1552 r = 0; 1553 t->vis = 1; 1554 switch(t->etype){ 1555 case TIND: 1556 case TARRAY: 1557 r = cycle(t->link, base); 1558 break; 1559 case TSTRUCT: 1560 case TUNION: 1561 case TTUPLE: 1562 for(l = t->link; l != T; l = l->down) 1563 r |= cycle(l, base); 1564 break; 1565 } 1566 t->vis = 0; 1567 return r; 1568 } 1569 1570 static void 1571 addnode(int op, Node *n) 1572 { 1573 Node *nn; 1574 1575 nn = new1(OXXX, Z, Z); 1576 *nn = *n; 1577 n->op = op; 1578 n->left = nn; 1579 n->right = Z; 1580 n->type = nn->type; 1581 } 1582 1583 static void 1584 cast(Node *n, Type *t) 1585 { 1586 addnode(OCAST, n); 1587 n->type = t; 1588 } 1589 1590 static void 1591 intcast(Node *n) 1592 { 1593 if(isptr(n->type)){ 1594 addnode(ONE, n); 1595 n->right = con(0); 1596 n->right->type = n->left->type; 1597 n->type = types[TINT]; 1598 } 1599 else 1600 cast(n, types[TINT]); 1601 } 1602 1603 static void 1604 strcast(Node *n) 1605 { 1606 cast(n, stringtype); 1607 } 1608 1609 static void 1610 bptr(Node *n) 1611 { 1612 if(n == Z) 1613 return; 1614 switch(n->op){ 1615 default: 1616 if(!lteq(n->type, types[TINT])) 1617 intcast(n); 1618 break; 1619 case ONOT: 1620 if(!lteq(n->left->type, types[TINT])){ 1621 intcast(n->left); 1622 if(n->left->op == ONE){ 1623 n->left->op = OEQ; 1624 *n = *n->left; 1625 } 1626 } 1627 break; 1628 case OANDAND: 1629 case OOROR: 1630 bptr(n->left); 1631 bptr(n->right); 1632 break; 1633 case OCOND: 1634 bptr(n->right->left); 1635 bptr(n->right->right); 1636 break; 1637 } 1638 } 1639 1640 static void 1641 bcomplex(Node *n) 1642 { 1643 if(n == Z) 1644 return; 1645 if(!passes) 1646 complex(n); 1647 bptr(n); 1648 } 1649 1650 static void 1651 ecomplex(Node *n) 1652 { 1653 if(!passes) 1654 complex(n); 1655 rewe(n, T, 0); 1656 } 1657 1658 static void 1659 becomplex(Node *n) 1660 { 1661 bcomplex(n); 1662 rewe(n, T, 0); 1663 } 1664 1665 static void 1666 tgen(Type *t, int dec, int arinit) 1667 { 1668 Type *l; 1669 1670 if(t == T) 1671 return; 1672 switch(t->etype){ 1673 case TXXX: 1674 prid("int"); 1675 break; 1676 case TCHAR: 1677 case TUCHAR: 1678 prid("byte"); 1679 break; 1680 case TSHORT: 1681 case TUSHORT: 1682 case TINT: 1683 case TUINT: 1684 case TLONG: 1685 case TULONG: 1686 case TENUM: 1687 prid("int"); 1688 break; 1689 case TVLONG: 1690 case TUVLONG: 1691 prid("big"); 1692 break; 1693 case TFLOAT: 1694 case TDOUBLE: 1695 prid("real"); 1696 break; 1697 case TIND: 1698 if(strings == 2 && t->link && t->link->etype == TCHAR){ 1699 prid("string"); 1700 break; 1701 } 1702 if(isadt(t->link) || t->link->etype == TFUNC) 1703 prid("ref "); 1704 else 1705 prid("array of "); 1706 if(t->link && t->link->etype == TVOID){ 1707 prid("byte"); 1708 prcom("was void*", Z); 1709 } 1710 else 1711 tgen(t->link, 1, 0); 1712 break; 1713 case TFUNC: 1714 if(0){ 1715 prid("int"); 1716 prcom("was function", Z); 1717 break; 1718 } 1719 prid("fn"); 1720 prdelim("("); 1721 for(l = t->down; l != T; l = l->down){ 1722 if(l->etype == TVOID && l->down == T) 1723 break; 1724 if(l->etype == TDOT){ 1725 prcom("was ...", Z); 1726 break; 1727 } 1728 if(l->sym != S) 1729 prsym(l->sym, 0); 1730 else 1731 prid("nil"); 1732 prdelim(": "); 1733 tgen(l, 1, 0); 1734 if(l->down != T && l->down->etype != TDOT) 1735 prdelim(", "); 1736 } 1737 /* tgen(t->down, dec, 0, 0); */ 1738 prdelim(")"); 1739 if(!isvoid(t->link)){ 1740 prdelim(": "); 1741 tgen(t->link, dec, 0); 1742 } 1743 break; 1744 case TARRAY: 1745 prid("array"); 1746 if(t->width == LARR) 1747 t->width = LARR; 1748 else if(dec){ 1749 if(t->nwidth != Z) 1750 prcom("array index was ", t->nwidth); 1751 else if(t->width != 0){ 1752 sprint(buf, "array index was %ld", t->width/t->link->width); 1753 prcom(buf, Z); 1754 } 1755 } 1756 else{ 1757 prdelim("["); 1758 if(t->nwidth != Z) 1759 egen(t->nwidth, ONOOP, PRE); 1760 else if(t->width != 0) 1761 prnum(t->width/t->link->width, KDEC, T); 1762 prdelim("]"); 1763 } 1764 prdelim(" of "); 1765 if(!arinit) 1766 tgen(t->link, 1, 0); 1767 break; 1768 case TVOID: 1769 /* prid("void"); */ 1770 prid("byte"); 1771 prcom("was void", Z); 1772 break; 1773 case TSTRUCT: 1774 case TUNION: 1775 if(t->link != T && t->link->etype == TFD){ 1776 prid("Sys->FD"); 1777 usemod(sysop, 0); 1778 } 1779 else 1780 prsym(suename(t), 1); 1781 break; 1782 case TTUPLE: 1783 prdelim("("); 1784 for(l = t->link; l != T; l = l->down){ 1785 tgen(l, dec, 0); 1786 if(l->down != T) 1787 prdelim(", "); 1788 } 1789 prdelim(")"); 1790 break; 1791 case TDOT: 1792 prdelim("..."); 1793 break; 1794 case TSTRING: 1795 prid("string"); 1796 break; 1797 case TFD: 1798 prid("fd"); 1799 break; 1800 default: 1801 diag(Z, "unknown type"); 1802 break; 1803 } 1804 } 1805 1806 static Type* 1807 typn(Type *t, int i) 1808 { 1809 Type *l; 1810 1811 for(l = t->down; l != T && --i >= 0; l = l->down) 1812 ; 1813 return l; 1814 } 1815 1816 void 1817 ttgen2(Type *t) 1818 { 1819 Type *l; 1820 Sym *s; 1821 int anon = 0; 1822 1823 switch(t->etype){ 1824 case TSTRUCT: 1825 case TUNION: 1826 newsec(0); 1827 output(t->lineno, 1); 1828 s = suename(t); 1829 if(isgen(s->name)) 1830 addmodn(s); 1831 setmod(s); 1832 prsym(s, 0); 1833 prdelim(": "); 1834 prid("adt"); 1835 prdelim("{"); 1836 if(t->etype == TUNION) 1837 prcom("was union", Z); 1838 newline(); 1839 incind(); 1840 t->vis = 1; 1841 for(l = t->link; l != T; l = l->down){ 1842 output(l->lineno, 1); 1843 if(l->nbits) 1844 prcom("was bit field", Z); 1845 if(l->sym != S) 1846 prsym(l->sym, 0); 1847 else 1848 pranon(anon++); 1849 prdelim(": "); 1850 if(cycle(l, t)) 1851 prid("cyclic "); 1852 tgen(l, 1, 0); 1853 prdelim(";"); 1854 newline(); 1855 } 1856 t->vis = 0; 1857 decind(); 1858 prdelim("};"); 1859 newline(); 1860 newline(); 1861 break; 1862 default: 1863 break; 1864 } 1865 } 1866 1867 static int 1868 canjoin(Node *n, Node *nn) 1869 { 1870 return teq(n->type, nn->type) && isname(n) && isname(nn) && n->type->etype != TARRAY; 1871 } 1872 1873 void 1874 vtgen2(Node *n) 1875 { 1876 int t, c, comma = 0; 1877 Node *nn; 1878 Sym *s; 1879 1880 nn = n; 1881 if(n->op == ODAS) 1882 nn = n->left; 1883 if(nn->type == T || nn->sym == S) 1884 return; 1885 t = nn->type->etype; 1886 c = nn->sym->class; 1887 if(0 && c == CTYPEDEF){ 1888 /* egen(nn, ONOOP, PRE); */ 1889 /* tdgen(n, 1, 0); */ 1890 if(isadt(n->type)){ 1891 s = suename(n->type); 1892 if(isgen(s->name)){ 1893 s->lname = nn->sym->name; 1894 ttgen2(n->type); 1895 } 1896 } 1897 } 1898 if(c != CGLOBL && c != CSTATIC && c != CLOCAL && c != CEXREG) 1899 return; 1900 newsec(1); 1901 if(lastd != Z){ 1902 if(t != TFUNC && canjoin(lastd, n)) 1903 comma = 1; 1904 else 1905 tdgen(lastd, 1); 1906 } 1907 output(nn->lineno, 1); 1908 if(t == TFUNC){ 1909 if(ism()){ 1910 setmod(nn->sym); 1911 egen(nn, ONOOP, PRE); 1912 tdgen(n, 1); 1913 } 1914 lastd = Z; 1915 return; 1916 } 1917 if(comma) 1918 prdelim(", "); 1919 if(nn->op != ONAME) 1920 diag(nn, "internal: not name in vtgen"); 1921 setmod(nn->sym); 1922 prsym(nn->sym, 0); 1923 /* egen(nn, ONOOP, PRE); */ 1924 /* tdgen(n, 1, 0); */ 1925 lastd = n; 1926 if(n->op == ODAS) 1927 rewe(n->right, T, 1); 1928 } 1929 1930 static void minseq(Syml*); 1931 1932 static Node* 1933 con(vlong v) 1934 { 1935 int neg = 0; 1936 Node *n; 1937 1938 if(v < 0){ 1939 neg = 1; 1940 v = -v; 1941 } 1942 n = new1(OCONST, Z, Z); 1943 n->vconst = v; 1944 n->kind = KDEC; 1945 n->type = types[TINT]; 1946 if(neg) 1947 n = new1(ONEG, n, Z); 1948 return n; 1949 } 1950 1951 /* 1952 static Node* 1953 fcon(double v) 1954 { 1955 int neg = 0; 1956 Node *n; 1957 1958 if(v < 0){ 1959 neg = 1; 1960 v = -v; 1961 } 1962 n = new1(OCONST, Z, Z); 1963 n->fconst = v; 1964 n->kind = KDEC; 1965 n->type = types[TDOUBLE]; 1966 if(neg) 1967 n = new1(ONEG, n, Z); 1968 return n; 1969 } 1970 */ 1971 1972 static Node* 1973 add(vlong v, Node *n) 1974 { 1975 if(v == 0) 1976 return n; 1977 return new1(OADD, con(v), n); 1978 } 1979 1980 static Node* 1981 addn(Node *n1, Node *n2) 1982 { 1983 if(n1 == Z || n2 == Z) 1984 return Z; 1985 if(isconst(n1, 0)) 1986 return n2; 1987 if(isconst(n2, 0)) 1988 return n1; 1989 return new1(OADD, n1, n2); 1990 } 1991 1992 static Node* 1993 mul(vlong v, Node *n) 1994 { 1995 if(v == 0) 1996 return con(0); 1997 else if(v == 1) 1998 return n; 1999 else if(v == -1) 2000 return new1(ONEG, n, Z); 2001 return new1(OMUL, con(v), n); 2002 } 2003 2004 static Node* 2005 mydiv(Node *n, vlong w) 2006 { 2007 Node *nn; 2008 2009 if(w == 0) 2010 return Z; 2011 if(w == 1) 2012 return n; 2013 else if(w == -1) 2014 return new1(ONEG, n, Z); 2015 switch(n->op){ 2016 case OCONST: 2017 if(n->vconst % w == 0){ 2018 n->vconst /= w; 2019 if(n->left != Z && mydiv(n->left, w) == Z){ 2020 n->vconst *= w; 2021 break; 2022 } 2023 return n; 2024 } 2025 break; 2026 case OCAST: 2027 return mydiv(n->left, w); 2028 case OMUL: 2029 nn = mydiv(n->right, w); 2030 if(nn != Z){ 2031 if(isconst(nn, 1)) 2032 *n = *n->left; 2033 return n; 2034 } 2035 nn = mydiv(n->left, w); 2036 if(nn != Z){ 2037 if(isconst(nn, 1)) 2038 *n = *n->right; 2039 return n; 2040 } 2041 break; 2042 default: 2043 break; 2044 } 2045 return Z; 2046 } 2047 2048 static Node* 2049 iota(void) 2050 { 2051 return new1(OIOTA, Z, Z); 2052 } 2053 2054 static Node* 2055 symcon(Sym *s) 2056 { 2057 Node *n; 2058 2059 if(s->nconst != Z) 2060 return s->nconst; 2061 n = con(s->vconst); 2062 n->kind = s->kind; 2063 return n; 2064 } 2065 2066 #define ARITH 1 2067 #define GEOM 2 2068 2069 static Syml* 2070 newsyml(Sym *s, Syml **frees) 2071 { 2072 Syml *sl, *f; 2073 2074 if((f = *frees) != nil){ 2075 sl = f; 2076 *frees = f->nxt; 2077 } 2078 else 2079 sl = (Syml*)malloc(sizeof(Syml)); 2080 sl->sym = s; 2081 sl->nxt = nil; 2082 return sl; 2083 } 2084 2085 static Syml* 2086 etseq(Syml *syml) 2087 { 2088 int e, pio, io, comma; 2089 vlong d, dd, v0, v1, v, t, tt; 2090 Node *expr; 2091 Sym *s; 2092 Syml *sl, *lsl; 2093 2094 lsl = nil; 2095 pio = io = ARITH|GEOM; 2096 e = 0; 2097 dd = 0; 2098 d = 0; 2099 for(sl = syml; sl != nil; sl = sl->nxt){ 2100 s = sl->sym; 2101 if(isreal(s->tenum) || s->tenum->etype == TIND) 2102 break; 2103 if(e == 0) 2104 v0 = s->vconst; 2105 if(e == 1){ 2106 v1 = s->vconst; 2107 d = v1-v0; 2108 } 2109 if(e > 0 && (v <= 0 || s->vconst != 2*v)) 2110 io &= ~GEOM; 2111 if(0 && e > 1 && s->vconst-v != d) 2112 io &= ~ARITH; 2113 if(e > 1){ 2114 t = s->vconst-v; 2115 tt = t-d; 2116 if(e > 2 && tt != dd) 2117 io &= ~ARITH; 2118 else{ 2119 d = t; 2120 dd = tt; 2121 } 2122 } 2123 if(io == 0) 2124 break; 2125 v = s->vconst; 2126 lsl = sl; 2127 pio = io; 2128 e++; 2129 } 2130 if(e < 2) 2131 pio = 0; 2132 if(pio&GEOM){ 2133 if(e < 3) 2134 pio = 0; 2135 } 2136 else if(pio&ARITH){ 2137 int n; 2138 2139 if(d == 0 && dd == 0) 2140 n = 2; 2141 else if(dd == 0) 2142 n = 3; 2143 else 2144 n = 4; 2145 if(e < n || (dd&1) != 0) 2146 pio = 0; 2147 } 2148 if(lsl == nil || pio == 0) 2149 lsl = syml; 2150 comma = 0; 2151 for(sl = syml; sl != nil; sl = sl->nxt){ 2152 s = sl->sym; 2153 nearln = s->lineno; 2154 output(s->lineno, 1); 2155 if(pio){ 2156 if(comma) 2157 prdelim(", "); 2158 setmod(s); 2159 prsym(s, 0); 2160 comma = 1; 2161 } 2162 else{ 2163 setmod(s); 2164 prsym(s, 0); 2165 prdelim(": "); 2166 prid("con "); 2167 if(isbyte(s->tenum) || isbig(s->tenum) && !islbigv(s->vconst) || !isbig(s->tenum) && isuintv(s->vconst)){ 2168 tgen(s->tenum, 1, 0); 2169 prdelim(" "); 2170 } 2171 if(s->nconst != Z) 2172 egen(s->nconst, ONOOP, PRE); 2173 else if(s->kind == KCHR) 2174 prchar(s->vconst); 2175 else if(isreal(s->tenum)) 2176 prreal(s->fconst, s->cstring, s->kind); 2177 else 2178 prnum(s->vconst, s->kind, s->tenum); 2179 prdelim(";"); 2180 newline(); 2181 } 2182 if(sl == lsl) 2183 break; 2184 } 2185 if(pio){ 2186 s = syml->sym; 2187 prdelim(": "); 2188 prid("con "); 2189 if(isbyte(s->tenum) || isbig(s->tenum)){ 2190 tgen(s->tenum, 1, 0); 2191 prdelim(" "); 2192 } 2193 if(pio&GEOM){ 2194 if(v0 == 0 || v0 == 1 || v0 == -1) 2195 expr = mul(v0, new1(OASHL, con(1), iota())); 2196 else 2197 expr = new1(OMUL, symcon(s), new1(OASHL, con(1), iota())); 2198 } 2199 else if(d == 0 && dd == 0) 2200 expr = symcon(s); 2201 else if(dd == 0) 2202 expr = add(v0, mul(d, iota())); 2203 else 2204 expr = add(v0, new1(OADD, mul(v1-dd/2-v0, iota()), mul(dd/2, new1(OMUL, iota(), iota())))); 2205 complex(expr); 2206 expr = ckneg(expr); 2207 egen(expr, ONOOP, PRE); 2208 prdelim(";"); 2209 newline(); 2210 } 2211 return lsl->nxt; 2212 } 2213 2214 static void 2215 adde(Syml *sl, Symq *q) 2216 { 2217 if(q->f == nil) 2218 q->f = sl; 2219 else 2220 q->r->nxt = sl; 2221 q->r = sl; 2222 } 2223 2224 static void 2225 freeq(Symq *q, Syml **frees) 2226 { 2227 if(q->f){ 2228 q->r->nxt = *frees; 2229 *frees = q->f; 2230 q->f = q->r = nil; 2231 } 2232 } 2233 2234 static void 2235 etgen2(Sym *s) 2236 { 2237 Syml *sl; 2238 static Syml *frees; 2239 static Symq symq, symq1; 2240 2241 if(s != nil){ 2242 newsec(2); 2243 sl = newsyml(s, &frees); 2244 adde(sl, &symq); 2245 if(isinteger(s->tenum) && isbigv(s->vconst) && !isbig(s->tenum)) 2246 s->tenum = types[TVLONG]; 2247 return; 2248 } 2249 /* end of enums */ 2250 if(symq.f && symq.f == symq.r){ /* try to merge with other singletons */ 2251 adde(symq.f, &symq1); 2252 symq.f = symq.r = nil; 2253 return; 2254 } 2255 if(symq1.f){ 2256 for(sl = symq1.f; sl != nil; sl = etseq(sl)) 2257 ; 2258 freeq(&symq1, &frees); 2259 } 2260 if(symq.f){ 2261 for(sl = symq.f; sl != nil; sl = etseq(sl)) 2262 ; 2263 freeq(&symq, &frees); 2264 } 2265 } 2266 2267 static void 2268 lgen(Node *n, int br, int first) 2269 { 2270 if(br) 2271 prdelim("("); 2272 if(n == Z){ 2273 if(br) 2274 prdelim(")"); 2275 return; 2276 } 2277 if(n->op == OLIST || n->op == OTUPLE){ 2278 lgen(n->left, 0, first); 2279 lgen(n->right, 0, 0); 2280 } 2281 else if(n->op != ODOTDOT){ 2282 if(!first) 2283 prdelim(", "); 2284 egen(n, ONOOP, PRE); 2285 } 2286 else 2287 prcom("was ...", Z); 2288 if(br) 2289 prdelim(")"); 2290 } 2291 2292 static void 2293 preced(int op1, int op2, int s, int c) 2294 { 2295 int p1, p2, k1, k2, br; 2296 char buf[2]; 2297 2298 br = 0; 2299 p1 = ops[op1].prec; 2300 p2 = ops[op2].prec; 2301 if(p1 < 0 || p2 < 0) 2302 diag(Z, "-ve precedence"); 2303 if(p1 > p2) 2304 br = 1; 2305 else if(p1 == p2){ 2306 k1 = ops[op1].kind; 2307 k2 = ops[op2].kind; 2308 if(op1 == op2){ 2309 if(k1&RASSOC) 2310 br = s == LEFT; 2311 else 2312 br = s == RIGHT && !(k1&ASSOC); 2313 } 2314 else{ 2315 if(k1&RASSOC) 2316 br = s == LEFT; 2317 else 2318 br = s == RIGHT && op1 != OADD; 2319 2320 if(k1&POSTOP && !(k2&POSTOP)) 2321 br = 1; 2322 2323 /* funny case */ 2324 if(op2 == OMDOT && s == LEFT && (op1 == ODOT || op1 == ODOTIND)) 2325 br = 1; 2326 } 2327 } 2328 if(br){ 2329 buf[0] = c; 2330 buf[1] = '\0'; 2331 prdelim(buf); 2332 } 2333 } 2334 2335 static void 2336 egen(Node *n, int op0, int side) 2337 { 2338 int op, p; 2339 Type *t; 2340 Node *nn; 2341 2342 if(n == Z){ 2343 if(op0 == OBRACKET) 2344 prdelim("()"); 2345 return; 2346 } 2347 if(n->op == OCONST && n->left != Z){ /* actual node in source */ 2348 n->left->type = n->type; 2349 n = n->left; 2350 } 2351 if((n->op == OSTRING || n->op == OLSTRING) && n->left != Z) /* actual node in source */ 2352 n = n->left; 2353 if(n->op == OCAST && (lteq(n->type, n->left->type) || isnil(n) || !iscastable(n->type, n->left->type))){ 2354 if(isnil(n)) 2355 prid("nil"); 2356 else 2357 egen(n->left, op0, side); 2358 return; 2359 } 2360 if(n->op == ONAME && arrow(n->sym)) 2361 n->op = OMDOT; 2362 if(n->op != OLIST) 2363 output(n->lineno, 0); 2364 op = n->op; 2365 preced(op0, op, side, '('); 2366 switch(op){ 2367 case OLIST: 2368 case OTUPLE: 2369 lgen(n, 1, 1); 2370 break; 2371 case OIOTA: 2372 prid("iota"); 2373 break; 2374 case OMDOT: 2375 case ONAME: 2376 case OXXX: 2377 prsym(n->sym, 1); 2378 break; 2379 case OCONST: 2380 if(n->kind == KCHR) 2381 prchar(n->vconst); 2382 else if(isreal(n->type)) 2383 prreal(n->fconst, n->cstring, n->kind); 2384 else if(isnil(n)) 2385 prid("nil"); 2386 else 2387 prnum(n->vconst, n->kind, n->type); 2388 if(n->right != Z) 2389 prcom("was ", n->right); 2390 break; 2391 case OSTRING: 2392 prstr(n->cstring); 2393 break; 2394 case OLSTRING: 2395 prlstr(n->rstring); 2396 break; 2397 case OCOND: 2398 egen(n->left, op, POST); 2399 prdelim(" ? "); 2400 egen(n->right->left, op, PRE|POST); 2401 prdelim(" : "); 2402 egen(n->right->right, op, PRE); 2403 prcom("?", Z); 2404 break; 2405 case OCOMMA: 2406 if(op0 != OCOMMA) 2407 prdelim("("); 2408 egen(n->left, op, LEFT); 2409 prdelim(", "); 2410 egen(n->right, op, RIGHT); 2411 if(op0 != OCOMMA) 2412 prdelim(")"); 2413 break; 2414 case OLDOT: 2415 egen(n->left, OMOD, LEFT); /* any precedence 13 operator */ 2416 prdelim("."); 2417 egen(n->right, op, RIGHT); 2418 break; 2419 default: 2420 p = ops[op].prec; 2421 egen(n->left, op, LEFT); 2422 if(space[p]) 2423 prdelim(" "); 2424 prdelim(ops[op].name); 2425 if(space[p]) 2426 prdelim(" "); 2427 egen(n->right, op, RIGHT); 2428 break; 2429 case OIND: case OADDR: case OSADDR: 2430 case OPOS: case ONEG: 2431 case ONOT: case OCOM: 2432 case OPREINC: case OPREDEC: 2433 if(op == OADDR){ 2434 n->op = OSADDR; 2435 if(!isfn(n->left->type)) 2436 prcom("was ", n); 2437 } 2438 else 2439 prdelim(ops[op].name); 2440 egen(n->left, op, PRE); 2441 break; 2442 case OPOSTINC: case OPOSTDEC: 2443 egen(n->left, op, POST); 2444 prdelim(ops[op].name); 2445 break; 2446 case ODOT: 2447 egen(n->left, op, LEFT); 2448 dotpath(n->sym, n->left->type, 1); 2449 /* prdelim(ops[op].name); */ 2450 /* prsym(n->sym, 0); */ 2451 break; 2452 case ODOTIND: 2453 egen(n->left, op, LEFT); 2454 if(isadt(n->left->type)) 2455 dotpath(n->sym, n->left->type, 1); /* type may be demoted arg */ 2456 else 2457 dotpath(n->sym, n->left->type->link, 1); 2458 /* prdelim(ops[op].name); */ 2459 /* prsym(n->sym, 0); */ 2460 break; 2461 case OARRIND: 2462 egen(n->left, op, LEFT); 2463 prdelim("["); 2464 egen(n->right, ONOOP, RIGHT); 2465 prdelim("]"); 2466 if(n->right->op == OCONST && n->right->vconst < 0) 2467 prcom("negative array index", Z); 2468 break; 2469 case OLEN: 2470 prid("len "); 2471 egen(n->right, op, PRE); 2472 break; 2473 case OREF: 2474 prid("ref "); 2475 tgen(n->type->link, 0, 0); 2476 break; 2477 case OARRAYOF: 2478 prid("array"); 2479 prdelim("["); 2480 egen(n->left, ONOOP, LEFT); 2481 prdelim("]"); 2482 prid(" of "); 2483 tgen(n->type->link, 0, 0); 2484 break; 2485 case OSLICE: 2486 egen(n->left, op, LEFT); 2487 prdelim("["); 2488 egen(n->right->left, ONOOP, RIGHT); 2489 prdelim(": "); 2490 egen(n->right->right, ONOOP, RIGHT); 2491 prdelim("]"); 2492 break; 2493 case OFUNC: 2494 if(n->kind == KEXP) 2495 egen(n->left, op, LEFT); 2496 else 2497 prsym(n->left->sym, 0); 2498 lgen(n->right, 1, 1); 2499 if(n->kind != KEXP && !isvoid(n->left->type->link)){ 2500 prdelim(": "); 2501 tgen(n->left->type->link, 0, 0); 2502 } 2503 break; 2504 case ONIL: 2505 prid("nil"); 2506 break; 2507 case OCAST: 2508 if(isnil(n)) 2509 prid("nil"); 2510 else if(iscastable(n->type, n->left->type)){ 2511 tgen(n->type, 0, 0); 2512 prdelim(" "); 2513 egen(n->left, op, RIGHT); 2514 } 2515 else 2516 egen(n->left, op0, RIGHT); 2517 break; 2518 case OARRAY: 2519 tgen(n->type, 0, 0); 2520 egen(n->left, op, LEFT); 2521 prdelim("["); 2522 egen(n->right, ONOOP, RIGHT); 2523 prdelim("]"); 2524 break; 2525 case OSTRUCT: 2526 case OUNION: 2527 tgen(n->type, 0, 0); 2528 lgen(n->left, 1, 1); 2529 break; 2530 case OELEM: 2531 prdelim("."); 2532 /* tgen(n->type, 0, 0, 0); */ 2533 prsym(n->sym, 0); 2534 break; 2535 case OSIZE: 2536 case OSIGN: 2537 prid(ops[op].name); 2538 if(n->left != Z) 2539 egen(n->left, OBRACKET, RIGHT); 2540 else{ 2541 prdelim(" "); 2542 prid(tnames[n->type->etype]); 2543 if(typesu[n->type->etype] && n->type->tag){ 2544 prdelim(" "); 2545 prid(n->type->tag->name); 2546 } 2547 } 2548 break; 2549 case OPROTO: 2550 nn = n; 2551 t = n->type; 2552 n = protoname(n); 2553 if(n != Z) 2554 t = n->type; 2555 else 2556 t = prototype(nn->left, t); 2557 if(!isvoid(t) || n != Z){ 2558 if(n == Z) 2559 prid("nil"); 2560 else if(n->op == ODOTDOT){ 2561 prcom("was ...", Z); 2562 break; 2563 } 2564 else 2565 prsym(n->sym, 0); 2566 /* egen(n, ONOOP, PRE); */ 2567 prdelim(": "); 2568 tgen(t, 1, 0); 2569 } 2570 break; 2571 case ODOTDOT: 2572 prid("..."); 2573 break; 2574 case OINIT: 2575 egen(n->left, ONOOP, PRE); 2576 break; 2577 case OS2AB: 2578 prid("libc0->s2ab"); 2579 prdelim("("); 2580 egen(n->left, ONOOP, PRE); 2581 prdelim(")"); 2582 usemod(libcop, 1); 2583 break; 2584 case OAB2S: 2585 prid("libc0->ab2s"); 2586 prdelim("("); 2587 egen(n->left, ONOOP, PRE); 2588 prdelim(")"); 2589 usemod(libcop, 1); 2590 break; 2591 case OFILDES: 2592 prid("sys->fildes"); 2593 prdelim("("); 2594 egen(n->left, ONOOP, PRE); 2595 prdelim(")"); 2596 usemod(sysop, 1); 2597 break; 2598 case OFD: 2599 egen(n->left, op, LEFT); 2600 prdelim(ops[op].name); 2601 prid("fd"); 2602 break; 2603 case OT0: 2604 egen(n->left, op, LEFT); 2605 prdelim(ops[op].name); 2606 prid("t0"); 2607 break; 2608 case ORETV: 2609 n->op = OAS; 2610 nn = n->left; 2611 p = isvoid(n->type) || n->type->etype != TTUPLE || n->type->mark == TCPC; 2612 if(p) 2613 n->left = n->right; 2614 else 2615 n->left = new1(OTUPLE, new1(ONIL, Z, Z), n->right); 2616 n->right = nn; 2617 n->left->type = n->type; 2618 if(!p && op0 != ONOOP) 2619 addnode(OT0, n); 2620 egen(n, op0, side); 2621 break; 2622 case OCAT: 2623 egen(n->left, op, LEFT); 2624 prdelim(" + "); 2625 egen(n->right, op, RIGHT); 2626 break; 2627 } 2628 preced(op0, op, side, ')'); 2629 } 2630 2631 static int 2632 isexpr(Node *n, Type *t) 2633 { 2634 if(n == Z) 2635 return 0; 2636 if(n->op == OLIST || n->op == OINIT || n->op == OSTRUCT) 2637 return 0; 2638 if(teq(t, n->type)) 2639 return 1; 2640 return 0; 2641 } 2642 2643 static Node * 2644 nxtval(Node *n, Node **nn) 2645 { 2646 if(n == Z){ 2647 *nn = Z; 2648 return Z; 2649 } 2650 if(n->op == OLIST){ 2651 *nn = n->right; 2652 return n->left; 2653 } 2654 *nn = Z; 2655 return n; 2656 } 2657 2658 static Node* 2659 eagen(Node *n, Type *t, int ar, int *nz, int depth) 2660 { 2661 int i, w, nw, down; 2662 Type *t1; 2663 Node *nn, *tn; 2664 2665 if(n != Z){ 2666 if(n->type == T && t == T){ 2667 egen(n, ONOOP, PRE); 2668 if(ar){ 2669 prdelim(","); 2670 newline(); 2671 } 2672 return Z; 2673 } 2674 if(ar && n->op == OLIST && n->left->op == OARRAY){ 2675 egen(n->left->left, ONOOP, PRE); 2676 prdelim(" => "); 2677 n = n->right; 2678 } 2679 if(n->op == OLIST && n->left->op == OELEM){ 2680 prcom("cannot do ", n->left); 2681 n = n->right; 2682 } 2683 if(n->op == OUSED || n->op == ODOTDOT) 2684 n = n->left; 2685 if(t == T) 2686 t = n->type; 2687 } 2688 switch(t->etype){ 2689 case TSTRUCT: 2690 case TUNION: 2691 if(isexpr(n, t)) 2692 goto Default; 2693 down = 0; 2694 tn = nxtval(n, &nn); 2695 if(tn != Z && (tn->op == OINIT || tn->op == OSTRUCT)){ 2696 down = 1; 2697 n = tn->left; 2698 } 2699 if(depth > 0){ 2700 tgen(t, 0, 0); 2701 prdelim(" "); 2702 } 2703 prdelim("("); 2704 for(t1 = t->link; t1 != T; t1 = t1->down){ 2705 if(n == Z) 2706 n = defval(t1); 2707 n = eagen(n, t1, 0, nil, depth+1); 2708 if(t1->down != T){ 2709 prdelim(","); 2710 if(ar) 2711 prdelim("\t"); 2712 else 2713 prdelim(" "); 2714 } 2715 } 2716 prdelim(")"); 2717 if(down) 2718 n = nn; 2719 break; 2720 case TARRAY: 2721 if(isexpr(n, t)) 2722 goto Default; 2723 if(depth > 0){ 2724 tgen(t, 0, 1); 2725 prdelim(" "); 2726 } 2727 prdelim("{"); 2728 newline(); 2729 incind(); 2730 w = t->width/t->link->width; 2731 nw = 0; 2732 for(i = 0; i < w; i++){ 2733 down = 0; 2734 tn = nxtval(n, &nn); 2735 if(tn != Z && (tn->op == OINIT || tn->op == OSTRUCT)){ 2736 down = 1; 2737 n = tn->left; 2738 } 2739 n = eagen(n, t->link, 1, &nw, depth+1); 2740 if(down) 2741 n = nn; 2742 } 2743 if(nw > 0){ 2744 if(nw > 1) 2745 prdelim("* => "); 2746 egen(defval(t->link), ONOOP, PRE); 2747 newline(); 2748 } 2749 decind(); 2750 prdelim("}"); 2751 break; 2752 default: 2753 Default: 2754 if(n == Z){ 2755 if(ar) 2756 (*nz)++; 2757 else 2758 egen(defval(t), ONOOP, PRE); 2759 return Z; 2760 } 2761 n = nxtval(n, &nn); 2762 if(ar && isnil(n) && iscastable(t, types[TINT])){ 2763 tgen(t, 0, 0); 2764 prdelim(" "); 2765 } 2766 egen(n, ONOOP, PRE); 2767 n = nn; 2768 break; 2769 } 2770 if(ar){ 2771 prdelim(","); 2772 newline(); 2773 } 2774 return n; 2775 } 2776 2777 /* better is 2778 * array of byte "abcde\0" 2779 * but limbo compiler does not accept this as a constant expression 2780 */ 2781 static void 2782 stob(Node *n) 2783 { 2784 int m; 2785 char *s = nil, buf[UTFmax]; 2786 Rune *u = nil; 2787 2788 while(n->op == ONAME) 2789 n = n->sym->nconst; 2790 if(n->op == OSTRING) 2791 s = n->cstring; 2792 else 2793 u = n->rstring; 2794 prdelim("{ "); 2795 if(s){ 2796 while(*s){ 2797 prid("byte "); 2798 prchar(*s++); 2799 prdelim(", "); 2800 } 2801 } 2802 else{ 2803 while(*u){ 2804 m = runetochar(buf, u++); 2805 s = buf; 2806 while(--m >= 0){ 2807 prid("byte "); 2808 prchar(*s++); 2809 prdelim(", "); 2810 } 2811 } 2812 } 2813 prid("byte "); 2814 prchar('\0'); 2815 prdelim(" }"); 2816 } 2817 2818 static Type *arrayofchar; 2819 2820 static void 2821 sdgen(Node *n, int glob) 2822 { 2823 int sop = 0; 2824 2825 prdelim(" := "); 2826 if(glob && n->right->op == OS2AB && isstring(n->right->left)){ 2827 if(arrayofchar == T){ 2828 arrayofchar = typ1(TARRAY, types[TCHAR]); 2829 arrayofchar->width = 0; 2830 } 2831 n->type = n->right->type = arrayofchar; 2832 sop = 1; 2833 } 2834 else 2835 n->type = n->right->type = T; 2836 tgen(n->type, 0, 1); 2837 if(sop) 2838 stob(n->right->left); 2839 else 2840 eagen(n->right, n->type, 0, nil, 0); 2841 prdelim(";"); 2842 newline(); 2843 } 2844 2845 static void 2846 tdgen(Node *n, int glob) 2847 { 2848 int ar, arinit; 2849 2850 if(ism()){ 2851 prdelim(": "); 2852 tgen(n->type, 1, 0); 2853 if(n->op == ODAS) 2854 prcom("initial value was ", n->right); 2855 prdelim(";"); 2856 newline(); 2857 return; 2858 } 2859 if(n->op == ODAS && (isstring(n->right) || n->right->op == OS2AB)){ 2860 sdgen(n, glob); 2861 return; 2862 } 2863 ar = n->type->etype == TARRAY && n->type->width != LARR; 2864 arinit = ar && n->op == ODAS; 2865 if(ar) 2866 prdelim(" := "); 2867 else 2868 prdelim(": "); 2869 tgen(n->type, 0, arinit); 2870 if(n->op == ODAS){ 2871 if(!arinit) 2872 prdelim(" = "); 2873 eagen(n->right, n->type, 0, nil, 0); 2874 } 2875 prdelim(";"); 2876 newline(); 2877 } 2878 2879 static int 2880 isdec(Node *n) 2881 { 2882 return isname(n) && n->kind != KEXP || n->op == ODAS; 2883 } 2884 2885 static void 2886 sgen(Node *n, int blk, Node **ln) 2887 { 2888 int comma = 0; 2889 Node *nn; 2890 2891 if(n == Z) 2892 return; 2893 if(blk){ 2894 pushscope(n, SAUTO); 2895 if(n->op == OLIST && !(blk&NOBR) || (blk&YESBR)){ 2896 prdelim("{"); 2897 newline(); 2898 } 2899 else if(!(blk&NONL)) 2900 newline(); 2901 if(!(blk&NOIN)) 2902 incind(); 2903 } 2904 if((nn = *ln) != Z && isdec(nn)){ 2905 if(isdec(n)){ 2906 if(canjoin(nn, n)) 2907 comma = 1; 2908 else 2909 tdgen(nn, 0); 2910 } 2911 else if(n->op != OLIST){ 2912 tdgen(nn, 0); 2913 newline(); 2914 } 2915 } 2916 if(n->op != OLIST){ 2917 *ln = n; 2918 output(n->lineno, 1); 2919 } 2920 switch(n->op){ 2921 default: 2922 egen(n, ONOOP, PRE); 2923 prdelim(";"); 2924 newline(); 2925 break; 2926 case ODAS: 2927 pushdcl(n->left, CAUTO); 2928 egen(n->left, ONOOP, PRE); 2929 break; 2930 case ONAME: 2931 if(n->kind == KEXP){ 2932 egen(n, ONOOP, PRE); 2933 prdelim(";"); 2934 newline(); 2935 } 2936 else{ 2937 pushdcl(n, CAUTO); 2938 if(comma) 2939 prdelim(", "); 2940 if(n->op != ONAME) 2941 diag(n, "internal: not name in sgen"); 2942 prsym(n->sym, 0); 2943 /* egen(n, ONOOP, PRE); */ 2944 /* 2945 prdelim(": "); 2946 tgen(n->type, 0, 0, 0); 2947 prdelim(";"); 2948 newline(); 2949 */ 2950 } 2951 break; 2952 case OSBREAK: 2953 break; 2954 case ONUL: 2955 prdelim(";"); 2956 newline(); 2957 break; 2958 case OBLK: 2959 sgen(n->left, 1|YESBR, ln); 2960 break; 2961 case OLIST: 2962 sgen(n->left, 0, ln); 2963 sgen(n->right, 0, ln); 2964 break; 2965 case ORETURN: 2966 prkeywd("return"); 2967 if(n->left != Z) 2968 prdelim(" "); 2969 egen(n->left, ONOOP, PRE); 2970 prdelim(";"); 2971 newline(); 2972 break; 2973 case OLABEL: 2974 prcom("was label ", n->left); 2975 /* i = zeroind(); */ 2976 /* egen(n->left, ONOOP, PRE); */ 2977 /* prdelim(":"); */ 2978 newline(); 2979 /* restoreind(i); */ 2980 break; 2981 case OGOTO: 2982 prcom("was goto ", n->left); 2983 /* prkeywd("goto "); */ 2984 /* egen(n->left, ONOOP, PRE); */ 2985 prdelim(";"); 2986 newline(); 2987 break; 2988 case OCASE: 2989 for(nn = n->left; nn != Z; nn = nn->right){ 2990 if(nn != n->left) 2991 prkeywd(" or "); 2992 if(nn->left != Z) 2993 egen(nn->left, ONOOP, PRE); 2994 else 2995 prkeywd("*"); 2996 } 2997 prdelim(" =>"); 2998 clrbrk(n->right); 2999 sgen(n->right, 1|NOBR, ln); 3000 if(n->kind != KLAST && !hasbrk(n->right)){ 3001 prcom("fall through", Z); 3002 newline(); 3003 } 3004 break; 3005 case OSWITCH: 3006 prkeywd("case"); 3007 egen(n->left, OBRACKET, PRE); 3008 sgen(n->right, 1|NOIN|YESBR, ln); 3009 break; 3010 case OWHILE: 3011 prkeywd("while"); 3012 egen(n->left, OBRACKET, PRE); 3013 sgen(n->right, 1, ln); 3014 break; 3015 case ODWHILE: 3016 prkeywd("do"); 3017 sgen(n->right, 1|NOENL, ln); 3018 prkeywd("while"); 3019 egen(n->left, OBRACKET, PRE); 3020 prdelim(";"); 3021 newline(); 3022 break; 3023 case OFOR: 3024 prkeywd("for"); 3025 prdelim("("); 3026 egen(n->left->right->left, ONOOP, PRE); 3027 prdelim(";"); 3028 if(n->left->left != Z) 3029 prdelim(" "); 3030 egen(n->left->left, ONOOP, PRE); 3031 prdelim(";"); 3032 if(n->left->right->right != Z) 3033 prdelim(" "); 3034 egen(n->left->right->right, ONOOP, PRE); 3035 prdelim(")"); 3036 sgen(n->right, 1, ln); 3037 break; 3038 case OCONTINUE: 3039 prkeywd("continue"); 3040 prdelim(";"); 3041 newline(); 3042 break; 3043 case OBREAK: 3044 prkeywd("break"); 3045 prdelim(";"); 3046 newline(); 3047 break; 3048 case OIF: 3049 prkeywd("if"); 3050 egen(n->left, OBRACKET, PRE); 3051 if(n->right->left->op == OIF && n->right->left->right->right == Z && n->right->right != Z) /* avoid dangling else */ 3052 sgen(n->right->left, 1|YESBR, ln); 3053 else 3054 sgen(n->right->left, 1, ln); 3055 if(n->right->right != Z){ 3056 prdelim("else"); 3057 if(n->right->right->op == OIF){ /* merge else and if */ 3058 prdelim(" "); 3059 sgen(n->right->right, 1|NONL|NOIN, ln); 3060 } 3061 else 3062 sgen(n->right->right, 1, ln); 3063 } 3064 break; 3065 case OSET: 3066 case OUSED: 3067 prkeywd(ops[n->op].name); 3068 lgen(n->left, 1, 1); 3069 prdelim(";"); 3070 newline(); 3071 break; 3072 } 3073 if(blk){ 3074 if(!(blk&NOIN)) 3075 decind(); 3076 if(n->op == OLIST&& !(blk&NOBR) || (blk&YESBR)){ 3077 prdelim("}"); 3078 if(!(blk&NOENL)) 3079 newline(); 3080 } 3081 popscope(); 3082 } 3083 } 3084 3085 static void rew(Node*, int); 3086 3087 static void 3088 rewc0(Node *n, Node *r) 3089 { 3090 Node *nn; 3091 3092 if((nn = cfind(n)) != Z){ 3093 cgen0(nn, n); 3094 if(r->op == ORETURN){ 3095 n->right->left = new1(ORETURN, n->right->left, Z); 3096 n->right->right = new1(ORETURN, n->right->right, Z); 3097 n->right->left->type = n->right->left->left->type; 3098 n->right->right->type = n->right->right->left->type; 3099 *r = *n; 3100 } 3101 } 3102 } 3103 3104 static void 3105 rewc1(Node *n) 3106 { 3107 Node *c, *nc; 3108 3109 if(n == Z || n->op != OCOND || side(n) || !simple(n)) 3110 return; 3111 c = n->left; 3112 nc = new1(ONOT, ncopy(c), Z); 3113 n->op = OOROR; 3114 n->left = new1(OANDAND, c, n->right->left); 3115 n->right = new1(OANDAND, nc, n->right->right); 3116 } 3117 3118 static void 3119 rewc(Node *n, Node *r) 3120 { 3121 Node *nn, *rr, *i; 3122 3123 if((nn = cfind(n)) != Z){ 3124 i = cgen(nn, n); 3125 rr = new1(OXXX, Z, Z); 3126 if(n == r && nn == n) 3127 *rr = *nn; 3128 else 3129 *rr = *r; 3130 r->op = OLIST; 3131 r->left = i; 3132 r->right = rr; 3133 } 3134 } 3135 3136 static int 3137 rewe(Node *n, Type *t, int lev) 3138 { 3139 int op, k, k1, k2; 3140 int v; 3141 Node *nn; 3142 3143 if(n == Z) 3144 return -1; 3145 switch(n->op){ 3146 case OCONST: 3147 break; 3148 case ONAME: 3149 if(strings || !isstring(n)) 3150 break; 3151 case OSTRING: 3152 case OLSTRING: 3153 if(!strings) 3154 addnode(OS2AB, n); 3155 break; 3156 case OCOND: 3157 bptr(n->left); 3158 rewe(n->left, T, 1); 3159 rewe(n->right, T, 1); 3160 break; 3161 case OIND: 3162 if(isfn(n->type)){ 3163 *n = *n->left; 3164 rewe(n, T, 1); 3165 break; 3166 } 3167 if(!isadt(n->type)){ 3168 n->op = OARRIND; 3169 n->right = con(0); 3170 rewe(n, T, 1); 3171 break; 3172 } 3173 rewe(n->left, T, 1); 3174 break; 3175 case OADDR: 3176 if(n->left->op == OARRIND){ 3177 n->right = n->left; 3178 n->left = n->right->left; 3179 n->right->left = n->right->right; 3180 n->right->right = Z; 3181 n->right->op = OLIST; 3182 n->op = OSLICE; 3183 rewe(n, T, 1); 3184 break; 3185 } 3186 rewe(n->left, T, 1); 3187 break; 3188 case OSLICE: 3189 rewe(n->left, T, 1); 3190 rewe(n->right, T, 1); 3191 if(n->left->op == OSLICE){ 3192 n->right->left = addn(n->left->right->left, n->right->left); 3193 n->right->right = addn(n->left->right->left, n->right->right); 3194 n->left = n->left->left; 3195 rewe(n, T, 1); 3196 break; 3197 } 3198 break; 3199 case OCOMMA: 3200 rewe(n->left, T, 1); 3201 rewe(n->right, T, 1); 3202 if(n->left->op == OAS && n->right->op == OAS){ 3203 n->op = OAS; 3204 n->left->op = n->right->op = OLIST; 3205 nn = n->left->right; 3206 n->left->right = n->right->left; 3207 n->right->left = nn; 3208 rewe(n, T, 1); 3209 break; 3210 } 3211 break; 3212 case OFUNC: 3213 if(n->left->op == ONAME){ 3214 if((k = n->left->sym->kind) != LNONE){ 3215 rewlc(n, k, t); 3216 rewe(n->left, T, 1); 3217 rewe(n->right, T, 1); 3218 args(n); 3219 return k; 3220 } 3221 } 3222 else 3223 rewe(n->left, T, 1); 3224 rewe(n->right, T, 1); 3225 args(n); 3226 break; 3227 case OCAST: 3228 rewe(n->left, n->type, 1); 3229 break; 3230 case OAS: 3231 case OASI: 3232 case OASD: 3233 rewe(n->left, T, 1); 3234 rewe(n->right, n->type, 1); 3235 break; 3236 case ONOT: 3237 case OANDAND: 3238 case OOROR: 3239 bptr(n); 3240 rewe(n->left, T, 1); 3241 rewe(n->right, T, 1); 3242 break; 3243 case OPREINC: 3244 case OPOSTINC: 3245 case OASADD: 3246 if(n->op != OPOSTINC || lev == 0){ 3247 sliceasgn(n); 3248 if(n->op == OAS){ 3249 rewe(n, T, 1); 3250 break; 3251 } 3252 } 3253 rewe(n->left, T, 1); 3254 rewe(n->right, T, 1); 3255 break; 3256 case OEQ: 3257 case ONE: 3258 case OLT: 3259 case OLE: 3260 case OGT: 3261 case OGE: 3262 k1 = rewe(n->left, T, 1); 3263 k2 = rewe(n->right, T, 1); 3264 if(k1 == LSTRCMP && n->right->op == OCONST){ 3265 op = -1; 3266 v = n->right->vconst; 3267 switch(v){ 3268 case -1: 3269 if(n->op == OEQ) 3270 op = OLT; 3271 else if(n->op == ONE) 3272 op = OGE; 3273 break; 3274 case 0: 3275 op = n->op; 3276 break; 3277 case 1: 3278 if(n->op == OEQ) 3279 op = OGT; 3280 else if(n->op == ONE) 3281 op = OLE; 3282 break; 3283 } 3284 if(op != -1){ 3285 *n = *n->left; 3286 n->op = op; 3287 } 3288 } 3289 if(k2 == LSTRCMP && n->left->op == OCONST){ 3290 op = -1; 3291 v = n->left->vconst; 3292 switch(v){ 3293 case -1: 3294 if(n->op == OEQ) 3295 op = OLT; 3296 else if(n->op == ONE) 3297 op = OGE; 3298 break; 3299 case 0: 3300 op = rev(n->op); 3301 break; 3302 case 1: 3303 if(n->op == OEQ) 3304 op = OGT; 3305 else if(n->op == ONE) 3306 op = OLE; 3307 break; 3308 } 3309 if(op != -1){ 3310 *n = *n->right; 3311 n->op = op; 3312 } 3313 } 3314 break; 3315 default: 3316 rewe(n->left, T, 1); 3317 rewe(n->right, T, 1); 3318 break; 3319 } 3320 return -1; 3321 } 3322 3323 /* 3324 static void 3325 rewf(Node *n) 3326 { 3327 if(n == Z) 3328 return; 3329 switch(n->op){ 3330 case OFUNC: 3331 if(n->left->op == ONAME) 3332 fdargs(n); 3333 break; 3334 default: 3335 rewf(n->left); 3336 rewf(n->right); 3337 break; 3338 } 3339 } 3340 */ 3341 3342 static void 3343 rew(Node *n, int blk) 3344 { 3345 int i; 3346 Node *a, *nn; 3347 3348 if(n == Z) 3349 return; 3350 if(blk) 3351 pushscope(n, SAUTO); 3352 nearln = n->lineno; 3353 if(n->blk){ 3354 n->blk = 0; 3355 addnode(OBLK, n); 3356 } 3357 switch(n->op){ 3358 default: 3359 if(simple(n)) 3360 rewc0(n, n); 3361 else 3362 rewc(n, n); 3363 if(n->op == OLIST || n->op == OIF){ 3364 rew(n, 0); 3365 break; 3366 } 3367 ecomplex(n); 3368 break; 3369 case ODAS: 3370 pushdcl(n->left, CAUTO); 3371 rewe(n->right, T, 1); 3372 break; 3373 case OSBREAK: 3374 case ONUL: 3375 break; 3376 case ONAME: 3377 if(n->kind == KEXP) 3378 ecomplex(n); 3379 else 3380 pushdcl(n, CAUTO); 3381 break; 3382 case OBLK: 3383 rew(n->left, 1); 3384 break; 3385 case OLIST: 3386 rew(n->left, 0); 3387 rew(n->right, 0); 3388 break; 3389 case ORETURN: 3390 if(simple(n->left)) 3391 rewc0(n->left, n); 3392 else 3393 rewc(n->left, n); 3394 if(n->op != ORETURN){ 3395 rew(n, 0); 3396 break; 3397 } 3398 ecomplex(n); 3399 break; 3400 case OLABEL: 3401 case OGOTO: 3402 break; 3403 case OCASE: 3404 for(nn = n->left; nn != Z; nn = nn->right) 3405 if(nn->left != Z) 3406 ecomplex(nn->left); 3407 rew(n->right, 1); 3408 break; 3409 case OSWITCH: 3410 rewc(n->left, n); 3411 if(n->op == OLIST){ 3412 rew(n, 0); 3413 break; 3414 } 3415 ecomplex(n->left); 3416 if(!lteq(n->left->type, types[TINT])) 3417 intcast(n->left); 3418 n->right = buildcases(n->right); 3419 rew(n->right, 1); 3420 break; 3421 case OWHILE: 3422 case ODWHILE: 3423 rewc1(n->left); 3424 becomplex(n->left); 3425 rew(n->right, 1); 3426 break; 3427 case OFOR: 3428 rewc1(n->left->left); 3429 rewc(n->left->right->left, n); 3430 if(n->op == OLIST){ 3431 rew(n, 0); 3432 break; 3433 } 3434 becomplex(n->left->left); 3435 ecomplex(n->left->right->left); 3436 ecomplex(n->left->right->right); 3437 rew(n->right, 1); 3438 break; 3439 case OCONTINUE: 3440 break; 3441 case OBREAK: 3442 break; 3443 case OIF: 3444 rewc1(n->left); 3445 rewc(n->left, n); 3446 if(n->op == OLIST){ 3447 rew(n, 0); 3448 break; 3449 } 3450 becomplex(n->left); 3451 rew(n->right->left, 1); 3452 rew(n->right->right, 1); 3453 break; 3454 case OSET: 3455 if(n->left == Z){ 3456 n->op = ONUL; 3457 n->left = n->right = Z; 3458 break; 3459 } 3460 if(n->left->op != OLIST){ 3461 n->op = OAS; 3462 n->right = defval(n->left->type); 3463 rew(n, 0); 3464 break; 3465 } 3466 i = 0; 3467 nn = Z; 3468 for(;;){ 3469 a = arg(n->left, i); 3470 if(a == Z) 3471 break; 3472 a = new1(OAS, a, defval(a->type)); 3473 if(i == 0) 3474 nn = a; 3475 else 3476 nn = new1(OLIST, nn, a); 3477 i++; 3478 } 3479 *n = *nn; 3480 rew(n, 0); 3481 break; 3482 case OUSED: 3483 if(n->left == Z){ 3484 n->op = ONUL; 3485 n->left = n->right = Z; 3486 break; 3487 } 3488 i = 0; 3489 nn = Z; 3490 for(;;){ 3491 a = arg(n->left, i); 3492 if(a == Z) 3493 break; 3494 if(i == 0) 3495 nn = a; 3496 else 3497 nn = new1(OOROR, nn, a); 3498 i++; 3499 } 3500 n->op = OIF; 3501 n->left = nn; 3502 n->right = new1(OLIST, Z, Z); 3503 n->right->left = new1(ONUL, Z, Z); 3504 rew(n, 0); 3505 break; 3506 } 3507 if(blk) 3508 popscope(); 3509 } 3510 3511 void 3512 codgen2(Node *n, Node *nn, int lastlno, int rw) 3513 { 3514 Node *ln = Z; 3515 3516 newsec(0); 3517 output(nn->lineno, 1); 3518 tmp = 0; 3519 /* t = types[TVOID]; */ 3520 nn = func(nn); 3521 pushscope(nn, SPARM); 3522 if(rw) 3523 rew(n, 1); 3524 egen(nn, ONOOP, PRE); 3525 newline(); 3526 prdelim("{"); 3527 newline(); 3528 incind(); 3529 /* rewf(n); */ 3530 pushscope(n, SAUTO); 3531 sgen(n, 0, &ln); 3532 if(ln != Z && isdec(ln)) 3533 tdgen(ln, 0); 3534 popscope(); 3535 popscope(); 3536 if(n != Z) 3537 output(lline(n), 1); 3538 output(lastlno, 1); 3539 decind(); 3540 prdelim("}"); 3541 newline(); 3542 newline(); 3543 setmain(nn); 3544 } 3545 3546 void 3547 rewall(Node *n, Node *nn, int lastlno) 3548 { 3549 USED(lastlno); 3550 tmp = 0; 3551 nn = func(nn); 3552 pushscope(nn, SPARM); 3553 rew(n, 1); 3554 popscope(); 3555 setmain(nn); 3556 } 3557 3558 void 3559 suball(Node *n, Node *nn) 3560 { 3561 Node *rn; 3562 3563 nn = func(nn); 3564 pushscope(nn, SPARM); 3565 subs(nn, 0, 0); 3566 subs(n, 1, 1); 3567 nn = lastn(n); 3568 if(nn != Z && nn->op != ORETURN){ 3569 rn = retval(Z); 3570 if(rn != Z){ 3571 addnode(OLIST, nn); 3572 nn->right = rn; 3573 } 3574 } 3575 popscope(); 3576 } 3577 3578 void 3579 ginit(void) 3580 { 3581 thechar = 'o'; 3582 thestring = "386"; 3583 tfield = types[TLONG]; 3584 } 3585 3586 long 3587 align(long i, Type *t, int op) 3588 { 3589 long o; 3590 Type *v; 3591 int w; 3592 3593 o = i; 3594 w = 1; 3595 switch(op) { 3596 default: 3597 diag(Z, "unknown align opcode %d", op); 3598 break; 3599 3600 case Asu2: /* padding at end of a struct */ 3601 w = SZ_LONG; 3602 break; 3603 3604 case Ael1: /* initial allign of struct element */ 3605 for(v=t; v->etype==TARRAY; v=v->link) 3606 ; 3607 w = ewidth[v->etype]; 3608 if(w <= 0 || w >= SZ_LONG) 3609 w = SZ_LONG; 3610 break; 3611 3612 case Ael2: /* width of a struct element */ 3613 o += t->width; 3614 break; 3615 3616 case Aarg0: /* initial passbyptr argument in arg list */ 3617 if(typesuv[t->etype]) { 3618 o = align(o, types[TIND], Aarg1); 3619 o = align(o, types[TIND], Aarg2); 3620 } 3621 break; 3622 3623 case Aarg1: /* initial allign of parameter */ 3624 w = ewidth[t->etype]; 3625 if(w <= 0 || w >= SZ_LONG) { 3626 w = SZ_LONG; 3627 break; 3628 } 3629 w = 1; /* little endian no adjustment */ 3630 break; 3631 3632 case Aarg2: /* width of a parameter */ 3633 o += t->width; 3634 w = SZ_LONG; 3635 break; 3636 3637 case Aaut3: /* total allign of automatic */ 3638 o = align(o, t, Ael2); 3639 o = align(o, t, Ael1); 3640 w = SZ_LONG; /* because of a pun in cc/dcl.c:contig() */ 3641 break; 3642 } 3643 o = round(o, w); 3644 if(0) 3645 print("align %s %ld %T = %ld\n", bnames[op], i, t, o); 3646 return o; 3647 } 3648 3649 long 3650 maxround(long max, long v) 3651 { 3652 v = round(v, SZ_LONG); 3653 if(v > max) 3654 return v; 3655 return max; 3656 } 3657 3658 static int 3659 nlen(Node *n) 3660 { 3661 if(n == Z) 3662 return 0; 3663 if(n->op == OLIST) 3664 return nlen(n->left)+nlen(n->right); 3665 return 1; 3666 } 3667 3668 static void 3669 flatten(Node *n, Node **a, int *i) 3670 { 3671 if(n == Z) 3672 return; 3673 if(n->op == OLIST){ 3674 flatten(n->left, a, i); 3675 flatten(n->right, a, i); 3676 free(n); 3677 return; 3678 } 3679 a[(*i)++] = n; 3680 } 3681 3682 static Node* 3683 addcase(Node *n, Node **e, Node **s, int k) 3684 { 3685 Node *nn; 3686 3687 if(*e != Z){ 3688 nn = new1(OCASE, *e, *s); 3689 nn->right->blk = 0; 3690 nn->kind = k; 3691 } 3692 else 3693 nn = *s; 3694 *e = *s = Z; 3695 if(n == Z) 3696 return nn; 3697 return new1(OLIST, n, nn); 3698 } 3699 3700 /* collect case code together */ 3701 static Node* 3702 buildcases(Node *n) 3703 { 3704 int i, m, m0, c; 3705 Node *e, *s, *nn, **a, **ep; 3706 3707 m = nlen(n); 3708 a = (Node **)malloc(m*sizeof(Node*)); 3709 m0 = 0; 3710 flatten(n, a, &m0); 3711 if(m != m0) 3712 diag(Z, "internal: bad buildcases()"); 3713 c = 1; 3714 e = s = nn = Z; 3715 ep = &e; 3716 for(i = 0; i < m; i++){ 3717 n = a[i]; 3718 if(n->op == OCASE){ 3719 if(!c){ 3720 nn = addcase(nn, &e, &s, KNIL); 3721 ep = &e; 3722 } 3723 *ep = new1(OLIST, n->left, Z); 3724 if(n->left == Z) 3725 (*ep)->lineno = n->lineno; 3726 ep = &(*ep)->right; 3727 c = 1; 3728 } 3729 else{ 3730 if(s == Z) 3731 s = n; 3732 else 3733 s = new1(OLIST, s, n); 3734 c = 0; 3735 } 3736 } 3737 nn = addcase(nn, &e, &s, KLAST); 3738 free(a); 3739 return nn; 3740 } 3741 3742 static Sym * 3743 tmpgen(Type *t) 3744 { 3745 Sym *s; 3746 3747 sprint(buf, "tmp_%d", ++tmp); 3748 s = slookup(buf); 3749 s->type = t; 3750 s->class = CAUTO; 3751 if(t->etype == TENUM) 3752 s->type = types[TINT]; 3753 return s; 3754 } 3755 3756 static Node* 3757 cfind(Node *n) 3758 { 3759 Node *nn; 3760 3761 if(n == Z) 3762 return Z; 3763 if(n->op == OCOND) 3764 return n; 3765 nn = cfind(n->left); 3766 if(nn != Z) 3767 return nn; 3768 return cfind(n->right); 3769 } 3770 3771 Node* 3772 ncopy(Node *n) 3773 { 3774 Node *nn; 3775 3776 if(n == Z) 3777 return Z; 3778 nn = new1(n->op, Z, Z); 3779 *nn = *n; 3780 nn->left = ncopy(n->left); 3781 nn->right = ncopy(n->right); 3782 return nn; 3783 } 3784 3785 static int 3786 complexity(Node *n, int *cond) 3787 { 3788 int c; 3789 3790 if(n == Z) 3791 return 0; 3792 c = complexity(n->left, cond)+1+complexity(n->right, cond); 3793 if(n->op == OCOND) 3794 (*cond)++; 3795 return c; 3796 } 3797 3798 static int 3799 simple(Node *n) 3800 { 3801 int c; 3802 3803 c = 0; 3804 return complexity(n, &c) < COMPLEX && c <= 1; 3805 } 3806 3807 static Type* 3808 intype(Node *n) 3809 { 3810 Type *t; 3811 3812 t = ntype(n); 3813 if(t == T) 3814 return T; 3815 return t->link; 3816 } 3817 3818 static Type* 3819 ntype(Node *n) 3820 { 3821 Type *t; 3822 3823 if(n == Z) 3824 return T; 3825 t = n->type; 3826 if(t != T){ 3827 if(t->etype == TENUM) 3828 return n->sym->tenum; 3829 return t; 3830 } 3831 switch(n->op){ 3832 case OEQ: 3833 case ONE: 3834 case OLT: 3835 case OGE: 3836 case OGT: 3837 case OLE: 3838 case ONOT: 3839 case OANDAND: 3840 case OOROR: 3841 case OIOTA: 3842 return types[TINT]; 3843 case OCOMMA: 3844 return ntype(n->right); 3845 case OCOND: 3846 return maxtype(ntype(n->right->left), ntype(n->right->right)); 3847 case OFUNC: 3848 return intype(n->left); 3849 case ODOT: 3850 tcomd(n, ntype(n->left)); 3851 t = n->type; 3852 n->type = T; 3853 return t; 3854 case ODOTIND: 3855 tcomd(n, intype(n->left)); 3856 t = n->type; 3857 n->type = T; 3858 return t; 3859 case OARRIND: 3860 return intype(n->left); 3861 case OADDR: 3862 return typ1(TIND, ntype(n->left)); 3863 case OIND: 3864 return intype(n->left); 3865 case OSTRUCT: 3866 return T; 3867 } 3868 return maxtype(ntype(n->left), ntype(n->right)); 3869 } 3870 3871 static Type* 3872 gettype(Node *n1, Node *n2) 3873 { 3874 Type *t; 3875 3876 t = maxtype(n1->type, n2->type); 3877 if(t != T) 3878 return t; 3879 return maxtype(ntype(n1), ntype(n2)); 3880 } 3881 3882 static void 3883 cgen0(Node *n, Node *e) 3884 { 3885 Node *c, *nn, *ed, *ee; 3886 3887 if(n == e){ 3888 n->op = OIF; 3889 return; 3890 } 3891 c = n->left; 3892 ed = new1(OXXX, Z, Z); 3893 *ed = *e; 3894 ee = ncopy(e); 3895 nn = cfind(ee); 3896 *n = *n->right->left; 3897 *nn = *nn->right->right; 3898 e->op = OIF; 3899 e->left = c; 3900 e->right = new1(OLIST, ed, ee); 3901 } 3902 3903 static Node* 3904 cgen(Node *n, Node *e) 3905 { 3906 Type *t; 3907 Node *tn, *i; 3908 3909 USED(e); 3910 tn = new1(ONAME, Z, Z); 3911 t = gettype(n->right->left, n->right->right); 3912 tn->sym = tmpgen(t); 3913 tn->type = tn->sym->type; 3914 /* 3915 if(n == e){ 3916 n->op = OIF; 3917 n->right->left = new1(OASD, tn, n->right->left); 3918 n->right->right = new1(OAS, tn, n->right->right); 3919 return n; 3920 } 3921 */ 3922 i = new1(OIF, n->left, new1(OLIST, new1(OASD, tn, n->right->left), new1(OAS, tn, n->right->right))); 3923 *n = *tn; 3924 return i; 3925 } 3926 3927 static struct{ 3928 char *name; 3929 int args; 3930 int fd; 3931 char *lname; 3932 } sysops[] = { 3933 "create", 1, RET, nil, 3934 "dirstat", 1, 0, "stat", 3935 "dirfstat", 0, 1, "fstat", 3936 "dirwstat", 1, 0, "wstat", 3937 "dirfwstat", 0, 1, "fwstat", 3938 "dirread", 0, 1, nil, 3939 "dup", 0, 0, nil, 3940 "fprint", 2|STAR, 1, nil, 3941 "fprintf", 2|STAR, 1, "fprint", 3942 "open", 1, RET, nil, 3943 "print", 1|STAR, 0, nil, 3944 "printf", 1|STAR, 0, "print", 3945 "read", 0, 1, nil, 3946 "remove", 1, 0, nil, 3947 "seek", 0, 1, nil, 3948 "sleep", 0, 0, nil, 3949 "sprint", 1|STAR, 0, nil, 3950 "sprintf", 1|STAR, 0, "sprint", 3951 "write", 0, 1, nil, 3952 0 3953 }; 3954 3955 /* dummy entry for module */ 3956 #define BIOTMP "__bio__" 3957 3958 static struct{ 3959 char *name; 3960 char *lname; 3961 } bioops[] = { 3962 "Bflush", "flush", 3963 "Bgetc", "getc", 3964 "Bprint", "puts", 3965 "Bputc", "putc", 3966 "Bread", "read", 3967 "Bseek", "seek", 3968 "Bungetc", "ungetc", 3969 "Bwrite", "write", 3970 BIOTMP, nil, 3971 0 3972 }; 3973 3974 char *libcops[] = { 3975 "isalnum", 3976 "isalpha", 3977 "isascii", 3978 "iscntrl", 3979 "isdigit", 3980 "isgraph", 3981 "islower", 3982 "isprint", 3983 "ispunct", 3984 "isspace", 3985 "isupper", 3986 "isxdigit", 3987 "strchr", 3988 "strrchr", 3989 "toascii", 3990 "tolower", 3991 "toupper", 3992 "abs", 3993 "min", 3994 "max", 3995 0, 3996 }; 3997 3998 static struct{ 3999 char *name; 4000 int type; 4001 int string; 4002 } xops[] = { 4003 "strlen", LSTRLEN, 1, 4004 "strcmp", LSTRCMP, 1, 4005 "strcpy", LSTRCPY, 1, 4006 "strcat", LSTRCAT, 1, 4007 "strncmp", LSTRNCMP, 1, 4008 "strncpy", LSTRNCPY, 1, 4009 "strncat", LSTRNCAT, 1, 4010 "strdup", LSTRDUP, 1, 4011 "memcpy", LMEMMOVE, 0, 4012 "memmove", LMEMMOVE, 0, 4013 "malloc", LMALLOC, 0, 4014 "free", LFREE, 0, 4015 "exit", LEXIT, 0, 4016 "exits", LEXIT, 0, 4017 "close", LCLOSE, 0, 4018 "atoi", LATOI, 0, 4019 "atol", LATOI, 0, 4020 "atoll", LATOL, 0, 4021 "atof", LATOF, 0, 4022 "atod", LATOF, 0, 4023 "print", LPRINT, 0, 4024 "printf", LPRINT, 0, 4025 "fprint", LFPRINT, 0, 4026 "fprintf", LFPRINT, 0, 4027 "sprint", LSPRINT, 0, 4028 "sprintf", LSPRINT, 0, 4029 0 4030 }; 4031 4032 char *mathsops[] = { 4033 "sin", 4034 "cos", 4035 "tan", 4036 "sinh", 4037 "cosh", 4038 "tanh", 4039 "asin", 4040 "acos", 4041 "atan", 4042 "asinh", 4043 "acosh", 4044 "atanh", 4045 "atan2", 4046 "sqrt", 4047 "cbrt", 4048 "pow", 4049 "pow10", 4050 "exp", 4051 "log", 4052 "log10", 4053 0 4054 }; 4055 4056 Node *glob, *globe; 4057 4058 void 4059 sysinit(void) 4060 { 4061 int i; 4062 Sym *s; 4063 4064 glob = globe = new1(ONOOP, Z, Z); 4065 for(i = 0; sysops[i].name; i++){ 4066 s = slookup(sysops[i].name); 4067 s->class = CEXTERN; 4068 s->args = sysops[i].args; 4069 s->fd = sysops[i].fd; 4070 s->mod = "sys"; 4071 s->lname = sysops[i].lname; 4072 s->limbo = 1; 4073 sysop = s; 4074 } 4075 for(i = 0; bioops[i].name; i++){ 4076 s = slookup(bioops[i].name); 4077 s->class = CEXTERN; 4078 if(strcmp(bioops[i].name, BIOTMP) == 0){ 4079 s->mod = "bufio"; 4080 bioop = s; 4081 } 4082 s->lname = bioops[i].lname; 4083 s->kind = LSELF; 4084 s->limbo = 1; 4085 } 4086 for(i = 0; mathsops[i]; i++){ 4087 s = slookup(mathsops[i]); 4088 s->class = CEXTERN; 4089 s->mod = "math"; 4090 s->limbo = 1; 4091 } 4092 for(i = 0; libcops[i]; i++){ 4093 s = slookup(libcops[i]); 4094 s->class = CEXTERN; 4095 s->mod = strings ? "libc" : "libc0"; 4096 s->limbo = 1; 4097 libcop = s; 4098 } 4099 for(i = 0; xops[i].name; i++){ 4100 s = slookup(xops[i].name); 4101 s->class = CEXTERN; 4102 if(strings || !xops[i].string) 4103 s->kind = xops[i].type; 4104 else 4105 s->mod = "libc0"; 4106 if(s->kind == LEXIT) 4107 s->lname = "exit"; 4108 s->limbo = 1; 4109 } 4110 usemod(sysop, 1); 4111 if(!strings) 4112 usemod(libcop, 1); 4113 } 4114 4115 void 4116 clbegin(void) 4117 { 4118 pushscope(glob, SGLOB); 4119 } 4120 4121 void 4122 clend(void) 4123 { 4124 if(passes) 4125 swalk(); 4126 popscope(); 4127 } 4128 4129 static Modl *mods; 4130 4131 void 4132 usemod(Sym *s, int ld) 4133 { 4134 Modl *ml; 4135 4136 for(ml = mods; ml != nil; ml = ml->nxt) 4137 if(strcmp(ml->mod, s->mod) == 0){ 4138 ml->ld |= ld; 4139 return; 4140 } 4141 ml = (Modl *)malloc(sizeof(Modl)); 4142 ml->mod = s->mod; 4143 ml->ld = ld; 4144 ml->nxt = mods; 4145 mods = ml; 4146 } 4147 4148 static void 4149 ginc(Modl *ml) 4150 { 4151 int c; 4152 char *s; 4153 4154 if(ml == nil) 4155 return; 4156 if(ml->nxt != nil) 4157 ginc(ml->nxt); 4158 s = ml->mod; 4159 c = toupper(s[0]); 4160 sprint(buf, "include \"%s.m\";", s); 4161 prline(buf); 4162 if(ml->ld){ 4163 sprint(buf, " %s: %c%s;", s, c, s+1); 4164 prline(buf); 4165 } 4166 } 4167 4168 static void 4169 gload(Modl *ml) 4170 { 4171 int c; 4172 char *s; 4173 4174 if(ml == nil) 4175 return; 4176 if(ml->nxt != nil) 4177 gload(ml->nxt); 4178 if(ml->ld){ 4179 s = ml->mod; 4180 c = toupper(s[0]); 4181 sprint(buf, " %s = load %c%s %c%s->PATH;", s, c, s+1, c, s+1); 4182 prline(buf); 4183 } 4184 } 4185 4186 static void 4187 callmain(void) 4188 { 4189 if(inmain){ 4190 if(strings) 4191 prline(" main(len argl, argl);"); 4192 else 4193 prline(" main(len argl, libc0->ls2aab(argl));"); 4194 } 4195 } 4196 4197 static void 4198 genstart(void) 4199 { 4200 char *s; 4201 4202 if(!strings && inmain) 4203 usemod(libcop, 1); 4204 ginc(mods); 4205 s = hasm(); 4206 if(s){ 4207 sprint(buf, "include \"%s\";", s); 4208 prline(buf); 4209 } 4210 prline(""); 4211 prline("init(nil: ref Draw->Context, argl: list of string)"); 4212 prline("{"); 4213 gload(mods); 4214 callmain(); 4215 prline("}"); 4216 prline(""); 4217 } 4218 4219 static int 4220 argpos0(Node *nn, Node *n, int *p) 4221 { 4222 int pp; 4223 4224 if(n == Z) 4225 return -1; 4226 if(n->op == OLIST){ 4227 pp = argpos0(nn, n->left, p); 4228 if(pp >= 0) 4229 return pp; 4230 return argpos0(nn, n->right, p); 4231 } 4232 if(n == nn) 4233 return *p; 4234 (*p)++; 4235 return -1; 4236 } 4237 4238 static int 4239 argpos(Node *nn, Node *n) 4240 { 4241 int p = 0; 4242 4243 p = argpos0(nn, n, &p); 4244 if(p < 0) 4245 diag(Z, "-ve argpos"); 4246 return p; 4247 } 4248 4249 static Node* 4250 arg0(Node *n, int a, int *i) 4251 { 4252 Node *nn; 4253 4254 if(n == Z) 4255 return Z; 4256 if(n->op == OLIST){ 4257 nn = arg0(n->left, a, i); 4258 if(nn != Z) 4259 return nn; 4260 return arg0(n->right, a, i); 4261 } 4262 if(a == (*i)++) 4263 return n; 4264 return Z; 4265 } 4266 4267 static Node* 4268 arg(Node *n, int a) 4269 { 4270 int i = 0; 4271 4272 return arg0(n, a, &i); 4273 } 4274 4275 static Node* 4276 list(Node *l, Node *r) 4277 { 4278 if(r == Z) 4279 return l; 4280 if(l == Z) 4281 return r; 4282 return new1(OLIST, l, r); 4283 } 4284 4285 static Node* 4286 droparg(Node *n, int a, int *i) 4287 { 4288 if(n == Z) 4289 return Z; 4290 if(n->op == OLIST) 4291 return list(droparg(n->left, a, i), droparg(n->right, a, i)); 4292 if(a == (*i)++) 4293 return Z; 4294 return n; 4295 } 4296 4297 static void 4298 sargs(Node *n) 4299 { 4300 int s, f, i, j; 4301 Node *a; 4302 4303 if(strings || (f = n->left->sym->args) == 0) 4304 return; 4305 s = 0; 4306 for(i = 1, j = 0; i < STAR || s; i *= 2, j++){ 4307 if(f&i || s){ 4308 a = arg(n->right, j); 4309 if(a == Z) 4310 break; 4311 if(s && !isstr(a->type)) 4312 continue; 4313 if(f&STAR) 4314 s++; 4315 if(a->op == OS2AB){ 4316 *a = *a->left; 4317 continue; 4318 } 4319 addnode(OAB2S, a); 4320 } 4321 } 4322 } 4323 4324 static void 4325 fdargs(Node *n) 4326 { 4327 int f, i, j; 4328 Node *a; 4329 4330 if((f = n->left->sym->fd) == 0) 4331 return; 4332 marktype(pfdtype, TCFD); 4333 if(f&RET) 4334 tcon(n, pfdtype); 4335 for(i = 1, j = 0; i < RET; i *= 2, j++){ 4336 if(f&i){ 4337 a = arg(n->right, j); 4338 if(a == Z) 4339 break; 4340 tcon(a, pfdtype); 4341 } 4342 } 4343 } 4344 4345 static void 4346 aargs(Node *n) 4347 { 4348 int i; 4349 Node *a, *nn, *fn; 4350 Type *t, *t0, *ft, *at, *st; 4351 4352 if(!doaddr) 4353 return; 4354 if(n->op != OFUNC || n->left->op != ONAME) 4355 return; 4356 /* ft = n->left->type; */ 4357 ft = n->left->sym->type; 4358 t = t0 = ft->link; 4359 nn = Z; 4360 for(i = 0; ; i++){ 4361 a = arg(n->right, i); 4362 if(a == Z) 4363 break; 4364 at = typn(ft, i); 4365 if(at != T && at->etype != TDOT && (a->op == OADDR || iteq(a->type, at) || iteq(at, a->type))){ 4366 if(iteq(at, a->type)) 4367 st = at->link; 4368 else 4369 st = a->type->link; 4370 if(doalladdr || isscalar(st)){ 4371 if(a->op == OADDR) 4372 *a = *a->left; 4373 else if(iteq(a->type, at)) 4374 a->type = at; 4375 if(t->mark == 0){ 4376 t = tuple(t, a->type); 4377 trep(at, at->link); 4378 fn = finddec(n->left->sym, 1); 4379 if(fn != Z && fn->op == OFUNC) 4380 tind(arg(fn->right, i)); 4381 } 4382 if(nn == Z) 4383 nn = cknil(ncopy(a)); 4384 else{ 4385 nn = new1(OTUPLE, nn, cknil(ncopy(a))); 4386 nn->type = t; 4387 } 4388 } 4389 } 4390 } 4391 if(nn != Z){ 4392 if(isvoid(t0) || t->mark == TCPC) 4393 marktype(t, TCPC); 4394 else 4395 marktype(t, TCFC); 4396 tcon(n, t); 4397 addnode(ORETV, n); 4398 n->right = nn; 4399 } 4400 } 4401 4402 static void 4403 args(Node *n) 4404 { 4405 if(n->op != OFUNC || n->left->op != ONAME) 4406 return; 4407 sargs(n); 4408 if(passes){ 4409 fdargs(n); 4410 aargs(n); 4411 } 4412 } 4413 4414 static Node* 4415 indir(Node *n) 4416 { 4417 if(n->op == OADDR) 4418 return n->left; 4419 return new1(OIND, n, Z); 4420 } 4421 4422 static void 4423 rewlc(Node *n, int k, Type *t) 4424 { 4425 int i; 4426 Type *tt; 4427 Node *a0, *a1, *a2, *nn; 4428 4429 if(t == T) 4430 t = n->type; 4431 a0 = arg(n->right, 0); 4432 a1 = arg(n->right, 1); 4433 switch(k){ 4434 case LSTRLEN: 4435 n->op = OLEN; 4436 break; 4437 case LSTRCMP: 4438 n->op = ONE; 4439 n->left = a0; 4440 n->right = a1; 4441 break; 4442 case LSTRCPY: 4443 n->op = OAS; 4444 n->left = a0; 4445 n->right = a1; 4446 n->type = n->left->type; 4447 break; 4448 case LSTRCAT: 4449 n->op = OASADD; 4450 n->left = a0; 4451 n->right = a1; 4452 n->type = n->left->type; 4453 break; 4454 case LSTRDUP: 4455 *n = *a0; 4456 break; 4457 case LMEMMOVE: 4458 if(!teq(a0->type, a1->type)) 4459 break; 4460 if(a0->type->etype == TIND){ 4461 tt = a0->type->link; 4462 a2 = arg(n->right, 2); 4463 if(isadt(tt) && isconst(a2, tt->width)){ 4464 n->op = OAS; 4465 n->left = indir(a0); 4466 n->right = indir(a1); 4467 n->type = n->left->type = n->right->type = tt; 4468 break; 4469 } 4470 if(mydiv(a2, tt->width) != Z){ 4471 n->op = OAS; 4472 n->left = new1(OSLICE, a0, new1(OLIST, con(0), Z)); 4473 n->right = new1(OSLICE, a1, new1(OLIST, con(0), a2)); 4474 n->type = n->left->type = n->right->type = a0->type; 4475 } 4476 } 4477 break; 4478 case LMALLOC: 4479 if(t->etype == TIND){ 4480 tt = t->link; 4481 if(isadt(tt) && isconst(a0, tt->width)){ 4482 n->op = OREF; 4483 n->left = Z; 4484 n->right = Z; 4485 n->type = t; 4486 break; 4487 } 4488 if(mydiv(a0, tt->width) != Z){ 4489 n->op = OARRAYOF; 4490 n->left = a0; 4491 n->right = Z; 4492 n->type = t; 4493 if(isadt(tt)){ 4494 n->type = typ1(TARRAY, tt); 4495 n->type->width = LARR; /* limbo array without bounds */ 4496 marktype(n->type, TCAR); 4497 } 4498 } 4499 } 4500 break; 4501 case LFREE: 4502 n->op = OAS; 4503 n->left = a0; 4504 n->right = con(0); 4505 n->type = n->left->type; 4506 n->right->type = n->type; 4507 break; 4508 case LEXIT: 4509 i = n->kind; 4510 *n = *n->left; 4511 n->kind = i; 4512 break; 4513 case LCLOSE: 4514 n->op = OAS; 4515 n->left = a0; 4516 n->right = con(0); 4517 n->left->type = typ1(TIND, n->left->type); 4518 n->type = n->left->type; 4519 n->right->type = n->type; 4520 break; 4521 case LATOI: 4522 if(!strings) 4523 strcast(a0); 4524 n->op = OCAST; 4525 n->left = a0; 4526 n->right = Z; 4527 n->type = types[TINT]; 4528 break; 4529 case LATOL: 4530 if(!strings) 4531 strcast(a0); 4532 n->op = OCAST; 4533 n->left = a0; 4534 n->right = Z; 4535 n->type = types[TVLONG]; 4536 break; 4537 case LATOF: 4538 if(!strings) 4539 strcast(a0); 4540 n->op = OCAST; 4541 n->left = a0; 4542 n->right = Z; 4543 n->type = types[TDOUBLE]; 4544 break; 4545 case LPRINT: 4546 if(a0->op == OSTRING) 4547 pfmt(a0->cstring); 4548 else if(a0->op == OLSTRING) 4549 lpfmt(a0->rstring); 4550 break; 4551 case LFPRINT: 4552 if(a1->op == OSTRING) 4553 pfmt(a1->cstring); 4554 else if(a1->op == OLSTRING) 4555 lpfmt(a1->rstring); 4556 break; 4557 case LSPRINT: 4558 if(n->right->kind != KDROP){ 4559 if(a1->op == OSTRING) 4560 pfmt(a1->cstring); 4561 else if(a1->op == OLSTRING) 4562 lpfmt(a1->rstring); 4563 nn = new1(OXXX, Z, Z); 4564 *nn = *n; 4565 i = 0; 4566 nn->right = droparg(nn->right, 0, &i); 4567 nn->right->kind = KDROP; 4568 n->op = OAS; 4569 n->left = a0; 4570 n->right = nn; 4571 n->type = nn->type; 4572 } 4573 break; 4574 case LSELF: 4575 if(n->right != Z && n->right->kind != KDROP){ 4576 i = 0; 4577 n->right = droparg(n->right, 0, &i); 4578 if(n->right != Z) 4579 n->right->kind = KDROP; 4580 addnode(OLDOT, n->left); 4581 n->left->right = n->left->left; 4582 n->left->left = a0; 4583 usemod(bioop, 1); 4584 } 4585 break; 4586 } 4587 } 4588 4589 void 4590 expgen(Node *n) 4591 { 4592 egen(n, ONOOP, PRE); 4593 } 4594 4595 static void 4596 clrbrk(Node *n) 4597 { 4598 if(n == Z) 4599 return; 4600 switch(n->op){ 4601 case OLIST: 4602 clrbrk(n->right); 4603 break; 4604 case OBREAK: 4605 n->op = OSBREAK; 4606 n->left = n->right = Z; 4607 break; 4608 } 4609 } 4610 4611 static int 4612 hasbrk(Node *n) 4613 { 4614 if(n == Z) 4615 return 0; 4616 switch(n->op){ 4617 case OLIST: 4618 case OWHILE: 4619 case ODWHILE: 4620 case OFOR: 4621 return hasbrk(n->right); 4622 case OIF: 4623 if(n->right->right == Z) 4624 return 0; 4625 return hasbrk(n->right->left) && hasbrk(n->right->right); 4626 case ORETURN: 4627 case OGOTO: 4628 case OCONTINUE: 4629 case OBREAK: 4630 case OSBREAK: 4631 return 1; 4632 default: 4633 return 0; 4634 } 4635 } 4636 4637 static int 4638 isgen(char *s) 4639 { 4640 char *s1, *s2; 4641 4642 s1 = strchr(s, '_'); 4643 s2 = strrchr(s, '_'); 4644 if(s1 == nil || s2-s1 != 4) 4645 return 0; 4646 return s1[1] == 'a' && s1[2] == 'd' && s1[3] == 't'; 4647 } 4648 4649 static void 4650 addmodn(Sym *s) 4651 { 4652 char buf[128], *ns; 4653 4654 if(s->name[0] == '_'){ 4655 outmod(buf, -1); 4656 ns = malloc(strlen(buf)+strlen(s->name)+1); 4657 strcpy(ns, buf); 4658 strcat(ns, s->name); 4659 s->name = ns; 4660 } 4661 } 4662 4663 static void 4664 pfmt(char *s) 4665 { 4666 char *t = s; 4667 4668 while(*s != '\0'){ 4669 if(*s == '%'){ 4670 *t++ = *s++; 4671 if(*s == 'l'){ 4672 s++; 4673 if(*s == 'l') 4674 *t++ = 'b'; 4675 else 4676 *t++ = *s; 4677 s++; 4678 } 4679 else if(*s == 'p'){ 4680 *t++ = 'x'; 4681 s++; 4682 } 4683 else 4684 *t++ = *s++; 4685 } 4686 else 4687 *t++ = *s++; 4688 } 4689 *t = '\0'; 4690 } 4691 4692 static void 4693 lpfmt(Rune *s) 4694 { 4695 Rune*t = s; 4696 4697 while(*s != '\0'){ 4698 if(*s == '%'){ 4699 *t++ = *s++; 4700 if(*s == 'l'){ 4701 s++; 4702 if(*s == 'l') 4703 *t++ = 'b'; 4704 else 4705 *t++ = *s; 4706 s++; 4707 } 4708 else if(*s == 'p'){ 4709 *t++ = 'x'; 4710 s++; 4711 } 4712 else 4713 *t++ = *s++; 4714 } 4715 else 4716 *t++ = *s++; 4717 } 4718 *t = '\0'; 4719 } 4720 4721 int 4722 line(Node *n) 4723 { 4724 if(n == Z) 4725 return 0; 4726 if(n->op == OLIST) 4727 return line(n->left); 4728 return n->lineno; 4729 } 4730 4731 static int 4732 lline(Node *n) 4733 { 4734 if(n == Z) 4735 return 0; 4736 if(n->op == OLIST) 4737 return lline(n->right); 4738 return n->lineno+1; 4739 } 4740 4741 static Node* 4742 lastn(Node *n) 4743 { 4744 while(n != Z && n->op == OLIST) 4745 n = n->right; 4746 return n; 4747 } 4748 4749 static Node* 4750 newnode(int op, Node *l) 4751 { 4752 Node *n; 4753 4754 n = new1(op, l, Z); 4755 globe->right = n; 4756 globe = n; 4757 return n; 4758 } 4759 4760 void 4761 codgen1(Node *n, Node *nn, int lastlno) 4762 { 4763 Node *nnn; 4764 4765 scomplex(n); 4766 nnn = newnode(OCODE, new1(OLIST, n, nn)); 4767 nnn->lineno = lastlno; 4768 mset(n); 4769 mset(nn); 4770 nn = func(nn); 4771 newnode(ODECF, nn); 4772 setmain(nn); 4773 } 4774 4775 void 4776 vtgen1(Node *n) 4777 { 4778 int c; 4779 Node *nn = n; 4780 4781 if(n->op == ODAS) 4782 nn = n->left; 4783 if(nn->type == T || nn->sym == S) 4784 return; 4785 c = nn->sym->class; 4786 if(c == CGLOBL || c == CSTATIC || c == CLOCAL || c == CEXREG){ 4787 newnode(ODECV, n); 4788 if(nn->type->etype != TFUNC || ism()) 4789 setmod(nn->sym); 4790 } 4791 mset(n); 4792 } 4793 4794 void 4795 etgen1(Sym *s) 4796 { 4797 Node *n; 4798 4799 n = newnode(ODECE, Z); 4800 n->sym = s; 4801 if(s != S) 4802 setmod(s); 4803 } 4804 4805 void 4806 ttgen1(Type *t) 4807 { 4808 Node *n; 4809 4810 n = newnode(ODECT, Z); 4811 n->type = t; 4812 if(isadt(t)) 4813 setmod(suename(t)); 4814 } 4815 4816 void 4817 outpush1(char *s) 4818 { 4819 Node *n; 4820 char *t; 4821 4822 n = newnode(OPUSH, Z); 4823 if(s == nil) 4824 t = nil; 4825 else{ 4826 t = malloc(strlen(s)+1); 4827 strcpy(t, s); 4828 } 4829 n->cstring = t; 4830 outpush0(s, n); 4831 } 4832 4833 void 4834 outpop1(int lno) 4835 { 4836 Node *n; 4837 4838 n = newnode(OPOP, Z); 4839 n->lineno = lno; 4840 outpop0(lno); 4841 } 4842 4843 void 4844 codgen(Node *n, Node *nn, int lastlno) 4845 { 4846 if(passes) 4847 codgen1(n, nn, lastlno); 4848 else 4849 codgen2(n, nn, lastlno, 1); 4850 } 4851 4852 void 4853 vtgen(Node *n) 4854 { 4855 if(passes) 4856 vtgen1(n); 4857 else 4858 vtgen2(n); 4859 } 4860 4861 void 4862 etgen(Sym *s) 4863 { 4864 if(passes) 4865 etgen1(s); 4866 else 4867 etgen2(s); 4868 } 4869 4870 void 4871 ttgen(Type *t) 4872 { 4873 if(passes) 4874 ttgen1(t); 4875 else 4876 ttgen2(t); 4877 } 4878 4879 void 4880 outpush(char *s) 4881 { 4882 if(passes) 4883 outpush1(s); 4884 else 4885 outpush2(s, Z); 4886 } 4887 4888 void 4889 outpop(int lno) 4890 { 4891 if(passes) 4892 outpop1(lno); 4893 else 4894 outpop2(lno); 4895 } 4896 4897 static void 4898 swalk(void) 4899 { 4900 Node *n, *l; 4901 4902 for(n = glob; n != Z; n = n->right){ 4903 l = n->left; 4904 switch(n->op){ 4905 case OCODE: 4906 rewall(l->left, l->right, n->lineno); 4907 break; 4908 default: 4909 break; 4910 } 4911 } 4912 while(again){ 4913 again = 0; 4914 for(n = glob; n != Z; n = n->right){ 4915 l = n->left; 4916 switch(n->op){ 4917 case OCODE: 4918 suball(l->left, l->right); 4919 break; 4920 case ODECV: 4921 subs(l, 0, 0); 4922 break; 4923 case ODECE: 4924 case ODECT: 4925 case ODECF: 4926 break; 4927 default: 4928 break; 4929 } 4930 } 4931 } 4932 for(n = glob; n != Z; n = n->right){ 4933 l = n->left; 4934 switch(n->op){ 4935 case ONOOP: 4936 break; 4937 case OPUSH: 4938 outpush2(n->cstring, n); 4939 break; 4940 case OPOP: 4941 outpop2(n->lineno); 4942 break; 4943 case OCODE: 4944 codgen2(l->left, l->right, n->lineno, 0); 4945 break; 4946 case ODECV: 4947 vtgen2(l); 4948 break; 4949 case ODECE: 4950 etgen2(n->sym); 4951 break; 4952 case ODECT: 4953 ttgen2(n->type); 4954 break; 4955 case ODECF: 4956 break; 4957 } 4958 } 4959 } 4960 4961 static void 4962 scomplex(Node *n) 4963 { 4964 if(n == Z) 4965 return; 4966 switch(n->op){ 4967 default: 4968 complex(n); 4969 break; 4970 case ODAS: 4971 case OSBREAK: 4972 case ONUL: 4973 case OLABEL: 4974 case OGOTO: 4975 case OCONTINUE: 4976 case OBREAK: 4977 break; 4978 case ONAME: 4979 if(n->kind == KEXP) 4980 complex(n); 4981 break; 4982 case OBLK: 4983 case OSET: 4984 case OUSED: 4985 scomplex(n->left); 4986 break; 4987 case OLIST: 4988 scomplex(n->left); 4989 scomplex(n->right); 4990 break; 4991 case ORETURN: 4992 complex(n); 4993 break; 4994 case OCASE: 4995 complex(n->left); 4996 break; 4997 case OSWITCH: 4998 case OWHILE: 4999 case ODWHILE: 5000 complex(n->left); 5001 scomplex(n->right); 5002 break; 5003 case OFOR: 5004 complex(n->left->left); 5005 complex(n->left->right->left); 5006 complex(n->left->right->right); 5007 scomplex(n->right); 5008 break; 5009 case OIF: 5010 complex(n->left); 5011 scomplex(n->right->left); 5012 scomplex(n->right->right); 5013 break; 5014 } 5015 } 5016 5017 static void 5018 mtset(Type *t) 5019 { 5020 if(t == T) 5021 return; 5022 switch(t->etype){ 5023 case TIND: 5024 case TARRAY: 5025 mtset(t->link); 5026 break; 5027 case TSTRUCT: 5028 case TUNION: 5029 prsym0(suename(t)); 5030 /* 5031 for(l = t->link; l != T; l = l->down) 5032 mtset(l); 5033 */ 5034 break; 5035 } 5036 } 5037 5038 static void 5039 mset(Node *n) 5040 { 5041 if(n == Z) 5042 return; 5043 n->garb = 0; 5044 if(n->op == ONAME) 5045 prsym0(n->sym); 5046 mtset(n->type); 5047 mset(n->left); 5048 mset(n->right); 5049 } 5050 5051 static int 5052 sign(Node *n) 5053 { 5054 int s; 5055 5056 if(n == Z) 5057 return 1; 5058 switch(n->op){ 5059 case OCONST: 5060 sign(n->left); 5061 if(n->vconst < 0){ 5062 n->vconst = -n->vconst; 5063 return -1; 5064 } 5065 break; 5066 case OPOS: 5067 s = sign(n->left); 5068 *n = *n->left; 5069 return s; 5070 case ONEG: 5071 s = sign(n->left); 5072 *n = *n->left; 5073 return -s; 5074 case OADD: 5075 if(sign(n->right) < 0) 5076 n->op = OSUB; 5077 break; 5078 case OSUB: 5079 if(sign(n->right) < 0) 5080 n->op = OADD; 5081 break; 5082 case OMUL: 5083 case ODIV: 5084 return sign(n->left)*sign(n->right); 5085 default: 5086 break; 5087 } 5088 return 1; 5089 } 5090 5091 static Node* 5092 ckneg(Node *n) 5093 { 5094 if(sign(n) < 0) 5095 return new1(ONEG, n, Z); 5096 return n; 5097 } 5098 5099 static void 5100 sliceasgn(Node *n) 5101 { 5102 Type *t; 5103 Node *nn; 5104 5105 if(side(n->left) || (n->right != Z && side(n->right))) 5106 return; 5107 t = n->type; 5108 if(isarray(t) && (!strings || t->link->etype != TCHAR)){ 5109 if(n->op == OASADD) 5110 nn = n->right; 5111 else 5112 nn = con(1); 5113 n->op = OAS; 5114 n->right = new1(OSLICE, ncopy(n->left), new1(OLIST, nn, Z)); 5115 } 5116 } 5117