Annotation of researchv10dc/cmd/gre/regress.d/t6.i, revision 1.1.1.1

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){

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.