|
|
1.1 ! root 1: #include "alloc.h" ! 2: #include <libc.h> ! 3: ! 4: char * ! 5: emalloc(unsigned long n) ! 6: { ! 7: char *p; ! 8: p=malloc((unsigned)n); ! 9: if(p==0){ ! 10: warn("out of memory; exiting"); ! 11: exits("out of memory"); ! 12: } ! 13: return p; ! 14: } ! 15: char * ! 16: erealloc(char *p, unsigned long n) ! 17: { ! 18: p=realloc(p, (unsigned)n); ! 19: if(p==0){ ! 20: warn("out of memory; exiting"); ! 21: exits("out of memory"); ! 22: } ! 23: return p; ! 24: } ! 25: #include "alloc.h" ! 26: #include "word.h" ! 27: #include "store.h" ! 28: #include "comm.h" ! 29: #include <libc.h> ! 30: ! 31: /* ! 32: * Push constants ! 33: */ ! 34: ! 35: ipushconst(Proc *proc) ! 36: { ! 37: *proc->sp++=(SWord)*++proc->pc; ! 38: return 1; ! 39: } ! 40: ! 41: ipush_2(Proc *proc) ! 42: { ! 43: *proc->sp++=-2; ! 44: return 1; ! 45: } ! 46: ! 47: ipush_1(Proc *proc) ! 48: { ! 49: *proc->sp++=-1; ! 50: return 1; ! 51: } ! 52: ! 53: ipush0(Proc *proc) ! 54: { ! 55: *proc->sp++=0; ! 56: return 1; ! 57: } ! 58: ! 59: ipush1(Proc *proc) ! 60: { ! 61: *proc->sp++=1; ! 62: return 1; ! 63: } ! 64: ! 65: ipush2(Proc *proc) ! 66: { ! 67: *proc->sp++=2; ! 68: return 1; ! 69: } ! 70: ! 71: ipush3(Proc *proc) ! 72: { ! 73: *proc->sp++=3; ! 74: return 1; ! 75: } ! 76: ! 77: ipush4(Proc *proc) ! 78: { ! 79: *proc->sp++=4; ! 80: return 1; ! 81: } ! 82: ! 83: ipush5(Proc *proc) ! 84: { ! 85: *proc->sp++=5; ! 86: return 1; ! 87: } ! 88: ! 89: ipush6(Proc *proc) ! 90: { ! 91: *proc->sp++=6; ! 92: return 1; ! 93: } ! 94: ! 95: ipush7(Proc *proc) ! 96: { ! 97: *proc->sp++=7; ! 98: return 1; ! 99: } ! 100: ! 101: ipush8(Proc *proc) ! 102: { ! 103: *proc->sp++=8; ! 104: return 1; ! 105: } ! 106: ! 107: ipush9(Proc *proc) ! 108: { ! 109: *proc->sp++=9; ! 110: return 1; ! 111: } ! 112: ! 113: ipush10(Proc *proc) ! 114: { ! 115: *proc->sp++=10; ! 116: return 1; ! 117: } ! 118: ! 119: /* ! 120: * Binary operators ! 121: */ ! 122: ige(Proc *proc) ! 123: { ! 124: --proc->sp; ! 125: proc->sp[-1]=proc->sp[-1]>=proc->sp[0]; ! 126: return 1; ! 127: } ! 128: ! 129: ile(Proc *proc) ! 130: { ! 131: --proc->sp; ! 132: proc->sp[-1]=proc->sp[-1]<=proc->sp[0]; ! 133: return 1; ! 134: } ! 135: ! 136: ine(Proc *proc) ! 137: { ! 138: --proc->sp; ! 139: proc->sp[-1]=proc->sp[-1]!=proc->sp[0]; ! 140: return 1; ! 141: } ! 142: ! 143: ieq(Proc *proc) ! 144: { ! 145: --proc->sp; ! 146: proc->sp[-1]=proc->sp[-1]==proc->sp[0]; ! 147: return 1; ! 148: } ! 149: ! 150: igt(Proc *proc) ! 151: { ! 152: --proc->sp; ! 153: proc->sp[-1]=proc->sp[-1]>proc->sp[0]; ! 154: return 1; ! 155: } ! 156: ! 157: ilt(Proc *proc) ! 158: { ! 159: --proc->sp; ! 160: proc->sp[-1]=proc->sp[-1]<proc->sp[0]; ! 161: return 1; ! 162: } ! 163: ! 164: iadd(Proc *proc) ! 165: { ! 166: --proc->sp; ! 167: proc->sp[-1]+=proc->sp[0]; ! 168: return 1; ! 169: } ! 170: ! 171: isub(Proc *proc) ! 172: { ! 173: --proc->sp; ! 174: proc->sp[-1]-=proc->sp[0]; ! 175: return 1; ! 176: } ! 177: ! 178: imul(Proc *proc) ! 179: { ! 180: long l0, l1, l; ! 181: --proc->sp; ! 182: l0=proc->sp[-1]; ! 183: l1=proc->sp[0]; ! 184: l=l0*l1; ! 185: if(l1 && l/l1 != l0) ! 186: rerror("product overflow"); ! 187: proc->sp[-1]=l; ! 188: return 1; ! 189: } ! 190: ! 191: idiv(Proc *proc) ! 192: { ! 193: --proc->sp; ! 194: if(proc->sp[0]==0) ! 195: rerror("zero divide"); ! 196: proc->sp[-1]/=proc->sp[0]; ! 197: return 1; ! 198: } ! 199: ! 200: imod(Proc *proc) ! 201: { ! 202: --proc->sp; ! 203: if(proc->sp[0]==0) ! 204: rerror("zero modulo"); ! 205: proc->sp[-1]%=proc->sp[0]; ! 206: return 1; ! 207: } ! 208: ! 209: iand(Proc *proc) ! 210: { ! 211: --proc->sp; ! 212: proc->sp[-1]&=proc->sp[0]; ! 213: return 1; ! 214: } ! 215: ! 216: ior(Proc *proc) ! 217: { ! 218: --proc->sp; ! 219: proc->sp[-1]|=proc->sp[0]; ! 220: return 1; ! 221: } ! 222: ! 223: ixor(Proc *proc) ! 224: { ! 225: --proc->sp; ! 226: proc->sp[-1]^=proc->sp[0]; ! 227: return 1; ! 228: } ! 229: ! 230: ilsh(Proc *proc) ! 231: { ! 232: --proc->sp; ! 233: proc->sp[-1]<<=proc->sp[0]; ! 234: return 1; ! 235: } ! 236: ! 237: irsh(Proc *proc) ! 238: { ! 239: --proc->sp; ! 240: proc->sp[-1]>>=proc->sp[0]; ! 241: return 1; ! 242: } ! 243: ! 244: imax(Proc *proc) ! 245: { ! 246: SWord l; ! 247: l=*--proc->sp; ! 248: if(l>proc->sp[-1]) ! 249: proc->sp[-1]=l; ! 250: return 1; ! 251: } ! 252: ! 253: /* ! 254: * Unary operators ! 255: */ ! 256: ! 257: ineg(Proc *proc) ! 258: { ! 259: proc->sp[-1]=-proc->sp[-1]; ! 260: return 1; ! 261: } ! 262: ! 263: inot(Proc *proc) ! 264: { ! 265: proc->sp[-1]=~proc->sp[-1]; ! 266: return 1; ! 267: } ! 268: ! 269: ilnot(Proc *proc) ! 270: { ! 271: proc->sp[-1]=!proc->sp[-1]; ! 272: return 1; ! 273: } ! 274: ! 275: iref(Proc *proc) ! 276: { ! 277: Store *s=(Store *)*--proc->sp; ! 278: *proc->sp++=s->ref-1; ! 279: decref(&s); ! 280: return 1; ! 281: } ! 282: ! 283: ilen(Proc *proc) ! 284: { ! 285: Store *s=(Store *)*--proc->sp; ! 286: *proc->sp++=s->len; ! 287: decref(&s); ! 288: return 1; ! 289: } ! 290: ! 291: /* ! 292: * String comparison: put value of strcmp() on stack ! 293: */ ! 294: ! 295: istrcmp(Proc *proc) ! 296: { ! 297: int cmp; ! 298: Store *s1, *s2; ! 299: s1=(Store *)proc->sp[-2]; ! 300: s2=(Store *)proc->sp[-1]; ! 301: cmp=strcmp((char *)s1->data, (char *)s2->data); ! 302: decref(&s1); ! 303: decref(&s2); ! 304: proc->sp--; ! 305: proc->sp[-1]=cmp; ! 306: return 1; ! 307: } ! 308: ! 309: /* ! 310: * Print ! 311: */ ! 312: ! 313: iprintint(Proc *proc) ! 314: { ! 315: pprint(proc, "%ld", *--proc->sp); ! 316: return 1; ! 317: } ! 318: ! 319: iprintnewline(Proc *proc) ! 320: { ! 321: pprint(proc, "\n"); ! 322: return 1; ! 323: } ! 324: ! 325: iprintblank(Proc *proc) ! 326: { ! 327: pprint(proc, " "); ! 328: return 1; ! 329: } ! 330: ! 331: iprintunit(Proc *proc) ! 332: { ! 333: pprint(proc, "(unit)"); ! 334: return 1; ! 335: } ! 336: ! 337: iprintchar(Proc *proc) ! 338: { ! 339: pprint(proc, "%c", *--proc->sp); ! 340: return 1; ! 341: } ! 342: ! 343: pprint(proc, fmt, a, b, c, d, e) ! 344: Proc *proc; ! 345: char *fmt; ! 346: { ! 347: char buf[1024]; ! 348: long n; ! 349: n=sprint(buf, fmt, a, b, c, d, e); ! 350: if(proc->prbuf==0){ ! 351: proc->prbuf=emalloc(64+n); ! 352: proc->maxprbuf=64+n; ! 353: proc->nprbuf=0; ! 354: } ! 355: if(n+proc->nprbuf+1>proc->maxprbuf){ ! 356: proc->prbuf=erealloc(proc->prbuf, proc->maxprbuf+64+n); ! 357: proc->maxprbuf+=64+n; ! 358: } ! 359: strcpy(proc->prbuf+proc->nprbuf, buf); ! 360: proc->nprbuf+=n; ! 361: } ! 362: /* ! 363: * Stack management ! 364: */ ! 365: ! 366: ipop(Proc *proc) ! 367: { ! 368: --proc->sp; ! 369: return 1; ! 370: } ! 371: ! 372: ipopptr(Proc *proc) ! 373: { ! 374: decref((Store **)(proc->sp-1)); ! 375: --proc->sp; ! 376: return 1; ! 377: } ! 378: ! 379: idup(Proc *proc) ! 380: { ! 381: proc->sp++; ! 382: proc->sp[-1]=proc->sp[-2]; ! 383: return 1; ! 384: } ! 385: ! 386: idupptr(Proc *proc) ! 387: { ! 388: proc->sp++; ! 389: proc->sp[-1]=proc->sp[-2]; ! 390: ((Store *)(proc->sp[-1]))->ref++; ! 391: return 1; ! 392: } ! 393: #include "node.h" ! 394: #include "symbol.h" ! 395: #include "alloc.h" ! 396: #include "word.h" ! 397: #include "store.h" ! 398: #include "comm.h" ! 399: #include "inst.h" ! 400: #include <libc.h> ! 401: ! 402: #define FNS ! 403: #include "lib.h" ! 404: #undef FNS ! 405: ! 406: #define C 0x40000000 ! 407: #define I 0x20000000 ! 408: #define F 0x10000000 ! 409: #define M(x) ((x)&~(C|I|F)) ! 410: ! 411: long call0[]={ /* plain function, 0 arguments */ ! 412: I+Ipushfp, C+0, F, I+Iret, C+0*WS, I+Idone, 0 ! 413: }; ! 414: long call1[]={ /* plain function, 1 argument */ ! 415: I+Ipushfp, C+0, F, I+Iret, C+1*WS, I+Idone, 0 ! 416: }; ! 417: long call2[]={ /* plain function, 2 arguments */ ! 418: I+Ipushfp, C+0, F, I+Iret, C+2*WS, I+Idone, 0 ! 419: }; ! 420: long call3[]={ /* plain function, 3 arguments */ ! 421: I+Ipushfp, C+0, F, I+Iret, C+3*WS, I+Idone, 0 ! 422: }; ! 423: long call4[]={ /* plain function, 4 arguments */ ! 424: I+Ipushfp, C+0, F, I+Iret, C+4*WS, I+Idone, 0 ! 425: }; ! 426: long call5[]={ /* plain function, 5 arguments */ ! 427: I+Ipushfp, C+0, F, I+Iret, C+5*WS, I+Idone, 0 ! 428: }; ! 429: long call2_0[]={/* two-step function, 0 arguments */ ! 430: I+Ipushfp, C+0, F+0, F+1, I+Iret, C+0*WS, I+Idone, 0 ! 431: }; ! 432: ! 433: struct{ ! 434: char *name; ! 435: int (*fn[3])(); ! 436: int nargs; ! 437: long *template; ! 438: }bltin[]={ ! 439: #include "lib.h" ! 440: 0, {0, 0, 0}, 0, 0, ! 441: }; ! 442: ! 443: bltinlookup(char *s) ! 444: { ! 445: int i; ! 446: for(i=0; bltin[i].name; i++) ! 447: if(strcmp(s, bltin[i].name)==0) ! 448: return i; ! 449: error("%s not a builtin", s); ! 450: return -1; ! 451: } ! 452: ! 453: long ! 454: bltinval(char *name, Node *t) ! 455: { ! 456: int i, nargs, len; ! 457: long *template, *p; ! 458: Store *s; ! 459: SWord *d; ! 460: if(t->o.t!=TProg) ! 461: error("builtin %s not a function", name); ! 462: i=bltinlookup(name); ! 463: nargs=bltin[i].nargs; ! 464: if(nargs!=length(t->l)) /* necessary but not sufficient */ ! 465: error("wrong #args to builtin %s: %d (should be %d)", name, length(t->l), nargs); ! 466: template=bltin[i].template; ! 467: p=template; ! 468: for(len=0; *p; p++) ! 469: len++; ! 470: s=(Store *)emalloc(SHSZ+len*LWS); ! 471: s->ref=1; ! 472: s->type=Sprog; ! 473: s->sbits=0; ! 474: s->len=len; ! 475: d=s->data; ! 476: for(p=template; *p; p++) ! 477: if(*p&C) ! 478: *d++=(SWord)M(*p); ! 479: else if(*p&I) ! 480: *d++=(SWord)insttab[M(*p)].fp; ! 481: else if(*p&F) ! 482: *d++=(SWord)bltin[i].fn[M(*p)]; ! 483: return (long)s; ! 484: } ! 485: ! 486: Store * ! 487: mk(type, len) ! 488: { ! 489: Store *s; ! 490: if(type==Sstruct) ! 491: len++; ! 492: s=(Store *)emalloc(SHSZ+len*LWS); ! 493: s->ref=1; ! 494: s->type=type; ! 495: if(type==Sstruct){ ! 496: s->sbits=1; ! 497: s->data[0]=0; ! 498: }else ! 499: s->sbits=0; ! 500: s->len=len; ! 501: return s; ! 502: } ! 503: #include "node.h" ! 504: #include "symbol.h" ! 505: #include "alloc.h" ! 506: #include "ydefs.h" ! 507: #include "word.h" ! 508: #include "store.h" ! 509: #include "comm.h" ! 510: #include "inst.h" ! 511: #include "errjmp.h" ! 512: #include <libc.h> ! 513: ! 514: long resultloc; ! 515: long returnloc; ! 516: Node *formals; ! 517: long autooffset; ! 518: extern int bflag; ! 519: extern int cflag; ! 520: extern int nscope; ! 521: extern Node arychartype; ! 522: ! 523: compile(n) /* called from parser only */ ! 524: Node *n; ! 525: { ! 526: extern long autooffset; ! 527: Errjmp x; ! 528: n=constants(n); ! 529: if(cflag){ ! 530: fileline(); ! 531: fprint(2, "constants:\n"); ! 532: dump(n, 0); ! 533: } ! 534: errsave(x); ! 535: if(errmark()){ ! 536: autooffset=0; ! 537: freenode(n); ! 538: errrest(x); ! 539: errjmp(); ! 540: } ! 541: istart(); ! 542: gen(n, 0); ! 543: freenode(n); ! 544: errrest(x); ! 545: } ! 546: ! 547: gen(Node *n, int retain) ! 548: { ! 549: int i; ! 550: if(n==0) ! 551: return; ! 552: switch(n->t){ ! 553: case NArrayref: ! 554: arygen(n->l, n->r, 0, 0L); ! 555: if(!retain) ! 556: popgen(n->l->o.s->val->type->r); ! 557: return; ! 558: case NBecome: ! 559: if(n->l->t==NCall && !bflag){ ! 560: callgen(n->l, Ibecome); ! 561: return; ! 562: } ! 563: gen(n->l, 1); ! 564: n=n->r; ! 565: if(n->o.t==TID) ! 566: n=typeoftid(n); ! 567: switch(n->o.t){ ! 568: case TInt: ! 569: case TChar: ! 570: emit(Istoreauto); ! 571: emitconst(-LWS*(3+length(formals))); ! 572: break; ! 573: case TArray: ! 574: case TChan: ! 575: case TProg: ! 576: case TStruct: ! 577: emit(Istoreptrauto); ! 578: emitconst(-LWS*(3+length(formals))); ! 579: break; ! 580: case TUnit: ! 581: break; ! 582: default: ! 583: panic("can't compile %t become", n->o.t); ! 584: } ! 585: scopedecrefgen(); ! 586: trlrgen(); ! 587: return; ! 588: case NBegin: ! 589: callgen(n->l, Ibegin); ! 590: return; ! 591: case NCall: ! 592: callgen(n, Icall); ! 593: if(!retain) ! 594: popgen(etypeoft(n->l)->r); ! 595: return; ! 596: case NDecl: ! 597: case NDeclsc: ! 598: declare(n, 0, 0, 1); ! 599: return; ! 600: case NExpr: ! 601: switch(n->o.i){ ! 602: case GE: ! 603: i=Ige; ! 604: Binop: ! 605: gen(n->l, 1); ! 606: gen(n->r, 1); ! 607: if(eqtype(etypeof(n->l), &arychartype)){ ! 608: emit(Istrcmp); ! 609: constgen(0L); ! 610: } ! 611: emit(i); ! 612: Popit: ! 613: if(!retain) ! 614: emit(Ipop); ! 615: return; ! 616: case LE: ! 617: i=Ile; ! 618: goto Binop; ! 619: case NE: ! 620: i=Ine; ! 621: goto Binop; ! 622: case EQ: ! 623: i=Ieq; ! 624: goto Binop; ! 625: case '>': ! 626: i=Igt; ! 627: goto Binop; ! 628: case '<': ! 629: i=Ilt; ! 630: goto Binop; ! 631: case '+': ! 632: i=Iadd; ! 633: goto Binop; ! 634: case '-': ! 635: i=Isub; ! 636: goto Binop; ! 637: case '*': ! 638: i=Imul; ! 639: goto Binop; ! 640: case '/': ! 641: i=Idiv; ! 642: goto Binop; ! 643: case '%': ! 644: i=Imod; ! 645: goto Binop; ! 646: case '&': ! 647: i=Iand; ! 648: goto Binop; ! 649: case '|': ! 650: i=Ior; ! 651: goto Binop; ! 652: case '^': ! 653: i=Ixor; ! 654: goto Binop; ! 655: case LSH: ! 656: i=Ilsh; ! 657: goto Binop; ! 658: case RSH: ! 659: i=Irsh; ! 660: goto Binop; ! 661: case ANDAND: ! 662: condgen(n->l, n->r, Ijmptrue, Ijmpfalse, 0L, 1L, retain); ! 663: return; ! 664: case OROR: ! 665: condgen(n->l, n->r, Ijmpfalse, Ijmptrue, 1L, 0L, retain); ! 666: return; ! 667: case PRINT: ! 668: gen(n->l, 1); ! 669: printgen(n->l); ! 670: emit(Isprint); ! 671: if(!retain) ! 672: emit(Iprint); ! 673: return; ! 674: case SND: ! 675: gen(n->l, 1); ! 676: constgen((long)Cissnd); ! 677: emit(Icommset1); ! 678: emit(Icommcln1); ! 679: gen(n->r, 1); ! 680: if(isptrtype(etypeoft(n->l)->r)) ! 681: emit(Isndptr); ! 682: else ! 683: emit(Isnd); ! 684: if(!retain) ! 685: popgen(etypeof(n)); ! 686: return; ! 687: case RCV: ! 688: gen(n->l, 1); ! 689: constgen(0L); /* not Cissnd */ ! 690: emit(Icommset1); ! 691: emit(Icommcln1); ! 692: return; ! 693: case '=': ! 694: gen(n->r, 1); ! 695: if(retain) ! 696: dupgen(etypeof(n->r), 1); ! 697: lgen(n->l); ! 698: return; ! 699: case LEN: ! 700: gen(n->l, 1); ! 701: emit(Ilen); ! 702: goto Popit; ! 703: case REF: ! 704: if(isptrtype(etypeof(n->l))){ ! 705: gen(n->l, 1); ! 706: emit(Iref); ! 707: }else ! 708: constgen(1L); ! 709: goto Popit; ! 710: case DEF: ! 711: if(retain && n->l->t==NID && isinttype(etypeof(n->l))){ ! 712: constgen(1L); ! 713: return; ! 714: } ! 715: /* ! 716: * don't really need to call lgen1, which will uniquify our ! 717: * array for us, but it does no harm, and it's easy. ! 718: */ ! 719: lgen1(n->l, Idefauto, Idef, Idefary); ! 720: goto Popit; ! 721: case UMINUS: ! 722: gen(n->l, 1); ! 723: emit(Ineg); ! 724: goto Popit; ! 725: case '~': ! 726: gen(n->l, 1); ! 727: emit(Inot); ! 728: goto Popit; ! 729: case '!': ! 730: gen(n->l, 1); ! 731: emit(Ilnot); ! 732: goto Popit; ! 733: case INC: ! 734: lgen1(n->l, Iincauto, Iinc, Iincary); ! 735: goto Popit; ! 736: case DEC: ! 737: lgen1(n->l, Idecauto, Idec, Idecary); ! 738: goto Popit; ! 739: default: ! 740: panic("can't compile %e expression", n->o.i); ! 741: } ! 742: ! 743: case NExprlist: ! 744: /* ! 745: * This is an arg or element list; first is pushed last ! 746: */ ! 747: gen(n->r, 1); ! 748: gen(n->l, 1); ! 749: return; ! 750: case NID: ! 751: if(!retain) ! 752: return; ! 753: switch(typeof(n)->o.t){ ! 754: case TInt: ! 755: case TChar: ! 756: if(n->o.s->val->isauto){ ! 757: emit(Ipushauto); ! 758: emitconst(n->o.s->val->store.off); ! 759: }else{ ! 760: emit(Ipush); ! 761: emitconst((long)&n->o.s->val->store.l); ! 762: } ! 763: return; ! 764: case TProg: ! 765: case TArray: ! 766: case TChan: ! 767: case TStruct: ! 768: if(n->o.s->val->isauto){ ! 769: emit(Ipushptrauto); ! 770: emitconst(n->o.s->val->store.off); ! 771: }else{ ! 772: emit(Ipushptr); ! 773: emitconst((long)&n->o.s->val->store.l); ! 774: } ! 775: return; ! 776: case TUnit: ! 777: if(retain) ! 778: constgen(0L); ! 779: return; ! 780: case TType: ! 781: lerror(n, "attempt to evaluate type variable %m", n); ! 782: default: ! 783: panic("can't compile type %t", n->o.s->val->type->o.t); ! 784: } ! 785: case NIf: ! 786: ifgen(n); ! 787: return; ! 788: case NList: ! 789: gen(n->l, 0); ! 790: gen(n->r, 0); ! 791: return; ! 792: case NLoop: ! 793: loopgen(n); ! 794: return; ! 795: case NMk: ! 796: mkgen(n->l, n->r); ! 797: return; ! 798: case NNum: ! 799: if(retain) ! 800: constgen(n->o.l); ! 801: return; ! 802: case NProg: ! 803: if(retain) ! 804: proggen(n->l, n->r); ! 805: return; ! 806: case NResult: ! 807: gen(n->l, 1); ! 808: emit(Ijmp); ! 809: emitconst((long)(resultloc-here()-1)*WS); ! 810: return; ! 811: case NScope: ! 812: pushscope(); ! 813: if(nscope==1){ ! 814: int nauto; ! 815: autooffset=0; ! 816: emit(Ipushfp); ! 817: nauto=here(); ! 818: emitconst(0L); ! 819: gen(n->l, 0); ! 820: patch((int)nauto, autooffset); ! 821: }else ! 822: gen(n->l, 0); ! 823: scopedecrefgen(); ! 824: popscope(); ! 825: return; ! 826: case NSelect: ! 827: selgen(n->l); ! 828: return; ! 829: case NSmash:{ ! 830: Value *vl, *vr; ! 831: vl=n->l->o.s->val; ! 832: vr=n->r->o.s->val; ! 833: if(vr->type->o.t==TType){ ! 834: freenode(vl->type); ! 835: vl->type=dupnode(vr->type); ! 836: return; ! 837: } ! 838: gen(n->r, 1); ! 839: /* ! 840: * Free old values; tricky: push as int, pop as ptr ! 841: */ ! 842: if(isptrtype(vl->type)){ ! 843: if(vl->isauto){ ! 844: emit(Ipushauto); ! 845: emitconst(vl->store.off); ! 846: }else{ ! 847: emit(Ipush); ! 848: emitconst((long)&vl->store.l); ! 849: } ! 850: emit(Ipopptr); ! 851: } ! 852: if(vl->isauto){ ! 853: emit(Istoreauto); ! 854: emitconst(vl->store.l); ! 855: return; ! 856: } ! 857: emit(Istore); ! 858: emitconst((long)&vl->store.l); ! 859: return; ! 860: } ! 861: case NString: ! 862: if(retain){ ! 863: Store *s; ! 864: s=(Store *)emalloc(SHSZ+strlen(n->o.c)+1); ! 865: strcpy((char *)(s->data), n->o.c); ! 866: s->ref=1; ! 867: s->len=strlen(n->o.c); ! 868: s->type=Sarychar; ! 869: emit(Ipushdata); ! 870: emitconst((long)s); ! 871: } ! 872: return; ! 873: case NStructref: ! 874: arygen(n->l, n->r, 1, n->o.l); ! 875: return; ! 876: case NSwitch: ! 877: switchgen(n->l, n->r); ! 878: return; ! 879: case NUnit: ! 880: if(retain) ! 881: constgen(0L); ! 882: return; ! 883: case NVal: ! 884: valgen(n->l); ! 885: if(!retain) ! 886: popgen(n->o.n); ! 887: return; ! 888: } ! 889: panic("can't compile node %n", n->t); ! 890: return; ! 891: } ! 892: ! 893: arygen(Node *a, Node *i, int isstr, long off) ! 894: { ! 895: int ptr, ischar; ! 896: if(isstr){ ! 897: ptr=isptrtype(i); ! 898: constgen(off); ! 899: ischar=0; ! 900: }else{ ! 901: Node *t=etypeoft(a)->r; ! 902: ptr=isptrtype(t); ! 903: gen(i, 1); ! 904: ischar=t->o.t==TChar; ! 905: } ! 906: if(a->t!=NID){ ! 907: gen(a, 1); ! 908: emit(ptr? Ipusharyptrexpr : ! 909: (ischar? Ipusharycharexpr :Ipusharyexpr)); ! 910: }else if(a->o.s->val->isauto){ ! 911: emit(ptr? Ipusharyptrauto : ! 912: (ischar? Ipusharycharauto :Ipusharyauto)); ! 913: emitconst(a->o.s->val->store.off); ! 914: }else{ ! 915: emit(ptr? Ipusharyptr : ! 916: (ischar? Ipusharychar :Ipushary)); ! 917: emitconst((long)&a->o.s->val->store.l); ! 918: } ! 919: } ! 920: ! 921: lgen(Node *n) ! 922: { ! 923: switch(n->t){ ! 924: case NID: ! 925: switch(typeof(n)->o.t){ ! 926: case TChar: ! 927: if(n->o.s->val->isauto){ ! 928: emit(Istorecharauto); ! 929: emitconst(n->o.s->val->store.off); ! 930: return; ! 931: } ! 932: emit(Istorechar); ! 933: emitconst((long)&n->o.s->val->store.l); ! 934: return; ! 935: case TInt: ! 936: case TUnit: ! 937: if(n->o.s->val->isauto){ ! 938: emit(Istoreauto); ! 939: emitconst(n->o.s->val->store.off); ! 940: return; ! 941: } ! 942: emit(Istore); ! 943: emitconst((long)&n->o.s->val->store.l); ! 944: return; ! 945: case TArray: ! 946: case TChan: ! 947: case TProg: ! 948: case TStruct: ! 949: if(n->o.s->val->isauto){ ! 950: emit(Istoreptrauto); ! 951: emitconst(n->o.s->val->store.off); ! 952: return; ! 953: } ! 954: emit(Istoreptr); ! 955: emitconst((long)&n->o.s->val->store.l); ! 956: return; ! 957: ! 958: default: ! 959: panic("lgen: ID type %t", n->o.s->val->type->o.t); ! 960: return; ! 961: } ! 962: case NArrayref: ! 963: gen(n->r, 1); ! 964: goto Genref; ! 965: case NStructref: ! 966: constgen(n->o.l); ! 967: Genref: ! 968: lgen1(n->l, Ipushuniqauto, Ipushuniq, Ipushuniqary); ! 969: emit(Istoreary); ! 970: return; ! 971: default: ! 972: panic("lgen: lvalue node %n", n->t); ! 973: } ! 974: } ! 975: ! 976: /* ! 977: * n is a compound object about to be assigned into ! 978: */ ! 979: lgen1(Node *n, int Iauto, int Ivar, int Iary) ! 980: { ! 981: switch(n->t){ ! 982: case NID: ! 983: if(n->o.s->val->isauto){ ! 984: emit(Iauto); ! 985: emitconst(n->o.s->val->store.off); ! 986: return; ! 987: } ! 988: emit(Ivar); ! 989: emitconst((long)&n->o.s->val->store.l); ! 990: return; ! 991: case NArrayref: ! 992: gen(n->r, 1); ! 993: goto Genref; ! 994: case NStructref: ! 995: constgen(n->o.l); ! 996: Genref: ! 997: lgen1(n->l, Ipushuniqauto, Ipushuniq, Ipushuniqary); ! 998: emit(Iary); ! 999: return; ! 1000: default: ! 1001: panic("lgen1: lvalue node %n", n->t); ! 1002: } ! 1003: } ! 1004: ! 1005: ifgen(Node *n) ! 1006: { ! 1007: int loc1, loc2; ! 1008: gen(n->o.n, 1); ! 1009: emit(Ijmpfalse); ! 1010: loc1=here(); ! 1011: emit(0); ! 1012: gen(n->l, 0); ! 1013: if(n->r==0){ ! 1014: patch(loc1, (long)(here()-loc1-1)*WS); ! 1015: return; ! 1016: } ! 1017: emit(Ijmp); ! 1018: loc2=here(); ! 1019: emit(0); ! 1020: patch(loc1, (long)(here()-loc1-1)*WS); ! 1021: gen(n->r, 0); ! 1022: patch(loc2, (long)(here()-loc2-1)*WS); ! 1023: return; ! 1024: } ! 1025: ! 1026: valgen(Node *n) ! 1027: { ! 1028: int loc1, loc2; ! 1029: int orl; ! 1030: emit(Ijmp); ! 1031: loc1=here(); ! 1032: emitconst(0L); ! 1033: orl=resultloc; ! 1034: resultloc=here(); ! 1035: emit(Ijmp); ! 1036: loc2=here(); ! 1037: emitconst(0L); ! 1038: patch(loc1, (long)(here()-loc1-1)*WS); ! 1039: gen(n, 1); ! 1040: emit(Ivalnoresult); ! 1041: patch(loc2, (long)(here()-loc2-1)*WS); ! 1042: resultloc=orl; ! 1043: } ! 1044: ! 1045: loopgen(Node *n) ! 1046: { ! 1047: int loc0, loc1, loc2; ! 1048: if(n->o.i){ /* enter loop at top, so jump to body */ ! 1049: emit(Ijmp); ! 1050: loc0=here(); ! 1051: emit(0); ! 1052: } ! 1053: gen(n->r->l, 0); /* left expr */ ! 1054: if(n->r->r){ /* jump to condition */ ! 1055: emit(Ijmp); ! 1056: loc1=here(); ! 1057: emit(0); ! 1058: } ! 1059: if(n->o.i) ! 1060: patch(loc0, (here()-loc0-1)*LWS); ! 1061: loc2=here(); ! 1062: gen(n->l, 0); /* body */ ! 1063: gen(n->r->o.n, 0); /* right expr */ ! 1064: if(n->r->r){ ! 1065: patch(loc1, (here()-loc1-1)*LWS); ! 1066: gen(n->r->r, 1); ! 1067: emit(Ijmptrue); ! 1068: }else ! 1069: emit(Ijmp); ! 1070: emitconst((loc2-here()-1)*LWS); ! 1071: } ! 1072: ! 1073: condgen(Node *l, Node *r, Inst i1, Inst i2, long t1, long t2, int retain) ! 1074: { ! 1075: int loc1, loc2, loc3; ! 1076: gen(l, 1); ! 1077: emit(i1); ! 1078: loc1=here(); ! 1079: emit(0); ! 1080: loc2=here(); ! 1081: if(retain) ! 1082: constgen(t1); ! 1083: emit(Ijmp); ! 1084: loc3=here(); ! 1085: emit(0); ! 1086: patch(loc1, (long)(here()-loc1-1)*WS); ! 1087: gen(r, 1); ! 1088: emit(i2); ! 1089: emitconst((long)(loc2-here()-1)*WS); ! 1090: if(retain) ! 1091: constgen(t2); ! 1092: patch(loc3, (long)(here()-loc3-1)*WS); ! 1093: } ! 1094: ! 1095: callgen(Node *n, int callinst) ! 1096: { ! 1097: Node *pt; ! 1098: pt=etypeof(n->l); ! 1099: /* ! 1100: * Space for result ! 1101: */ ! 1102: constgen(0L); ! 1103: /* ! 1104: * Args ! 1105: */ ! 1106: gen(n->r, 1); ! 1107: /* ! 1108: * Call ! 1109: */ ! 1110: emit(Ipushconst); ! 1111: if(n->l->t==NID) ! 1112: emitconst((long)n->l->o.s->name); ! 1113: else{ ! 1114: char buf[128]; ! 1115: char *p; ! 1116: sprint(buf, "prog(){call on line %d}", n->line); ! 1117: p=emalloc((unsigned long)strlen(buf)+1); ! 1118: strcpy(p, buf); ! 1119: emitconst((long)p); ! 1120: } ! 1121: gen(n->l, 1); ! 1122: switch(callinst){ ! 1123: case Icall: ! 1124: emit(Icall); ! 1125: return; ! 1126: case Ibegin: ! 1127: constgen(LWS*(1+1+length(pt->l))); /* result+procname+args */ ! 1128: emit(Ibegin); ! 1129: return; ! 1130: case Ibecome: ! 1131: constgen(LWS*(1+1+length(pt->l))); /* result+procname+args */ ! 1132: scopedecrefgen(); ! 1133: fdecrefgen(formals, -3L*WS); ! 1134: emit(Ibecome); ! 1135: if(formals) ! 1136: emitconst(length(formals)*LWS); ! 1137: else ! 1138: emitconst(0L); ! 1139: return; ! 1140: } ! 1141: panic("callgen"); ! 1142: } ! 1143: ! 1144: selgen(Node *n) ! 1145: { ! 1146: int tbl, i; ! 1147: long l; ! 1148: int ends[200]; ! 1149: selchangen(n); ! 1150: l=length(n); ! 1151: constgen(l); ! 1152: emit(Icommset); ! 1153: emit(Icommcln); ! 1154: if(l>(sizeof ends/sizeof ends[0])) ! 1155: panic("selgen table too small"); ! 1156: tbl=here(); ! 1157: emitspace(l); ! 1158: i=0; ! 1159: seltblgen(n, tbl, ends, &i); ! 1160: for(i=0; i<l; i++) ! 1161: patch(ends[i], (long)(here()-ends[i]-1)*WS); ! 1162: } ! 1163: ! 1164: selchangen(Node *n) ! 1165: { ! 1166: long flags; ! 1167: if(n->t==NList){ ! 1168: selchangen(n->l); ! 1169: selchangen(n->r); ! 1170: return; ! 1171: } ! 1172: if(n->t!=NCase) ! 1173: panic("selchangen"); ! 1174: n=n->l->l; ! 1175: if(n->o.t=='=') ! 1176: n=n->r; /* n is now RCV or SND */ ! 1177: flags=0; ! 1178: if(n->o.t==SND) ! 1179: flags|=Cissnd; ! 1180: n=n->l; /* n is now channel */ ! 1181: if(n->t==NArraycom){ ! 1182: flags|=Cisary; ! 1183: n=n->l; ! 1184: }else if(etypeoft(n)->o.t==TArray) ! 1185: flags|=Cisary; ! 1186: gen(n, 1); ! 1187: constgen(flags); ! 1188: } ! 1189: ! 1190: seltblgen(Node *n, int tbl, int *ends, int *ip) ! 1191: { ! 1192: Node *c, *s, *l, *t; ! 1193: if(n->t==NList){ ! 1194: /* chans are eval'ed from the top, so table is backwards */ ! 1195: seltblgen(n->r, tbl, ends, ip); ! 1196: seltblgen(n->l, tbl, ends, ip); ! 1197: return; ! 1198: } ! 1199: if(n->t!=NCase) ! 1200: panic("seltblgen"); ! 1201: if(n->l->t==NList) ! 1202: error("sorry, empty cases not implemented"); ! 1203: patch(tbl+*ip, (long)(here()-tbl)*WS); ! 1204: c=n->l->l; /* communication */ ! 1205: s=n->r; /* statement */ ! 1206: l=0; ! 1207: if(c->o.t=='='){ ! 1208: l=c->l; /* lvalue */ ! 1209: c=c->r; ! 1210: } ! 1211: if(c->o.t==SND){ ! 1212: gen(c->r, 1); ! 1213: if(isptrtype(etypeoft(c->l)->r)) ! 1214: emit(Isndptr); ! 1215: else ! 1216: emit(Isnd); ! 1217: } ! 1218: c=c->l; /* channel expression */ ! 1219: /* ! 1220: * The value is still on the stack; save it or toss it ! 1221: */ ! 1222: if(l) ! 1223: lgen(l); ! 1224: else if(c->t==NArraycom){ ! 1225: t=etypeoft(c->l)->r; ! 1226: if(t->o.t==TID) ! 1227: t=typeoftid(t); ! 1228: popgen(t->r); ! 1229: }else ! 1230: popgen(etypeoft(c)->r); ! 1231: if(c->t==NArraycom){ /* save array index */ ! 1232: if(c->r) ! 1233: lgen(c->r); ! 1234: else ! 1235: emit(Ipop); ! 1236: } ! 1237: gen(s, 0); ! 1238: emit(Ijmp); ! 1239: ends[*ip]=here(); ! 1240: (*ip)++; ! 1241: emitconst(0L); ! 1242: } ! 1243: ! 1244: switchgen(Node *s, Node *e) ! 1245: { ! 1246: int isptr, out; ! 1247: isptr=isptrtype(etypeof(e)); ! 1248: gen(e, 1); ! 1249: emit(Ijmp); ! 1250: emitconst(2*LWS); ! 1251: emit(Ijmp); /* each case jumps to here to get out */ ! 1252: out=here(); ! 1253: emitconst(0L); ! 1254: switchgen1(s, isptr, out-1); ! 1255: /* pop leftover value if no case matched */ ! 1256: if(isptr) ! 1257: emit(Ipopptr); ! 1258: else ! 1259: emit(Ipop); ! 1260: patch(out, (here()-out-1)*LWS); ! 1261: } ! 1262: ! 1263: switchgen1(Node *s, int isptr, int out) ! 1264: { ! 1265: Node *e; ! 1266: int loc; ! 1267: if(s->t==NList){ ! 1268: switchgen1(s->l, isptr, out); ! 1269: switchgen1(s->r, isptr, out); ! 1270: return; ! 1271: } ! 1272: if(s->t!=NCase) ! 1273: panic("switchgen1"); ! 1274: if(s->r==0) ! 1275: error("sorry; can't fold cases together yet"); ! 1276: if(s->l->t==NDefault) ! 1277: loc=-1; ! 1278: else{ ! 1279: e=s->l->l; ! 1280: if(isptr){ /* string */ ! 1281: emit(Idupptr); ! 1282: gen(e, 1); ! 1283: emit(Istrcmp); ! 1284: constgen(0L); ! 1285: }else{ ! 1286: emit(Idup); ! 1287: gen(e, 1); ! 1288: } ! 1289: emit(Ieq); ! 1290: emit(Ijmpfalse); ! 1291: loc=here(); ! 1292: emitconst(0L); ! 1293: } ! 1294: if(isptr) ! 1295: emit(Ipopptr); ! 1296: else ! 1297: emit(Ipop); ! 1298: gen(s->r, 0); ! 1299: emit(Ijmp); ! 1300: emitconst((out-here()-1)*LWS); ! 1301: if(loc!=-1) ! 1302: patch(loc, (here()-loc-1)*LWS); ! 1303: } ! 1304: ! 1305: popgen(Node *t) ! 1306: { ! 1307: if(isptrtype(t)) ! 1308: emit(Ipopptr); ! 1309: else if(isinttype(t) || t->o.t==TUnit) ! 1310: emit(Ipop); ! 1311: else ! 1312: panic("popgen %t\n", t->o.t); ! 1313: } ! 1314: ! 1315: genfreeauto(Symbol *s) ! 1316: { ! 1317: if(!s->val->isauto) ! 1318: panic("genfreeauto"); ! 1319: if(isptrtype(s->val->type)){ ! 1320: emit(Idecrefauto); ! 1321: emitconst(s->val->store.off); ! 1322: } ! 1323: } ! 1324: ! 1325: printgen(Node *n) ! 1326: { ! 1327: Node *t; ! 1328: if(n==0) ! 1329: return; ! 1330: if(n->t==NExprlist){ ! 1331: printgen(n->l); ! 1332: printgen(n->r); ! 1333: return; ! 1334: } ! 1335: t=etypeoft(n); ! 1336: switch(t->o.t){ ! 1337: case TArray: ! 1338: case TChan: ! 1339: case TProg: ! 1340: case TStruct: ! 1341: emit(Iprintary); ! 1342: break; ! 1343: case TChar: ! 1344: emit(Iprintchar); ! 1345: break; ! 1346: case TInt: ! 1347: emit(Iprintint); ! 1348: break; ! 1349: case TUnit: ! 1350: emit(Iprintunit); ! 1351: break; ! 1352: default: ! 1353: panic("printgen: bad type %t", t->o.t); ! 1354: } ! 1355: } ! 1356: ! 1357: proggen(Node *t, Node *n) ! 1358: { ! 1359: int or; ! 1360: Node *of; ! 1361: Errjmp s; ! 1362: Store *p; ! 1363: long len, loc; ! 1364: long nauto, oao; ! 1365: extern int (*prog[])(); ! 1366: oao=autooffset; ! 1367: or=returnloc; ! 1368: of=formals; ! 1369: autooffset=0; ! 1370: returnloc=0; ! 1371: formals=t->l; ! 1372: errsave(s); ! 1373: if(errmark()){ ! 1374: returnloc=or; ! 1375: formals=of; ! 1376: autooffset=oao; ! 1377: errrest(s); ! 1378: errjmp(); ! 1379: } ! 1380: loc=here(); ! 1381: pushscope(); ! 1382: dclformals(t->l); ! 1383: autooffset=0; ! 1384: emit(Ipushfp); ! 1385: nauto=here(); ! 1386: emitconst(0L); ! 1387: gen(n, 0); ! 1388: trlrgen(); ! 1389: patch((int)nauto, autooffset); ! 1390: popscope(); ! 1391: errrest(s); ! 1392: autooffset=oao; ! 1393: returnloc=or; ! 1394: formals=of; ! 1395: len=here()-loc+1; ! 1396: p=(Store *)emalloc(SHSZ+len*LWS); ! 1397: memcpy((char *)(p->data), (char *)(prog+loc), len*LWS); ! 1398: p->ref=1; ! 1399: p->len=len; ! 1400: p->type=Sprog; ! 1401: setprog(loc); ! 1402: emit(Ipushdata); ! 1403: emitconst((long)p); ! 1404: } ! 1405: ! 1406: trlrgen() ! 1407: { ! 1408: if(returnloc){ ! 1409: emit(Ijmp); ! 1410: emitconst((long)(returnloc-here()-1)*WS); ! 1411: return; ! 1412: } ! 1413: returnloc=here(); ! 1414: fdecrefgen(formals, -3L*WS); ! 1415: emit(Iret); ! 1416: if(formals) ! 1417: emitconst(length(formals)*LWS); ! 1418: else ! 1419: emitconst(0L); ! 1420: } ! 1421: ! 1422: fdecrefgen(Node *types, long offset) ! 1423: { ! 1424: if(types==0) ! 1425: return 0; ! 1426: if(types->t==NList){ ! 1427: offset=fdecrefgen(types->l, offset); ! 1428: return fdecrefgen(types->r, offset); ! 1429: } ! 1430: if(types->t!=NFormal) ! 1431: panic("fdecrefgen"); ! 1432: types=types->r; ! 1433: if(isptrtype(types)){ ! 1434: emit(Idecrefauto); ! 1435: emitconst(offset); ! 1436: } ! 1437: return offset-WS; ! 1438: } ! 1439: ! 1440: dupgen(Node *t, int n) ! 1441: { ! 1442: while(n--) ! 1443: emit(isptrtype(t)? Idupptr : Idup); ! 1444: } ! 1445: ! 1446: mkgen(Node *t, Node *v) ! 1447: { ! 1448: switch(t->o.t){ ! 1449: case TChar: ! 1450: case TInt: ! 1451: case TUnit: ! 1452: if(v) ! 1453: gen(v, 1); ! 1454: else ! 1455: constgen(0L); ! 1456: return; ! 1457: case TID: ! 1458: mkgen(typeoftid(t), v); ! 1459: return; ! 1460: case TChan: ! 1461: if(v) ! 1462: gen(v, 1); ! 1463: else{ ! 1464: constgen((long)(sizeof(Chan)-sizeof(Store))); ! 1465: mallocgen(t); ! 1466: } ! 1467: return; ! 1468: case TArray: ! 1469: if(v==0){ ! 1470: gen(t->l, 1); ! 1471: mallocgen(t); ! 1472: return; ! 1473: } ! 1474: gen(v, 1); ! 1475: if(v->t!=NExprlist && eqtype(t, etypeof(v))) ! 1476: return; ! 1477: if(v->t==NString) ! 1478: constgen((long)strlen(v->o.c)); ! 1479: else ! 1480: constgen((long)length(v)); ! 1481: emit(Idup); ! 1482: if(t->l) ! 1483: gen(t->l, 1); ! 1484: else ! 1485: constgen(0L); ! 1486: emit(Imax); ! 1487: mallocgen(t); ! 1488: if(t->r->o.t==TChar){ ! 1489: if(v->t==NString) ! 1490: emit(Imemcpychar); ! 1491: else ! 1492: emit(Imemcpycharint); ! 1493: }else ! 1494: emit(Imemcpy); ! 1495: return; ! 1496: case TProg: ! 1497: if(v==0){ ! 1498: v=new(NProg, dupnode(t), (Node *)0, (Node *)0); ! 1499: gen(v, 1); ! 1500: freenode(v); ! 1501: return; ! 1502: } ! 1503: gen(v, 1); ! 1504: return; ! 1505: case TStruct: ! 1506: if(v==0){ ! 1507: mallocgen(t); ! 1508: return; ! 1509: } ! 1510: gen(v, 1); ! 1511: if(v->t!=NExprlist && eqtype(t, etypeof(v))) ! 1512: return; ! 1513: constgen((long)length(v)); ! 1514: mallocgen(t); ! 1515: emit(Imemcpystruct); ! 1516: return; ! 1517: default: ! 1518: panic("mkgen: bad type %t", t->o.t); ! 1519: } ! 1520: } ! 1521: ! 1522: mallocgen(Node *t) ! 1523: { ! 1524: switch(t->o.t){ ! 1525: case TArray: ! 1526: t=t->r; ! 1527: if(t->o.t==TID) ! 1528: t=typeoftid(t); ! 1529: if(isptrtype(t)){ ! 1530: constgen((long)Saryptr); ! 1531: emit(Imalloc); ! 1532: }else if(t->o.t==TInt || t->o.t==TUnit){ ! 1533: constgen((long)Saryint); ! 1534: emit(Imalloc); ! 1535: }else if(t->o.t==TChar) ! 1536: emit(Imallocarychar); ! 1537: else ! 1538: panic("mallocgen array of %t", t->o.t); ! 1539: return; ! 1540: case TStruct:{ ! 1541: int pos=0; ! 1542: long bits=0; ! 1543: t=t->l; ! 1544: elembitsgen(t, &pos, &bits); ! 1545: if(pos) ! 1546: constgen(bits); ! 1547: constgen((long)length(t)); ! 1548: emit(Imallocstruct); ! 1549: return; ! 1550: } ! 1551: case TChan: ! 1552: constgen((long)Schan); ! 1553: emit(Imalloc); ! 1554: return; ! 1555: } ! 1556: panic("mallocgen of %t", t->o.t); ! 1557: } ! 1558: ! 1559: elembitsgen(Node *t, int *pos, long *bits) ! 1560: { ! 1561: int i; ! 1562: if(t->t==NList){ ! 1563: elembitsgen(t->l, pos, bits); ! 1564: elembitsgen(t->r, pos, bits); ! 1565: return; ! 1566: } ! 1567: if(t->t!=NElem) ! 1568: panic("elembitsgen %n", t->t); ! 1569: for(i=length(t); --i>=0; ){ ! 1570: if(*pos==BPW){ ! 1571: constgen(*bits); ! 1572: *pos=0; ! 1573: *bits=0; ! 1574: } ! 1575: if(isptrtype(t->r)) ! 1576: *bits|=1L<<*pos; ! 1577: (*pos)++; ! 1578: } ! 1579: } ! 1580: ! 1581: constgen(long l) ! 1582: { ! 1583: if(l<-2 || l>10){ ! 1584: emit(Ipushconst); ! 1585: emitconst(l); ! 1586: return; ! 1587: }; ! 1588: switch((int)l){ ! 1589: case -2: ! 1590: emit(Ipush_2); ! 1591: break; ! 1592: case -1: ! 1593: emit(Ipush_1); ! 1594: break; ! 1595: case 0: ! 1596: emit(Ipush0); ! 1597: break; ! 1598: case 1: ! 1599: emit(Ipush1); ! 1600: break; ! 1601: case 2: ! 1602: emit(Ipush2); ! 1603: break; ! 1604: case 3: ! 1605: emit(Ipush3); ! 1606: break; ! 1607: case 4: ! 1608: emit(Ipush4); ! 1609: break; ! 1610: case 5: ! 1611: emit(Ipush5); ! 1612: break; ! 1613: case 6: ! 1614: emit(Ipush6); ! 1615: break; ! 1616: case 7: ! 1617: emit(Ipush7); ! 1618: break; ! 1619: case 8: ! 1620: emit(Ipush8); ! 1621: break; ! 1622: case 9: ! 1623: emit(Ipush9); ! 1624: break; ! 1625: case 10: ! 1626: emit(Ipush10); ! 1627: break; ! 1628: default: ! 1629: panic("constgen"); ! 1630: } ! 1631: } ! 1632: ! 1633: printable(Node *n) ! 1634: { ! 1635: if(n==0) ! 1636: return 0; ! 1637: switch(n->t){ ! 1638: case NExpr: ! 1639: return n->o.t!='='; ! 1640: case NArrayref: ! 1641: case NCall: ! 1642: case NID: ! 1643: case NMk: ! 1644: case NNum: ! 1645: case NProg: ! 1646: case NString: ! 1647: case NStructref: ! 1648: case NUnit: ! 1649: case NVal: ! 1650: return 1; ! 1651: } ! 1652: return 0; ! 1653: } ! 1654: #include "alloc.h" ! 1655: #include "node.h" ! 1656: #include "symbol.h" ! 1657: #include "ydefs.h" ! 1658: #include "word.h" ! 1659: #include "store.h" ! 1660: #include <libc.h> ! 1661: ! 1662: Node *doconst(); ! 1663: extern int Cflag; ! 1664: ! 1665: Node * ! 1666: constants(Node *n) ! 1667: { ! 1668: if(n==0) ! 1669: return 0; ! 1670: if(Cflag) ! 1671: return n; ! 1672: switch(n->t){ ! 1673: case NArrayref: ! 1674: if(isconst(n)) ! 1675: return doconst(n); ! 1676: break; ! 1677: case NArraycom: ! 1678: break; ! 1679: case NBecome: ! 1680: break; ! 1681: case NBegin: ! 1682: break; ! 1683: case NCall: ! 1684: break; ! 1685: case NCase: ! 1686: break; ! 1687: case NDecl: ! 1688: n->r=constants(n->r); ! 1689: n->o.n=constants(n->o.n); ! 1690: declare(n, 0, 0, 0); ! 1691: return n; ! 1692: case NDeclsc: ! 1693: break; ! 1694: case NDefault: ! 1695: return n; ! 1696: case NElem: ! 1697: n->r=constants(n->r); ! 1698: return n; ! 1699: case NExpr: ! 1700: switch(n->o.i){ ! 1701: case GE: ! 1702: case LE: ! 1703: case NE: ! 1704: case EQ: ! 1705: case '>': ! 1706: case '<': ! 1707: case '+': ! 1708: case '-': ! 1709: case '*': ! 1710: case '/': ! 1711: case '%': ! 1712: case '&': ! 1713: case '|': ! 1714: case '^': ! 1715: case ANDAND: ! 1716: case OROR: ! 1717: case LSH: ! 1718: case RSH: ! 1719: if(isconst(n->l) && isconst(n->r)) ! 1720: return doconst(n); ! 1721: break; ! 1722: case DEF: ! 1723: case REF: ! 1724: case LEN: ! 1725: case UMINUS: ! 1726: case '~': ! 1727: case '!': ! 1728: if(isconst(n->l)) ! 1729: return doconst(n); ! 1730: break; ! 1731: case PRINT: ! 1732: case RCV: ! 1733: case SND: ! 1734: case INC: ! 1735: case DEC: ! 1736: break; ! 1737: case '=': ! 1738: break; ! 1739: default: ! 1740: fprint(2, "can't const expression %e\n", n->o.i); ! 1741: return n; ! 1742: } ! 1743: break; ! 1744: case NExprlist: ! 1745: break; ! 1746: case NFormal: ! 1747: n->r=constants(n->r); ! 1748: return n; ! 1749: case NLabel: ! 1750: break; ! 1751: case NID: ! 1752: if(isconst(n)) ! 1753: return doconst(n); ! 1754: break; ! 1755: case NIf: ! 1756: n->l=constants(n->l); ! 1757: n->r=constants(n->r); ! 1758: n->o.n=constants(n->o.n); ! 1759: if(isconst(n->o.n)){ ! 1760: Node *m; ! 1761: gen(n->o.n, 1); ! 1762: execute(); ! 1763: if(topofstack()){ ! 1764: m=n->l; ! 1765: n->l=0; ! 1766: }else{ ! 1767: m=n->r; ! 1768: n->r=0; ! 1769: } ! 1770: freenode(n); ! 1771: return m; ! 1772: } ! 1773: return n; ! 1774: case NList: ! 1775: break; ! 1776: case NLoop: ! 1777: break; ! 1778: case NLoopexpr: ! 1779: n->o.n=constants(n->o.n); ! 1780: break; ! 1781: case NMk: ! 1782: break; ! 1783: case NNum: ! 1784: return n; ! 1785: case NProg: ! 1786: pushscope(); ! 1787: dclformals(n->l->l); ! 1788: n->r=constants(n->r); ! 1789: popscope(); ! 1790: return n; ! 1791: case NResult: ! 1792: break; ! 1793: case NScope: ! 1794: pushscope(); ! 1795: n->l=constants(n->l); ! 1796: popscope(); ! 1797: return n; ! 1798: case NSelect: ! 1799: break; ! 1800: case NSmash: ! 1801: return n; ! 1802: case NString: ! 1803: return n; ! 1804: case NSwitch: ! 1805: break; ! 1806: case NStructref: ! 1807: if(isconst(n)) ! 1808: return (n); ! 1809: break; ! 1810: case NType: ! 1811: break; ! 1812: case NUnit: ! 1813: break; ! 1814: case NVal: ! 1815: if(isconst(n->l)) ! 1816: return doconst(n); ! 1817: break; ! 1818: default: ! 1819: fprint(2, "can't const node %n\n", n->t); ! 1820: return n; ! 1821: } ! 1822: n->l=constants(n->l); ! 1823: n->r=constants(n->r); ! 1824: return n; ! 1825: } ! 1826: ! 1827: isconst(Node *n) ! 1828: { ! 1829: if(n==0) ! 1830: return 1; ! 1831: switch(n->t){ ! 1832: case NArrayref: ! 1833: return isconst(n->l) && isconst(n->r); ! 1834: case NCall: ! 1835: return 0; ! 1836: case NExpr: ! 1837: switch(n->o.i){ ! 1838: case GE: ! 1839: case LE: ! 1840: case NE: ! 1841: case EQ: ! 1842: case '>': ! 1843: case '<': ! 1844: case '+': ! 1845: case '-': ! 1846: case '*': ! 1847: case '/': ! 1848: case '%': ! 1849: case '&': ! 1850: case '|': ! 1851: case '^': ! 1852: case ANDAND: ! 1853: case OROR: ! 1854: case LSH: ! 1855: case RSH: ! 1856: return isconst(n->l) && isconst(n->r); ! 1857: case DEF: ! 1858: case LEN: ! 1859: case UMINUS: ! 1860: case '~': ! 1861: case '!': ! 1862: return isconst(n->l); ! 1863: case REF: ! 1864: case '=': ! 1865: case RCV: ! 1866: case SND: ! 1867: case INC: ! 1868: case DEC: ! 1869: return 0; ! 1870: } ! 1871: fprint(2, "can't isconst expression %e", n->o.i); ! 1872: return 0; ! 1873: case NID: ! 1874: return n->o.s->val->scope==0 && (n->o.s->val->stclass&SCconst); ! 1875: case NIf: ! 1876: return isconst(n->o.n) && isconst(n->l) && isconst(n->r); ! 1877: case NList: ! 1878: return 0; ! 1879: case NLoop: ! 1880: return 0; ! 1881: case NNum: ! 1882: return 1; ! 1883: case NResult: ! 1884: return isconst(n->l); ! 1885: case NScope: ! 1886: return isconst(n->l); ! 1887: case NString: ! 1888: return 1; ! 1889: case NStructref: ! 1890: return isconst(n->l); ! 1891: case NVal: ! 1892: return isconst(n->l); ! 1893: case NUnit: ! 1894: return 1; ! 1895: } ! 1896: fprint(2, "can't isconst node %n\n", n->t); ! 1897: return 0; ! 1898: } ! 1899: ! 1900: Node * ! 1901: doconst(Node *n) ! 1902: { ! 1903: Node *t; ! 1904: if(n->t==NNum || n->t==NString || n->t==NUnit) ! 1905: return n; /* already const */ ! 1906: t=etypeoft(n); ! 1907: switch(t->o.t){ ! 1908: case TChar: ! 1909: case TInt: ! 1910: gen(n, 1); ! 1911: freenode(n); ! 1912: execute(); ! 1913: return new(NNum, (Node *)0, (Node *)0, (Node *)topofstack()); ! 1914: case TUnit: ! 1915: return new(NUnit, (Node *)0, (Node *)0, (Node *)0); ! 1916: case TArray: ! 1917: if(t->r->o.t==TChar){ ! 1918: Store *s; ! 1919: char *c; ! 1920: gen(n, 1); ! 1921: freenode(n); ! 1922: execute(); ! 1923: s=(Store *)topofstack(); ! 1924: c=emalloc(s->len+1); ! 1925: strncpy(c, (char *)s->data, (int)s->len); ! 1926: return newc(NString, (Node *)0, (Node *)0, c); ! 1927: } ! 1928: return n; ! 1929: } ! 1930: return n; ! 1931: } ! 1932: #include "alloc.h" ! 1933: #include "word.h" ! 1934: #include "store.h" ! 1935: #include "comm.h" ! 1936: #include <libc.h> ! 1937: ! 1938: extern int pflag; ! 1939: ! 1940: /* ! 1941: * Jumps ! 1942: */ ! 1943: ! 1944: ijmp(Proc *proc) ! 1945: { ! 1946: SWord l; ! 1947: l=(SWord)*++proc->pc; ! 1948: proc->pc+=l/WS; ! 1949: return 1; ! 1950: } ! 1951: ! 1952: ijmpfalse(Proc *proc) ! 1953: { ! 1954: SWord l; ! 1955: l=(SWord)*++proc->pc; ! 1956: if(*--proc->sp==0) ! 1957: proc->pc+=l/WS; ! 1958: return 1; ! 1959: } ! 1960: ! 1961: ijmptrue(Proc *proc) ! 1962: { ! 1963: SWord l; ! 1964: l=(SWord)*++proc->pc; ! 1965: if(*--proc->sp!=0) ! 1966: proc->pc+=l/WS; ! 1967: return 1; ! 1968: } ! 1969: ! 1970: ivalnoresult(Proc *proc) ! 1971: { ! 1972: rerror("val produces no result"); ! 1973: return 0; ! 1974: } ! 1975: ! 1976: /* ! 1977: * Progs ! 1978: * ! 1979: * Layout of a stack frame ! 1980: * ! 1981: * sp: ! 1982: * automatics ! 1983: * fp: old fp ! 1984: * old pc ! 1985: * symbol ! 1986: * arg1 ! 1987: * arg2 ! 1988: * ... ! 1989: * result ! 1990: */ ! 1991: ! 1992: iret(Proc *proc) ! 1993: { ! 1994: SWord nargs; ! 1995: nargs=(SWord)(proc->pc[1]); ! 1996: proc->sp=(SWord *)proc->fp+1; ! 1997: proc->fp=(SWord *)*--proc->sp; ! 1998: proc->pc=(int (**)())*--proc->sp; ! 1999: proc->sp-=(sizeof(char *)+nargs)/WS; ! 2000: if(proc->pc==0){ ! 2001: if(pflag) ! 2002: fprint(2, "%d halts\n", proc->procnum); ! 2003: halt(proc); ! 2004: return 0; ! 2005: } ! 2006: return 1; ! 2007: } ! 2008: ! 2009: ibecome(Proc *proc) ! 2010: { ! 2011: int nargs; ! 2012: int (**newpc)(); ! 2013: SWord oldfp, oldpc, *oldresultaddr, *newresultaddr; ! 2014: Store *s; ! 2015: nargs=*--proc->sp/LWS; ! 2016: nargs+=2; /* includes result and sym; add pc, fp */ ! 2017: s=(Store *)*--proc->sp; ! 2018: if(--(s->ref)==0) ! 2019: rpanic("ibecome ref==0"); ! 2020: newpc=((int (**)())s->data); ! 2021: oldfp=proc->fp[0]; ! 2022: oldpc=proc->fp[-1]; ! 2023: *proc->sp++=oldpc; ! 2024: *proc->sp++=oldfp; ! 2025: oldresultaddr=proc->fp-3-(long)(*++proc->pc)/LWS; ! 2026: newresultaddr=proc->sp-nargs; ! 2027: memcpy((char *)oldresultaddr, (char *)newresultaddr, LWS*nargs); ! 2028: /* args in place. do the call by hand, jmp to pushfp */ ! 2029: proc->sp=oldresultaddr+(nargs-2); ! 2030: *proc->sp++=oldpc; ! 2031: proc->fp=(SWord *)oldfp; ! 2032: proc->pc=newpc-1; ! 2033: return 1; ! 2034: } ! 2035: ! 2036: ipushfp(Proc *proc) ! 2037: { ! 2038: int nauto; ! 2039: *proc->sp=(SWord)proc->fp; ! 2040: proc->fp=proc->sp++; ! 2041: nauto=((SWord)*++proc->pc)/WS; ! 2042: while(nauto--) ! 2043: *proc->sp++=0; ! 2044: if(proc->sp>=&proc->stack[NSTACK]) ! 2045: rerror("stack overflow"); ! 2046: return 1; ! 2047: } ! 2048: ! 2049: icall(Proc *proc) ! 2050: { ! 2051: int (**newpc)(); ! 2052: Store *s; ! 2053: s=(Store *)*--proc->sp; ! 2054: if(--(s->ref)==0) ! 2055: rpanic("icall ref==0"); ! 2056: newpc=((int (**)())s->data); ! 2057: *proc->sp++=(SWord)proc->pc; ! 2058: proc->pc=newpc-1; ! 2059: return 1; ! 2060: } ! 2061: #include "node.h" ! 2062: #include "symbol.h" ! 2063: #include "alloc.h" ! 2064: #include "ydefs.h" ! 2065: #include "word.h" ! 2066: #include "store.h" ! 2067: #include <libc.h> ! 2068: ! 2069: extern int nscope; ! 2070: ! 2071: declare(Node *n, int stclass, int dotypchk, int docomp) ! 2072: { ! 2073: extern int iflag; ! 2074: if(n==0) ! 2075: return; ! 2076: if(n->t==NList){ ! 2077: declare(n->l, stclass, dotypchk, docomp); ! 2078: declare(n->r, stclass, dotypchk, docomp); ! 2079: return; ! 2080: } ! 2081: if(n->t==NDeclsc){ ! 2082: declare(n->l, n->o.i, dotypchk, docomp); ! 2083: return; ! 2084: } ! 2085: if(dotypchk) ! 2086: type(n->o.n, 0); ! 2087: if(n->r==0){ ! 2088: if(n->o.n==0) ! 2089: panic("declare: no type"); ! 2090: if(n->o.n->t==NMk && n->o.n->l==0) ! 2091: lerror(n, "can't derive type in declaration"); ! 2092: n->r=dupnode(etypeof(n->o.n)); ! 2093: } ! 2094: if(dotypchk){ ! 2095: type(n->r, 0); ! 2096: if(n->o.n){ ! 2097: /* ! 2098: * Make it a mk ! 2099: */ ! 2100: if(n->o.n->t!=NMk) ! 2101: n->o.n=new(NMk, (Node *)0, n->o.n, (Node *)0); ! 2102: /* ! 2103: * Default type for mk ! 2104: */ ! 2105: if(n->o.n->l==0) ! 2106: n->o.n->l=dupnode(n->r); ! 2107: else if(!compattype(n->r, n->o.n->l)) ! 2108: lerror(n, "type clash in declaration (%t %t)\n", ! 2109: n->r->o.t, etypeof(n->o.n)->o.t); ! 2110: mkcheck(n->o.n->l, n->o.n->r); ! 2111: } ! 2112: } ! 2113: if(docomp && n->o.n){ ! 2114: if(dotypchk) /* top level declaration */ ! 2115: n->o.n=constants(n->o.n); ! 2116: gen(n->o.n, 1); ! 2117: dupgen(n->r, length(n->l)-1); ! 2118: }else ! 2119: docomp=0; ! 2120: dcl(n->l, n->r, stclass, n->o.n, docomp); ! 2121: if(n->o.n && docomp && nscope==0){ ! 2122: if(iflag) ! 2123: idump(); ! 2124: execute(); ! 2125: } ! 2126: } ! 2127: ! 2128: dcl(id, typ, stclass, val, docomp) ! 2129: Node *id, *typ, *val; ! 2130: { ! 2131: if(id->t==NList){ ! 2132: dcl(id->l, typ, stclass, val, docomp); ! 2133: dcl(id->r, typ, stclass, val, docomp); ! 2134: return; ! 2135: } ! 2136: if(typ->o.t==TID && typ->l->o.s->val->type->o.t!=TType) ! 2137: error("%m not a type", typ->l); ! 2138: if(id->t!=NID) ! 2139: panic("dcl not ID"); ! 2140: pushval(id->o.s, dupnode(typ)); ! 2141: if(stclass&SCbltin) ! 2142: id->o.s->val->store.l=bltinval(id->o.s->name, typ); ! 2143: if(docomp) ! 2144: lgen(id); ! 2145: id->o.s->val->stclass=stclass; ! 2146: } ! 2147: ! 2148: /* ! 2149: * To compile this ! 2150: * rec { ! 2151: * x : chan of T = f(x,y); ! 2152: * y : chan of T = g(x,y); ! 2153: * }; ! 2154: * convert it to this ! 2155: * x : chan of T = mk(); ! 2156: * y : chan of T = mk(); ! 2157: * x1 : chan of T = f(x,y); ! 2158: * y1 : chan of T = g(x,y); ! 2159: * x <- x1; ! 2160: * y <- y1; ! 2161: * toss x1, y1; ! 2162: * where the operator x <- x1 means copy the representation of x1 into x. ! 2163: * ! 2164: * rec type T: struct of { t:T; }; ! 2165: * ! 2166: * is handled similarly. ! 2167: */ ! 2168: ! 2169: Node * ! 2170: op1(Node *n) ! 2171: { ! 2172: Node *m; ! 2173: if(n->t==NDeclsc){ ! 2174: m=op1(n->l); ! 2175: return newi(NDeclsc, m, (Node *)0, n->o.i); ! 2176: } ! 2177: if(n->r==0){ ! 2178: if(n->o.n && (n->o.n->t==NProg || (n->o.n->t==NMk && n->o.n->l))) ! 2179: n->r=dupnode(n->o.n->l); ! 2180: else ! 2181: lerror(n, "can't deduce type for rec decl"); ! 2182: }else if(n->r->o.t==TType){ ! 2183: m=newi(NType, (Node *)0, (Node *)0, n->r->l->o.t); ! 2184: m=new(NDecl, dupnode(n->l), m, (Node *)0); ! 2185: return m; ! 2186: } ! 2187: m=new(NMk, dupnode(n->r), (Node *)0, (Node *)0); ! 2188: m=new(NDecl, dupnode(n->l), dupnode(n->r), m); ! 2189: return m; ! 2190: } ! 2191: ! 2192: Node * ! 2193: op2(Node *n) ! 2194: { ! 2195: Node *m; ! 2196: char s[Namesize+2]; ! 2197: if(n->t==NDeclsc){ ! 2198: m=op2(n->l); ! 2199: return newi(NDeclsc, m, (Node *)0, n->o.i); ! 2200: } ! 2201: if(n->l->t==NList) ! 2202: error("no identifier lists in rec's, please"); ! 2203: strcpy(s+1, n->l->o.s->name); ! 2204: s[0]='*'; ! 2205: m=new(NDecl, idnode(lookup(s, ID)), dupnode(n->r), dupnode(n->o.n)); ! 2206: return m; ! 2207: } ! 2208: ! 2209: Node * ! 2210: op3(Node *n) ! 2211: { ! 2212: Node *m; ! 2213: char s[Namesize+2]; ! 2214: if(n->t==NDeclsc) ! 2215: return op3(n->l); ! 2216: if(n->l->t==NList) ! 2217: error("no lists in rec's, please"); ! 2218: strcpy(s+1, n->l->o.s->name); ! 2219: s[0]='*'; ! 2220: m=new(NSmash, idnode(lookup(s+1, ID)), idnode(lookup(s, ID)), (Node *)0); ! 2221: return m; ! 2222: } ! 2223: ! 2224: Node * ! 2225: rewr(Node *n, Node *(*f)()) ! 2226: { ! 2227: if(n->t==NList) ! 2228: return new(NList, rewr(n->l, f), rewr(n->r, f), (Node *)0); ! 2229: return (*f)(n); ! 2230: } ! 2231: ! 2232: recrewrite(Node *n) ! 2233: { ! 2234: Node *n1, *n2, *n3; ! 2235: n1=rewr(n->l, op1); ! 2236: n2=rewr(n->l, op2); ! 2237: n3=rewr(n->l, op3); ! 2238: freenode(n->l); ! 2239: n->t=NList; ! 2240: n->r=n3; ! 2241: n->l=new(NList, n1, n2, (Node *)0); ! 2242: ndump(n); ! 2243: } ! 2244: ! 2245: /* ! 2246: * ! 2247: * To compile this ! 2248: * ! 2249: * prog(a:int){ ! 2250: * begin prog(b:int){ f(a, b); }(b); ! 2251: * } ! 2252: * ! 2253: * convert it to this ! 2254: * ! 2255: * prog(a:int){ ! 2256: * begin prog(b:int, a:int){ f(a, b); }(b, a); ! 2257: * } ! 2258: * ! 2259: */ ! 2260: ! 2261: Node *begf; ! 2262: Node *bega; ! 2263: int fscope; ! 2264: int progerr; ! 2265: ! 2266: proglocals(Node *n) ! 2267: { ! 2268: progerr=1; ! 2269: pushscope(); ! 2270: fscope=nscope; ! 2271: begf=n->l->l; ! 2272: bega=0; ! 2273: dclformals(begf); ! 2274: progid(n->r); ! 2275: popscope(); ! 2276: } ! 2277: ! 2278: begrewrite(Node *n) ! 2279: { ! 2280: progerr=0; ! 2281: pushscope(); ! 2282: fscope=nscope; ! 2283: begf=n->l->l->l; ! 2284: bega=n->r; ! 2285: dclformals(begf); ! 2286: progid(n->l->r); ! 2287: popscope(); ! 2288: n->l->l->l=begf; ! 2289: n->r=bega; ! 2290: } ! 2291: ! 2292: addformal(Node *n) ! 2293: { ! 2294: Node *nf; ! 2295: if(!alreadyformal(n, begf)){ ! 2296: nf=new(NFormal, dupnode(n), dupnode(n->o.s->val->type), (Node *)0); ! 2297: if(begf) ! 2298: begf=new(NList, begf, nf, (Node *)0); ! 2299: else ! 2300: begf=nf; ! 2301: nf=dupnode(n); ! 2302: if(bega) ! 2303: bega=new(NExprlist, bega, nf, (Node *)0); ! 2304: else ! 2305: bega=nf; ! 2306: } ! 2307: } ! 2308: ! 2309: alreadyformal(Node *n, Node *f) ! 2310: { ! 2311: if(f==0) ! 2312: return 0; ! 2313: if(f->t==NList) ! 2314: return alreadyformal(n, f->l) || alreadyformal(n, f->r); ! 2315: return strcmp(n->o.s->name, f->l->o.s->name)==0; ! 2316: } ! 2317: ! 2318: progid(Node *n) ! 2319: { ! 2320: if(n==0) ! 2321: return; ! 2322: switch(n->t){ ! 2323: case NArrayref: ! 2324: case NArraycom: ! 2325: case NBecome: ! 2326: case NBegin: ! 2327: case NCall: ! 2328: case NCase: ! 2329: break; ! 2330: case NDecl: ! 2331: progid(n->r); ! 2332: progid(n->o.n); ! 2333: declare(n, 0, 0, 0); ! 2334: return; ! 2335: case NDeclsc: ! 2336: case NDefault: ! 2337: break; ! 2338: case NElem: ! 2339: return; ! 2340: case NExpr: ! 2341: case NExprlist: ! 2342: case NFormal: ! 2343: break; ! 2344: case NID: ! 2345: if(n->o.s->val) ! 2346: if(0<n->o.s->val->scope && n->o.s->val->scope<fscope){ ! 2347: if(progerr) ! 2348: lerror(n, "%m not in an accessible scope", n); ! 2349: addformal(n); ! 2350: } ! 2351: return; ! 2352: case NLabel: ! 2353: case NList: ! 2354: case NLoop: ! 2355: break; ! 2356: case NLoopexpr: ! 2357: progid(n->o.n); ! 2358: break; ! 2359: case NIf: ! 2360: progid(n->o.n); ! 2361: break; ! 2362: case NMk: ! 2363: break; ! 2364: case NNum: ! 2365: return; ! 2366: case NProg: ! 2367: pushscope(); ! 2368: dclformals(n->l->l); ! 2369: progid(n->r); ! 2370: popscope(); ! 2371: return; ! 2372: case NResult: ! 2373: break; ! 2374: case NScope: ! 2375: pushscope(); ! 2376: progid(n->l); ! 2377: popscope(); ! 2378: return; ! 2379: case NSelect: ! 2380: break; ! 2381: case NSmash: ! 2382: return; /* ?? */ ! 2383: case NString: ! 2384: return; ! 2385: case NSwitch: ! 2386: case NStructref: ! 2387: break; ! 2388: case NType: ! 2389: break; ! 2390: case NUnit: ! 2391: return; ! 2392: case NVal: ! 2393: break; ! 2394: default: ! 2395: fprint(2, "can't progid node %n\n", n->t); ! 2396: return; ! 2397: } ! 2398: progid(n->l); ! 2399: progid(n->r); ! 2400: } ! 2401: ! 2402: #include "nodenames.h" ! 2403: #include "typenames.h" ! 2404: #include "errjmp.h" ! 2405: #include "node.h" ! 2406: #include "symbol.h" ! 2407: #include "ydefs.h" ! 2408: #include <libc.h> ! 2409: ! 2410: lerror(Node *n, char *s, a, b, c, d, e, f) ! 2411: { ! 2412: lfileline(n->line); ! 2413: fprint(2, s, a, b, c, d, e, f); ! 2414: if(s[strlen(s)-1]!='\n') ! 2415: fprint(2, "\n"); ! 2416: errflush(); ! 2417: errjmp(); ! 2418: } ! 2419: ! 2420: error(char *s, a, b, c, d, e, f) ! 2421: { ! 2422: fileline(); ! 2423: fprint(2, s, a, b, c, d, e, f); ! 2424: if(s[strlen(s)-1]!='\n') ! 2425: fprint(2, "\n"); ! 2426: errflush(); ! 2427: errjmp(); ! 2428: } ! 2429: ! 2430: rerror(char *s, a, b, c, d, e, f) ! 2431: { ! 2432: fileline(); ! 2433: fprint(2, s, a, b, c, d, e, f); ! 2434: fprint(2, "\n"); ! 2435: processes(0); ! 2436: errflush(); ! 2437: errjmp(); ! 2438: } ! 2439: ! 2440: warn(char *s, a, b, c, d, e, f) ! 2441: { ! 2442: fileline(); ! 2443: fprint(2, "warning: "); ! 2444: fprint(2, s, a, b, c, d, e, f); ! 2445: fprint(2, "\n"); ! 2446: } ! 2447: ! 2448: panic(char *s, a, b, c, d, e, f) ! 2449: { ! 2450: fileline(); ! 2451: fprint(2, "internal error: "); ! 2452: fprint(2, s, a, b, c, d, e, f); ! 2453: fprint(2, "\n"); ! 2454: abort(); ! 2455: } ! 2456: ! 2457: rpanic(char *s, a, b, c, d, e, f) ! 2458: { ! 2459: fileline(); ! 2460: processes(0); ! 2461: fprint(2, "internal error: "); ! 2462: fprint(2, s, a, b, c, d, e, f); ! 2463: fprint(2, "\n"); ! 2464: abort(); ! 2465: } ! 2466: ! 2467: bconv(int *o, int f1, int f2) ! 2468: { ! 2469: extern int printcol; ! 2470: while(printcol<*o-8) ! 2471: strconv("\t", f1, f2); ! 2472: strconv(" "+(8-(*o-printcol)), f1, f2); ! 2473: return sizeof(int); ! 2474: } ! 2475: ! 2476: nconv(int *o, int f1, int f2) ! 2477: { ! 2478: if(*o<0 || sizeof(Ntypename)/sizeof(Ntypename[0])<=*o) ! 2479: strconv("mystery node", f1, f2); ! 2480: else ! 2481: strconv(Ntypename[*o], f1, f2); ! 2482: return sizeof(int); ! 2483: } ! 2484: ! 2485: tconv(int *o, int f1, int f2) ! 2486: { ! 2487: if(*o<0 || sizeof(Ttypename)/sizeof(Ttypename[0])<=*o) ! 2488: strconv("mystery type", f1, f2); ! 2489: else ! 2490: strconv(Ttypename[*o], f1, f2); ! 2491: return sizeof(int); ! 2492: } ! 2493: ! 2494: char bufx[128][10]; ! 2495: int bufno=9; ! 2496: ! 2497: char * ! 2498: prbuf(){ ! 2499: if(++bufno==10) ! 2500: bufno=0; ! 2501: return bufx[bufno]; ! 2502: } ! 2503: ! 2504: econv(int *o, int f1, int f2) ! 2505: { ! 2506: char *buf=prbuf(); ! 2507: char *x; ! 2508: int t=*o; ! 2509: if(t<128 && strchr("+-*/%|&^~?!><=", t)) ! 2510: sprint(buf, "%c", t); ! 2511: else{ ! 2512: switch(t){ ! 2513: case GE: ! 2514: x=">="; ! 2515: break; ! 2516: case LE: ! 2517: x="<="; ! 2518: break; ! 2519: case NE: ! 2520: x="!="; ! 2521: break; ! 2522: case EQ: ! 2523: x="=="; ! 2524: break; ! 2525: case ANDAND: ! 2526: x="&&"; ! 2527: break; ! 2528: case OROR: ! 2529: x="||"; ! 2530: break; ! 2531: case REF: ! 2532: x="ref"; ! 2533: break; ! 2534: case LEN: ! 2535: x="len"; ! 2536: break; ! 2537: case UMINUS: ! 2538: x="unary -"; ! 2539: break; ! 2540: case RCV: ! 2541: x="rcv"; ! 2542: break; ! 2543: case SND: ! 2544: x="send"; ! 2545: break; ! 2546: case LSH: ! 2547: x="<<"; ! 2548: break; ! 2549: case RSH: ! 2550: x=">>"; ! 2551: break; ! 2552: case DEC: ! 2553: x="--"; ! 2554: break; ! 2555: case INC: ! 2556: x="++"; ! 2557: break; ! 2558: default: ! 2559: x="mystery expression"; ! 2560: break; ! 2561: } ! 2562: strcpy(buf, x); ! 2563: } ! 2564: strconv(buf, f1, f2); ! 2565: return sizeof(int); ! 2566: } ! 2567: ! 2568: mconv(int *o, int f1, int f2) ! 2569: { ! 2570: char *buf=prbuf(); ! 2571: Node *n=(Node *)*o; ! 2572: switch(n->t){
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.