1 #include "limbo.h" 2 3 static vlong 4 ipow(vlong x, int n) 5 { 6 int inv; 7 vlong r; 8 9 inv = 0; 10 if(n < 0){ 11 n = -n; 12 inv = 1; 13 } 14 r = 1; 15 for(;;){ 16 if(n&1) 17 r *= x; 18 if((n >>= 1) == 0) 19 break; 20 x *= x; 21 } 22 if(inv) 23 r = 1/r; 24 return r; 25 } 26 27 double 28 rpow(double x, int n) 29 { 30 int inv; 31 double r; 32 33 inv = 0; 34 if(n < 0){ 35 n = -n; 36 inv = 1; 37 } 38 r = 1; 39 for(;;){ 40 if(n&1) 41 r *= x; 42 if((n >>= 1) == 0) 43 break; 44 x *= x; 45 } 46 if(inv) 47 r = 1/r; 48 return r; 49 } 50 51 Long 52 real2fix(double v, Type *t) 53 { 54 v /= scale(t); 55 v = v < 0 ? v-0.5: v+0.5; 56 return v; 57 } 58 59 Long 60 fix2fix(Long v, Type *f, Type *t) 61 { 62 double r; 63 64 r = (double)v * (scale(f)/scale(t)); 65 r = r < 0 ? r-0.5: r+0.5; 66 return r; 67 } 68 69 double 70 fix2real(Long v, Type *f) 71 { 72 return (double)v * scale(f); 73 } 74 75 int 76 istuple(Node *n) 77 { 78 Decl *d; 79 80 switch(n->op){ 81 case Otuple: 82 return 1; 83 case Oname: 84 d = n->decl; 85 if(d->importid != nil) 86 d = d->importid; 87 return d->store == Dconst && (n->ty->kind == Ttuple || n->ty->kind == Tadt); 88 case Odot: 89 return 0; /* istuple(n->left); */ 90 } 91 return 0; 92 } 93 94 static Node* 95 tuplemem(Node *n, Decl *d) 96 { 97 Type *ty; 98 Decl *ids; 99 100 ty = n->ty; 101 n = n->left; 102 for(ids = ty->ids; ids != nil; ids = ids->next){ 103 if(ids->sym == d->sym) 104 break; 105 else 106 n = n->right; 107 } 108 if(n == nil) 109 fatal("tuplemem cannot cope !\n"); 110 return n->left; 111 } 112 113 int 114 varcom(Decl *v) 115 { 116 Node *n, tn; 117 118 n = v->init; 119 n = fold(n); 120 v->init = n; 121 if(debug['v']) 122 print("variable '%D' val %V\n", v, n); 123 if(n == nil) 124 return 1; 125 126 tn = znode; 127 tn.op = Oname; 128 tn.decl = v; 129 tn.src = v->src; 130 tn.ty = v->ty; 131 return initable(&tn, n, 0); 132 } 133 134 int 135 initable(Node *v, Node *n, int allocdep) 136 { 137 Node *e; 138 139 switch(n->ty->kind){ 140 case Tiface: 141 case Tgoto: 142 case Tcase: 143 case Tcasel: 144 case Tcasec: 145 case Talt: 146 case Texcept: 147 return 1; 148 case Tint: 149 case Tbig: 150 case Tbyte: 151 case Treal: 152 case Tstring: 153 case Tfix: 154 if(n->op != Oconst) 155 break; 156 return 1; 157 case Tadt: 158 case Tadtpick: 159 case Ttuple: 160 if(n->op == Otuple) 161 n = n->left; 162 else if(n->op == Ocall) 163 n = n->right; 164 else 165 break; 166 for(; n != nil; n = n->right) 167 if(!initable(v, n->left, allocdep)) 168 return 0; 169 return 1; 170 case Tarray: 171 if(n->op != Oarray) 172 break; 173 if(allocdep >= DADEPTH){ 174 nerror(v, "%Vs initializer has arrays nested more than %d deep", v, allocdep); 175 return 0; 176 } 177 allocdep++; 178 usedesc(mktdesc(n->ty->tof)); 179 if(n->left->op != Oconst){ 180 nerror(v, "%Vs size is not a constant", v); 181 return 0; 182 } 183 for(e = n->right; e != nil; e = e->right) 184 if(!initable(v, e->left->right, allocdep)) 185 return 0; 186 return 1; 187 case Tany: 188 return 1; 189 case Tref: 190 case Tlist: 191 case Tpoly: 192 default: 193 nerror(v, "can't initialize %Q", v); 194 return 0; 195 } 196 nerror(v, "%Vs initializer, %V, is not a constant expression", v, n); 197 return 0; 198 } 199 200 /* 201 * merge together two sorted lists, yielding a sorted list 202 */ 203 static Node* 204 elemmerge(Node *e, Node *f) 205 { 206 Node rock, *r; 207 208 r = &rock; 209 while(e != nil && f != nil){ 210 if(e->left->left->val <= f->left->left->val){ 211 r->right = e; 212 e = e->right; 213 }else{ 214 r->right = f; 215 f = f->right; 216 } 217 r = r->right; 218 } 219 if(e != nil) 220 r->right = e; 221 else 222 r->right = f; 223 return rock.right; 224 } 225 226 /* 227 * recursively split lists and remerge them after they are sorted 228 */ 229 static Node* 230 recelemsort(Node *e, int n) 231 { 232 Node *r, *ee; 233 int i, m; 234 235 if(n <= 1) 236 return e; 237 m = n / 2 - 1; 238 ee = e; 239 for(i = 0; i < m; i++) 240 ee = ee->right; 241 r = ee->right; 242 ee->right = nil; 243 return elemmerge(recelemsort(e, n / 2), 244 recelemsort(r, (n + 1) / 2)); 245 } 246 247 /* 248 * sort the elems by index; wild card is first 249 */ 250 Node* 251 elemsort(Node *e) 252 { 253 Node *ee; 254 int n; 255 256 n = 0; 257 for(ee = e; ee != nil; ee = ee->right){ 258 if(ee->left->left->op == Owild) 259 ee->left->left->val = -1; 260 n++; 261 } 262 return recelemsort(e, n); 263 } 264 265 int 266 sametree(Node *n1, Node *n2) 267 { 268 if(n1 == n2) 269 return 1; 270 if(n1 == nil || n2 == nil) 271 return 0; 272 if(n1->op != n2->op || n1->ty != n2->ty) 273 return 0; 274 if(n1->op == Oconst){ 275 switch(n1->ty->kind){ 276 case Tbig: 277 case Tbyte: 278 case Tint: 279 return n1->val == n2->val; 280 case Treal: 281 return n1->rval == n2->rval; 282 case Tfix: 283 return n1->val == n2->val && tequal(n1->ty, n2->ty); 284 case Tstring: 285 return n1->decl->sym == n2->decl->sym; 286 } 287 return 0; 288 } 289 return n1->decl == n2->decl && sametree(n1->left, n2->left) && sametree(n1->right, n2->right); 290 } 291 292 int 293 occurs(Decl *d, Node *n) 294 { 295 if(n == nil) 296 return 0; 297 if(n->op == Oname){ 298 if(d == n->decl) 299 return 1; 300 return 0; 301 } 302 return occurs(d, n->left) + occurs(d, n->right); 303 } 304 305 /* 306 * left and right subtrees the same 307 */ 308 Node* 309 folds(Node *n) 310 { 311 if(hasside(n, 1)) 312 return n; 313 switch(n->op){ 314 case Oeq: 315 case Oleq: 316 case Ogeq: 317 n->val = 1; 318 break; 319 case Osub: 320 n->val = 0; 321 n->rval = 0.0; 322 break; 323 case Oxor: 324 case Oneq: 325 case Olt: 326 case Ogt: 327 n->val = 0; 328 break; 329 case Oand: 330 case Oor: 331 case Oandand: 332 case Ooror: 333 return n->left; 334 default: 335 return n; 336 } 337 n->op = Oconst; 338 n->left = n->right = nil; 339 n->decl = nil; 340 return n; 341 } 342 343 /* 344 * constant folding for typechecked expressions, 345 */ 346 Node* 347 fold(Node *n) 348 { 349 if(n == nil) 350 return nil; 351 if(debug['F']) 352 print("fold %n\n", n); 353 n = efold(n); 354 if(debug['F']) 355 print("folded %n\n", n); 356 return n; 357 } 358 359 Node* 360 efold(Node *n) 361 { 362 Decl *d; 363 Node *left, *right; 364 365 if(n == nil) 366 return nil; 367 368 left = n->left; 369 right = n->right; 370 switch(n->op){ 371 case Oname: 372 d = n->decl; 373 if(d->importid != nil) 374 d = d->importid; 375 if(d->store != Dconst){ 376 if(d->store == Dtag){ 377 n->op = Oconst; 378 n->ty = tint; 379 n->val = d->tag; 380 } 381 break; 382 } 383 switch(n->ty->kind){ 384 case Tbig: 385 n->op = Oconst; 386 n->val = d->init->val; 387 break; 388 case Tbyte: 389 n->op = Oconst; 390 n->val = d->init->val & 0xff; 391 break; 392 case Tint: 393 case Tfix: 394 n->op = Oconst; 395 n->val = d->init->val; 396 break; 397 case Treal: 398 n->op = Oconst; 399 n->rval = d->init->rval; 400 break; 401 case Tstring: 402 n->op = Oconst; 403 n->decl = d->init->decl; 404 break; 405 case Ttuple: 406 *n = *d->init; 407 break; 408 case Tadt: 409 *n = *d->init; 410 n = rewrite(n); /* was call */ 411 break; 412 case Texception: 413 if(!n->ty->cons) 414 fatal("non-const exception type in efold"); 415 n->op = Oconst; 416 break; 417 default: 418 fatal("unknown const type %T in efold", n->ty); 419 break; 420 } 421 break; 422 case Oadd: 423 left = efold(left); 424 right = efold(right); 425 n->left = left; 426 n->right = right; 427 if(n->ty == tstring && right->op == Oconst){ 428 if(left->op == Oconst) 429 n = mksconst(&n->src, stringcat(left->decl->sym, right->decl->sym)); 430 else if(left->op == Oadd && left->ty == tstring && left->right->op == Oconst){ 431 left->right = mksconst(&n->src, stringcat(left->right->decl->sym, right->decl->sym)); 432 n = left; 433 } 434 } 435 break; 436 case Olen: 437 left = efold(left); 438 n->left = left; 439 if(left->ty == tstring && left->op == Oconst) 440 n = mkconst(&n->src, utflen(left->decl->sym->name)); 441 break; 442 case Oslice: 443 if(right->left->op == Onothing) 444 right->left = mkconst(&right->left->src, 0); 445 n->left = efold(left); 446 n->right = efold(right); 447 break; 448 case Oinds: 449 n->left = left = efold(left); 450 n->right = right = efold(right); 451 if(right->op == Oconst && left->op == Oconst){ 452 ; 453 } 454 break; 455 case Ocast: 456 n->op = Ocast; 457 left = efold(left); 458 n->left = left; 459 if(n->ty == left->ty || n->ty->kind == Tfix && tequal(n->ty, left->ty)) 460 return left; 461 if(left->op == Oconst) 462 return foldcast(n, left); 463 break; 464 case Odot: 465 case Omdot: 466 /* 467 * what about side effects from left? 468 */ 469 d = right->decl; 470 switch(d->store){ 471 case Dconst: 472 case Dtag: 473 case Dtype: 474 /* 475 * set it up as a name and let that case do the hard work 476 */ 477 n->op = Oname; 478 n->decl = d; 479 n->left = nil; 480 n->right = nil; 481 return efold(n); 482 } 483 n->left = efold(left); 484 if(n->left->op == Otuple) 485 n = tuplemem(n->left, d); 486 else 487 n->right = efold(right); 488 break; 489 case Otagof: 490 if(n->decl != nil){ 491 n->op = Oconst; 492 n->left = nil; 493 n->right = nil; 494 n->val = n->decl->tag; 495 return efold(n); 496 } 497 n->left = efold(left); 498 break; 499 case Oif: 500 n->left = left = efold(left); 501 n->right = right = efold(right); 502 if(left->op == Oconst){ 503 if(left->val) 504 return right->left; 505 else 506 return right->right; 507 } 508 break; 509 default: 510 n->left = efold(left); 511 n->right = efold(right); 512 break; 513 } 514 515 left = n->left; 516 right = n->right; 517 if(left == nil) 518 return n; 519 520 if(right == nil){ 521 if(left->op == Oconst){ 522 if(left->ty == tint || left->ty == tbyte || left->ty == tbig) 523 return foldc(n); 524 if(left->ty == treal) 525 return foldr(n); 526 } 527 return n; 528 } 529 530 if(left->op == Oconst){ 531 switch(n->op){ 532 case Olsh: 533 case Orsh: 534 if(left->val == 0 && !hasside(right, 1)) 535 return left; 536 break; 537 case Ooror: 538 if(left->ty == tint || left->ty == tbyte || left->ty == tbig){ 539 if(left->val == 0){ 540 n = mkbin(Oneq, right, mkconst(&right->src, 0)); 541 n->ty = right->ty; 542 n->left->ty = right->ty; 543 return efold(n); 544 } 545 left->val = 1; 546 return left; 547 } 548 break; 549 case Oandand: 550 if(left->ty == tint || left->ty == tbyte || left->ty == tbig){ 551 if(left->val == 0) 552 return left; 553 n = mkbin(Oneq, right, mkconst(&right->src, 0)); 554 n->ty = right->ty; 555 n->left->ty = right->ty; 556 return efold(n); 557 } 558 break; 559 } 560 } 561 if(left->op == Oconst && right->op != Oconst 562 && opcommute[n->op] 563 && n->ty != tstring){ 564 n->op = opcommute[n->op]; 565 n->left = right; 566 n->right = left; 567 left = right; 568 right = n->right; 569 } 570 if(right->op == Oconst && left->op == n->op && left->right->op == Oconst 571 && (n->op == Oadd || n->op == Omul || n->op == Oor || n->op == Oxor || n->op == Oand) 572 && n->ty != tstring){ 573 n->left = left->left; 574 left->left = right; 575 right = efold(left); 576 n->right = right; 577 left = n->left; 578 } 579 if(right->op == Oconst){ 580 if(n->op == Oexp && left->ty == treal){ 581 if(left->op == Oconst) 582 return foldr(n); 583 return n; 584 } 585 if(right->ty == tint || right->ty == tbyte || left->ty == tbig){ 586 if(left->op == Oconst) 587 return foldc(n); 588 return foldvc(n); 589 } 590 if(right->ty == treal && left->op == Oconst) 591 return foldr(n); 592 } 593 if(sametree(left, right)) 594 return folds(n); 595 return n; 596 } 597 598 /* 599 * does evaluating the node have any side effects? 600 */ 601 int 602 hasside(Node *n, int strict) 603 { 604 for(; n != nil; n = n->right){ 605 if(sideeffect[n->op] && (strict || n->op != Oadr && n->op != Oind)) 606 return 1; 607 if(hasside(n->left, strict)) 608 return 1; 609 } 610 return 0; 611 } 612 613 int 614 hascall(Node *n) 615 { 616 for(; n != nil; n = n->right){ 617 if(n->op == Ocall || n->op == Ospawn) 618 return 1; 619 if(hascall(n->left)) 620 return 1; 621 } 622 return 0; 623 } 624 625 int 626 hasasgns(Node *n) 627 { 628 if(n == nil) 629 return 0; 630 if(n->op != Ocall && isused[n->op] && n->op != Onothing) 631 return 1; 632 return hasasgns(n->left) || hasasgns(n->right); 633 } 634 635 int 636 nodes(Node *n) 637 { 638 if(n == nil) 639 return 0; 640 return 1+nodes(n->left)+nodes(n->right); 641 } 642 643 Node* 644 foldcast(Node *n, Node *left) 645 { 646 Real r; 647 char *buf, *e; 648 649 switch(left->ty->kind){ 650 case Tint: 651 left->val &= 0xffffffff; 652 if(left->val & 0x80000000) 653 left->val |= (Long)0xffffffff << 32; 654 return foldcasti(n, left); 655 case Tbyte: 656 left->val &= 0xff; 657 return foldcasti(n, left); 658 case Tbig: 659 return foldcasti(n, left); 660 case Treal: 661 switch(n->ty->kind){ 662 case Tint: 663 case Tbyte: 664 case Tbig: 665 r = left->rval; 666 left->val = r < 0 ? r - .5 : r + .5; 667 break; 668 case Tfix: 669 left->val = real2fix(left->rval, n->ty); 670 break; 671 case Tstring: 672 buf = allocmem(NumSize); 673 e = seprint(buf, buf+NumSize, "%g", left->rval); 674 return mksconst(&n->src, enterstring(buf, e-buf)); 675 default: 676 return n; 677 } 678 break; 679 case Tfix: 680 switch(n->ty->kind){ 681 case Tint: 682 case Tbyte: 683 case Tbig: 684 left->val = fix2real(left->val, left->ty); 685 break; 686 case Treal: 687 left->rval = fix2real(left->val, left->ty); 688 break; 689 case Tfix: 690 if(tequal(left->ty, n->ty)) 691 return left; 692 left->val = fix2fix(left->val, left->ty, n->ty); 693 break; 694 case Tstring: 695 buf = allocmem(NumSize); 696 e = seprint(buf, buf+NumSize, "%g", fix2real(left->val, left->ty)); 697 return mksconst(&n->src, enterstring(buf, e-buf)); 698 default: 699 return n; 700 } 701 break; 702 case Tstring: 703 switch(n->ty->kind){ 704 case Tint: 705 case Tbyte: 706 case Tbig: 707 left->val = strtoi(left->decl->sym->name, 10); 708 break; 709 case Treal: 710 left->rval = strtod(left->decl->sym->name, nil); 711 break; 712 case Tfix: 713 left->val = real2fix(strtod(left->decl->sym->name, nil), n->ty); 714 break; 715 default: 716 return n; 717 } 718 break; 719 default: 720 return n; 721 } 722 left->ty = n->ty; 723 left->src = n->src; 724 return left; 725 } 726 727 /* 728 * left is some kind of int type 729 */ 730 Node* 731 foldcasti(Node *n, Node *left) 732 { 733 char *buf, *e; 734 735 switch(n->ty->kind){ 736 case Tint: 737 left->val &= 0xffffffff; 738 if(left->val & 0x80000000) 739 left->val |= (Long)0xffffffff << 32; 740 break; 741 case Tbyte: 742 left->val &= 0xff; 743 break; 744 case Tbig: 745 break; 746 case Treal: 747 left->rval = left->val; 748 break; 749 case Tfix: 750 left->val = real2fix(left->val, n->ty); 751 break; 752 case Tstring: 753 buf = allocmem(NumSize); 754 e = seprint(buf, buf+NumSize, "%lld", left->val); 755 return mksconst(&n->src, enterstring(buf, e-buf)); 756 default: 757 return n; 758 } 759 left->ty = n->ty; 760 left->src = n->src; 761 return left; 762 } 763 764 /* 765 * right is a const int 766 */ 767 Node* 768 foldvc(Node *n) 769 { 770 Node *left, *right; 771 772 left = n->left; 773 right = n->right; 774 switch(n->op){ 775 case Oadd: 776 case Osub: 777 case Oor: 778 case Oxor: 779 case Olsh: 780 case Orsh: 781 case Ooror: 782 if(right->val == 0) 783 return left; 784 if(n->op == Ooror && !hasside(left, 1)) 785 return right; 786 break; 787 case Oand: 788 if(right->val == 0 && !hasside(left, 1)) 789 return right; 790 break; 791 case Omul: 792 if(right->val == 1) 793 return left; 794 if(right->val == 0 && !hasside(left, 1)) 795 return right; 796 break; 797 case Odiv: 798 if(right->val == 1) 799 return left; 800 break; 801 case Omod: 802 if(right->val == 1 && !hasside(left, 1)){ 803 right->val = 0; 804 return right; 805 } 806 break; 807 case Oexp: 808 if(right->val == 0){ 809 right->val = 1; 810 return right; 811 } 812 if(right->val == 1) 813 return left; 814 break; 815 case Oandand: 816 if(right->val != 0) 817 return left; 818 if(!hasside(left, 1)) 819 return right; 820 break; 821 case Oneq: 822 if(!isrelop[left->op]) 823 return n; 824 if(right->val == 0) 825 return left; 826 n->op = Onot; 827 n->right = nil; 828 break; 829 case Oeq: 830 if(!isrelop[left->op]) 831 return n; 832 if(right->val != 0) 833 return left; 834 n->op = Onot; 835 n->right = nil; 836 break; 837 } 838 return n; 839 } 840 841 /* 842 * left and right are const ints 843 */ 844 Node* 845 foldc(Node *n) 846 { 847 Node *left, *right; 848 Long lv, v; 849 int rv, nb; 850 851 left = n->left; 852 right = n->right; 853 switch(n->op){ 854 case Oadd: 855 v = left->val + right->val; 856 break; 857 case Osub: 858 v = left->val - right->val; 859 break; 860 case Omul: 861 v = left->val * right->val; 862 break; 863 case Odiv: 864 if(right->val == 0){ 865 nerror(n, "divide by 0 in constant expression"); 866 return n; 867 } 868 v = left->val / right->val; 869 break; 870 case Omod: 871 if(right->val == 0){ 872 nerror(n, "mod by 0 in constant expression"); 873 return n; 874 } 875 v = left->val % right->val; 876 break; 877 case Oexp: 878 if(left->val == 0 && right->val < 0){ 879 nerror(n, "0 to negative power in constant expression"); 880 return n; 881 } 882 v = ipow(left->val, right->val); 883 break; 884 case Oand: 885 v = left->val & right->val; 886 break; 887 case Oor: 888 v = left->val | right->val; 889 break; 890 case Oxor: 891 v = left->val ^ right->val; 892 break; 893 case Olsh: 894 lv = left->val; 895 rv = right->val; 896 if(rv < 0 || rv >= n->ty->size * 8){ 897 nwarn(n, "shift amount %d out of range", rv); 898 rv = 0; 899 } 900 if(rv == 0){ 901 v = lv; 902 break; 903 } 904 v = lv << rv; 905 break; 906 case Orsh: 907 lv = left->val; 908 rv = right->val; 909 nb = n->ty->size * 8; 910 if(rv < 0 || rv >= nb){ 911 nwarn(n, "shift amount %d out of range", rv); 912 rv = 0; 913 } 914 if(rv == 0){ 915 v = lv; 916 break; 917 } 918 v = lv >> rv; 919 920 /* 921 * properly sign extend c right shifts 922 */ 923 if((n->ty == tint || n->ty == tbig) 924 && rv != 0 925 && (lv & (1<<(nb-1)))){ 926 lv = 0; 927 lv = ~lv; 928 v |= lv << (nb - rv); 929 } 930 break; 931 case Oneg: 932 v = -left->val; 933 break; 934 case Ocomp: 935 v = ~left->val; 936 break; 937 case Oeq: 938 v = left->val == right->val; 939 break; 940 case Oneq: 941 v = left->val != right->val; 942 break; 943 case Ogt: 944 v = left->val > right->val; 945 break; 946 case Ogeq: 947 v = left->val >= right->val; 948 break; 949 case Olt: 950 v = left->val < right->val; 951 break; 952 case Oleq: 953 v = left->val <= right->val; 954 break; 955 case Oandand: 956 v = left->val && right->val; 957 break; 958 case Ooror: 959 v = left->val || right->val; 960 break; 961 case Onot: 962 v = !left->val; 963 break; 964 default: 965 return n; 966 } 967 if(n->ty == tint){ 968 v &= 0xffffffff; 969 if(v & 0x80000000) 970 v |= (Long)0xffffffff << 32; 971 }else if(n->ty == tbyte) 972 v &= 0xff; 973 n->left = nil; 974 n->right = nil; 975 n->decl = nil; 976 n->op = Oconst; 977 n->val = v; 978 return n; 979 } 980 981 /* 982 * left and right are const reals 983 */ 984 Node* 985 foldr(Node *n) 986 { 987 Node *left, *right; 988 double rv; 989 Long v; 990 991 rv = 0.; 992 v = 0; 993 994 left = n->left; 995 right = n->right; 996 switch(n->op){ 997 case Ocast: 998 return n; 999 case Oadd: 1000 rv = left->rval + right->rval; 1001 break; 1002 case Osub: 1003 rv = left->rval - right->rval; 1004 break; 1005 case Omul: 1006 rv = left->rval * right->rval; 1007 break; 1008 case Odiv: 1009 rv = left->rval / right->rval; 1010 break; 1011 case Oexp: 1012 rv = rpow(left->rval, right->val); 1013 break; 1014 case Oneg: 1015 rv = -left->rval; 1016 break; 1017 case Oinv: 1018 if(left->rval == 0.0){ 1019 error(n->src.start, "divide by 0 in fixed point type"); 1020 return n; 1021 } 1022 rv = 1/left->rval; 1023 break; 1024 case Oeq: 1025 v = left->rval == right->rval; 1026 break; 1027 case Oneq: 1028 v = left->rval != right->rval; 1029 break; 1030 case Ogt: 1031 v = left->rval > right->rval; 1032 break; 1033 case Ogeq: 1034 v = left->rval >= right->rval; 1035 break; 1036 case Olt: 1037 v = left->rval < right->rval; 1038 break; 1039 case Oleq: 1040 v = left->rval <= right->rval; 1041 break; 1042 default: 1043 return n; 1044 } 1045 n->left = nil; 1046 n->right = nil; 1047 1048 if(isNaN(rv)) 1049 rv = canonnan; 1050 1051 n->rval = rv; 1052 n->val = v; 1053 1054 n->op = Oconst; 1055 return n; 1056 } 1057 1058 Node* 1059 varinit(Decl *d, Node *e) 1060 { 1061 Node *n; 1062 1063 n = mkdeclname(&e->src, d); 1064 if(d->next == nil) 1065 return mkbin(Oas, n, e); 1066 return mkbin(Oas, n, varinit(d->next, e)); 1067 } 1068 1069 /* 1070 * given: an Oseq list with left == next or the last child 1071 * make a list with the right == next 1072 * ie: Oseq(Oseq(a, b),c) ==> Oseq(a, Oseq(b, Oseq(c, nil)))) 1073 */ 1074 Node* 1075 rotater(Node *e) 1076 { 1077 Node *left; 1078 1079 if(e == nil) 1080 return e; 1081 if(e->op != Oseq) 1082 return mkunary(Oseq, e); 1083 e->right = mkunary(Oseq, e->right); 1084 while(e->left->op == Oseq){ 1085 left = e->left; 1086 e->left = left->right; 1087 left->right = e; 1088 e = left; 1089 } 1090 return e; 1091 } 1092 1093 /* 1094 * reverse the case labels list 1095 */ 1096 Node* 1097 caselist(Node *s, Node *nr) 1098 { 1099 Node *r; 1100 1101 r = s->right; 1102 s->right = nr; 1103 if(r == nil) 1104 return s; 1105 return caselist(r, s); 1106 } 1107 1108 /* 1109 * e is a seq of expressions; make into cons's to build a list 1110 */ 1111 Node* 1112 etolist(Node *e) 1113 { 1114 Node *left, *n; 1115 1116 if(e == nil) 1117 return nil; 1118 n = mknil(&e->src); 1119 n->src.start = n->src.stop; 1120 if(e->op != Oseq) 1121 return mkbin(Ocons, e, n); 1122 e->right = mkbin(Ocons, e->right, n); 1123 while(e->left->op == Oseq){ 1124 e->op = Ocons; 1125 left = e->left; 1126 e->left = left->right; 1127 left->right = e; 1128 e = left; 1129 } 1130 e->op = Ocons; 1131 return e; 1132 } 1133 1134 Node* 1135 dupn(int resrc, Src *src, Node *n) 1136 { 1137 Node *nn; 1138 1139 nn = allocmem(sizeof *nn); 1140 *nn = *n; 1141 if(resrc) 1142 nn->src = *src; 1143 if(nn->left != nil) 1144 nn->left = dupn(resrc, src, nn->left); 1145 if(nn->right != nil) 1146 nn->right = dupn(resrc, src, nn->right); 1147 return nn; 1148 } 1149 1150 Node* 1151 mkn(int op, Node *left, Node *right) 1152 { 1153 Node *n; 1154 1155 n = allocmem(sizeof *n); 1156 *n = znode; 1157 n->op = op; 1158 n->left = left; 1159 n->right = right; 1160 return n; 1161 } 1162 1163 Node* 1164 mkunary(int op, Node *left) 1165 { 1166 Node *n; 1167 1168 n = mkn(op, left, nil); 1169 n->src = left->src; 1170 return n; 1171 } 1172 1173 Node* 1174 mkbin(int op, Node *left, Node *right) 1175 { 1176 Node *n; 1177 1178 n = mkn(op, left, right); 1179 n->src.start = left->src.start; 1180 n->src.stop = right->src.stop; 1181 return n; 1182 } 1183 1184 Node* 1185 mkdeclname(Src *src, Decl *d) 1186 { 1187 Node *n; 1188 1189 n = mkn(Oname, nil, nil); 1190 n->src = *src; 1191 n->decl = d; 1192 n->ty = d->ty; 1193 d->refs++; 1194 return n; 1195 } 1196 1197 Node* 1198 mknil(Src *src) 1199 { 1200 return mkdeclname(src, nildecl); 1201 } 1202 1203 Node* 1204 mkname(Src *src, Sym *s) 1205 { 1206 Node *n; 1207 1208 n = mkn(Oname, nil, nil); 1209 n->src = *src; 1210 if(s->unbound == nil){ 1211 s->unbound = mkdecl(src, Dunbound, nil); 1212 s->unbound->sym = s; 1213 } 1214 n->decl = s->unbound; 1215 return n; 1216 } 1217 1218 Node* 1219 mkconst(Src *src, Long v) 1220 { 1221 Node *n; 1222 1223 n = mkn(Oconst, nil, nil); 1224 n->ty = tint; 1225 n->val = v; 1226 n->src = *src; 1227 return n; 1228 } 1229 1230 Node* 1231 mkrconst(Src *src, Real v) 1232 { 1233 Node *n; 1234 1235 n = mkn(Oconst, nil, nil); 1236 n->ty = treal; 1237 n->rval = v; 1238 n->src = *src; 1239 return n; 1240 } 1241 1242 Node* 1243 mksconst(Src *src, Sym *s) 1244 { 1245 Node *n; 1246 1247 n = mkn(Oconst, nil, nil); 1248 n->ty = tstring; 1249 n->decl = mkdecl(src, Dconst, tstring); 1250 n->decl->sym = s; 1251 n->src = *src; 1252 return n; 1253 } 1254 1255 int 1256 opconv(Fmt *f) 1257 { 1258 int op; 1259 char buf[32]; 1260 1261 op = va_arg(f->args, int); 1262 if(op < 0 || op > Oend) { 1263 seprint(buf, buf+sizeof(buf), "op %d", op); 1264 return fmtstrcpy(f, buf); 1265 } 1266 return fmtstrcpy(f, opname[op]); 1267 } 1268 1269 int 1270 etconv(Fmt *f) 1271 { 1272 Node *n; 1273 char buf[1024]; 1274 1275 n = va_arg(f->args, Node*); 1276 if(n->ty == tany || n->ty == tnone || n->ty == terror) 1277 seprint(buf, buf+sizeof(buf), "%V", n); 1278 else 1279 seprint(buf, buf+sizeof(buf), "%V of type %T", n, n->ty); 1280 return fmtstrcpy(f, buf); 1281 } 1282 1283 int 1284 expconv(Fmt *f) 1285 { 1286 Node *n; 1287 char buf[4096], *p; 1288 1289 n = va_arg(f->args, Node*); 1290 p = buf; 1291 *p = 0; 1292 if(f->r == 'V') 1293 *p++ = '\''; 1294 p = eprint(p, buf+sizeof(buf)-1, n); 1295 if(f->r == 'V') 1296 *p++ = '\''; 1297 *p = 0; 1298 return fmtstrcpy(f, buf); 1299 } 1300 1301 char* 1302 eprint(char *buf, char *end, Node *n) 1303 { 1304 if(n == nil) 1305 return buf; 1306 if(n->flags & PARENS) 1307 buf = secpy(buf, end, "("); 1308 switch(n->op){ 1309 case Obreak: 1310 case Ocont: 1311 buf = secpy(buf, end, opname[n->op]); 1312 if(n->decl != nil){ 1313 buf = seprint(buf, end, " %s", n->decl->sym->name); 1314 } 1315 break; 1316 case Oexit: 1317 case Owild: 1318 buf = secpy(buf, end, opname[n->op]); 1319 break; 1320 case Onothing: 1321 break; 1322 case Oadr: 1323 case Oused: 1324 buf = eprint(buf, end, n->left); 1325 break; 1326 case Oseq: 1327 buf = eprintlist(buf, end, n, ", "); 1328 break; 1329 case Oname: 1330 if(n->decl == nil) 1331 buf = secpy(buf, end, "<nil>"); 1332 else 1333 buf = seprint(buf, end, "%s", n->decl->sym->name); 1334 break; 1335 case Oconst: 1336 if(n->ty->kind == Tstring){ 1337 buf = stringpr(buf, end, n->decl->sym); 1338 break; 1339 } 1340 if(n->decl != nil && n->decl->sym != nil){ 1341 buf = seprint(buf, end, "%s", n->decl->sym->name); 1342 break; 1343 } 1344 switch(n->ty->kind){ 1345 case Tint: 1346 case Tbyte: 1347 buf = seprint(buf, end, "%ld", (long)n->val); 1348 break; 1349 case Tbig: 1350 buf = seprint(buf, end, "%lld", n->val); 1351 break; 1352 case Treal: 1353 buf = seprint(buf, end, "%g", n->rval); 1354 break; 1355 case Tfix: 1356 buf = seprint(buf, end, "%ld(%g)", (long)n->val, n->ty->val->rval); 1357 break; 1358 default: 1359 buf = secpy(buf, end, opname[n->op]); 1360 break; 1361 } 1362 break; 1363 case Ocast: 1364 buf = seprint(buf, end, "%T ", n->ty); 1365 buf = eprint(buf, end, n->left); 1366 break; 1367 case Otuple: 1368 if(n->ty != nil && n->ty->kind == Tadt) 1369 buf = seprint(buf, end, "%s", n->ty->decl->sym->name); 1370 buf = seprint(buf, end, "("); 1371 buf = eprintlist(buf, end, n->left, ", "); 1372 buf = secpy(buf, end, ")"); 1373 break; 1374 case Ochan: 1375 if(n->left){ 1376 buf = secpy(buf, end, "chan ["); 1377 buf = eprint(buf, end, n->left); 1378 buf = secpy(buf, end, "] of "); 1379 buf = seprint(buf, end, "%T", n->ty->tof); 1380 }else 1381 buf = seprint(buf, end, "chan of %T", n->ty->tof); 1382 break; 1383 case Oarray: 1384 buf = secpy(buf, end, "array ["); 1385 if(n->left != nil) 1386 buf = eprint(buf, end, n->left); 1387 buf = secpy(buf, end, "] of "); 1388 if(n->right != nil){ 1389 buf = secpy(buf, end, "{"); 1390 buf = eprintlist(buf, end, n->right, ", "); 1391 buf = secpy(buf, end, "}"); 1392 }else{ 1393 buf = seprint(buf, end, "%T", n->ty->tof); 1394 } 1395 break; 1396 case Oelem: 1397 case Olabel: 1398 if(n->left != nil){ 1399 buf = eprintlist(buf, end, n->left, " or "); 1400 buf = secpy(buf, end, " =>"); 1401 } 1402 buf = eprint(buf, end, n->right); 1403 break; 1404 case Orange: 1405 buf = eprint(buf, end, n->left); 1406 buf = secpy(buf, end, " to "); 1407 buf = eprint(buf, end, n->right); 1408 break; 1409 case Ospawn: 1410 buf = secpy(buf, end, "spawn "); 1411 buf = eprint(buf, end, n->left); 1412 break; 1413 case Oraise: 1414 buf = secpy(buf, end, "raise "); 1415 buf = eprint(buf, end, n->left); 1416 break; 1417 case Ocall: 1418 buf = eprint(buf, end, n->left); 1419 buf = secpy(buf, end, "("); 1420 buf = eprintlist(buf, end, n->right, ", "); 1421 buf = secpy(buf, end, ")"); 1422 break; 1423 case Oinc: 1424 case Odec: 1425 buf = eprint(buf, end, n->left); 1426 buf = secpy(buf, end, opname[n->op]); 1427 break; 1428 case Oindex: 1429 case Oindx: 1430 case Oinds: 1431 buf = eprint(buf, end, n->left); 1432 buf = secpy(buf, end, "["); 1433 buf = eprint(buf, end, n->right); 1434 buf = secpy(buf, end, "]"); 1435 break; 1436 case Oslice: 1437 buf = eprint(buf, end, n->left); 1438 buf = secpy(buf, end, "["); 1439 buf = eprint(buf, end, n->right->left); 1440 buf = secpy(buf, end, ":"); 1441 buf = eprint(buf, end, n->right->right); 1442 buf = secpy(buf, end, "]"); 1443 break; 1444 case Oload: 1445 buf = seprint(buf, end, "load %T ", n->ty); 1446 buf = eprint(buf, end, n->left); 1447 break; 1448 case Oref: 1449 case Olen: 1450 case Ohd: 1451 case Otl: 1452 case Otagof: 1453 buf = secpy(buf, end, opname[n->op]); 1454 buf = secpy(buf, end, " "); 1455 buf = eprint(buf, end, n->left); 1456 break; 1457 default: 1458 if(n->right == nil){ 1459 buf = secpy(buf, end, opname[n->op]); 1460 buf = eprint(buf, end, n->left); 1461 }else{ 1462 buf = eprint(buf, end, n->left); 1463 buf = secpy(buf, end, opname[n->op]); 1464 buf = eprint(buf, end, n->right); 1465 } 1466 break; 1467 } 1468 if(n->flags & PARENS) 1469 buf = secpy(buf, end, ")"); 1470 return buf; 1471 } 1472 1473 char* 1474 eprintlist(char *buf, char *end, Node *elist, char *sep) 1475 { 1476 if(elist == nil) 1477 return buf; 1478 for(; elist->right != nil; elist = elist->right){ 1479 if(elist->op == Onothing) 1480 continue; 1481 if(elist->left->op == Ofnptr) 1482 return buf; 1483 buf = eprint(buf, end, elist->left); 1484 if(elist->right->left->op != Ofnptr) 1485 buf = secpy(buf, end, sep); 1486 } 1487 buf = eprint(buf, end, elist->left); 1488 return buf; 1489 } 1490 1491 int 1492 nodeconv(Fmt *f) 1493 { 1494 Node *n; 1495 char buf[4096]; 1496 1497 n = va_arg(f->args, Node*); 1498 buf[0] = 0; 1499 nprint(buf, buf+sizeof(buf), n, 0); 1500 return fmtstrcpy(f, buf); 1501 } 1502 1503 char* 1504 nprint(char *buf, char *end, Node *n, int indent) 1505 { 1506 int i; 1507 1508 if(n == nil) 1509 return buf; 1510 buf = seprint(buf, end, "\n"); 1511 for(i = 0; i < indent; i++) 1512 if(buf < end-1) 1513 *buf++ = ' '; 1514 switch(n->op){ 1515 case Oname: 1516 if(n->decl == nil) 1517 buf = secpy(buf, end, "name <nil>"); 1518 else 1519 buf = seprint(buf, end, "name %s", n->decl->sym->name); 1520 break; 1521 case Oconst: 1522 if(n->decl != nil && n->decl->sym != nil) 1523 buf = seprint(buf, end, "const %s", n->decl->sym->name); 1524 else 1525 buf = seprint(buf, end, "%O", n->op); 1526 if(n->ty == tint || n->ty == tbyte || n->ty == tbig) 1527 buf = seprint(buf, end, " (%ld)", (long)n->val); 1528 break; 1529 default: 1530 buf = seprint(buf, end, "%O", n->op); 1531 break; 1532 } 1533 buf = seprint(buf, end, " %T %d %d", n->ty, n->addable, n->temps); 1534 indent += 2; 1535 buf = nprint(buf, end, n->left, indent); 1536 buf = nprint(buf, end, n->right, indent); 1537 return buf; 1538 } 1539