Annotation of researchv10no/cmd/PDP11/11c/c00.c, revision 1.1

1.1     ! root        1: /* C compiler
        !             2:  *
        !             3:  *
        !             4:  *
        !             5:  * Called from cc:
        !             6:  *   c0 source temp1 temp2 [ profileflag ]
        !             7:  * temp1 gets most of the intermediate code;
        !             8:  * strings are put on temp2, which c1 reads after temp1.
        !             9:  */
        !            10: 
        !            11: #include "c0.h"
        !            12: 
        !            13: int    isn     = 1;
        !            14: int    peeksym = -1;
        !            15: int    line    = 1;
        !            16: struct tnode   funcblk = { NAME };
        !            17: 
        !            18: struct kwtab {
        !            19:        char    *kwname;
        !            20:        int     kwval;
        !            21: } kwtab[] = {
        !            22:        "int",          INT,
        !            23:        "char",         CHAR,
        !            24:        "float",        FLOAT,
        !            25:        "double",       DOUBLE,
        !            26:        "struct",       STRUCT,
        !            27:        "long",         LONG,
        !            28:        "unsigned",     UNSIGN,
        !            29:        "union",        UNION,
        !            30:        "short",        INT,
        !            31:        "void",         VOID,
        !            32:        "auto",         AUTO,
        !            33:        "extern",       EXTERN,
        !            34:        "static",       STATIC,
        !            35:        "register",     REG,
        !            36:        "goto",         GOTO,
        !            37:        "return",       RETURN,
        !            38:        "if",           IF,
        !            39:        "while",        WHILE,
        !            40:        "else",         ELSE,
        !            41:        "switch",       SWITCH,
        !            42:        "case",         CASE,
        !            43:        "break",        BREAK,
        !            44:        "continue",     CONTIN,
        !            45:        "do",           DO,
        !            46:        "default",      DEFAULT,
        !            47:        "for",          FOR,
        !            48:        "sizeof",       SIZEOF,
        !            49:        "typedef",      TYPEDEF,
        !            50:        "enum",         ENUM,
        !            51:        0,              0,
        !            52: };
        !            53: 
        !            54: union  tree *cmst[CMSIZ];
        !            55: union  tree **cp = cmst;
        !            56: 
        !            57: main(argc, argv)
        !            58: char *argv[];
        !            59: {
        !            60:        register unsigned i;
        !            61:        register struct kwtab *ip;
        !            62: 
        !            63:        if (argc>1 && strcmp(argv[1], "-u")==0) {
        !            64:                argc--;
        !            65:                argv++;
        !            66:                unscflg++;
        !            67:        }
        !            68:        if(argc<4) {
        !            69:                error("Arg count");
        !            70:                exit(1);
        !            71:        }
        !            72:        if (freopen(argv[1], "r", stdin)==NULL) {
        !            73:                error("Can't find %s", argv[1]);
        !            74:                exit(1);
        !            75:        }
        !            76:        if (freopen(argv[2], "w", stdout)==NULL || (sbufp=fopen(argv[3],"w"))==NULL) {
        !            77:                error("Can't create temp");
        !            78:                exit(1);
        !            79:        }
        !            80:        setbuf(sbufp, sbuf);
        !            81:        if (argc>4)
        !            82:                proflg++;
        !            83:        /*
        !            84:         * The hash table locations of the keywords
        !            85:         * are marked; if an identifier hashes to one of
        !            86:         * these locations, it is looked up in in the keyword
        !            87:         * table first.
        !            88:         */
        !            89:        for (ip=kwtab; ip->kwname; ip++) {
        !            90:                i = hash(ip->kwname);
        !            91:                kwhash[i/LNBPW] |= 1 << (i%LNBPW);
        !            92:        }
        !            93:        coremax = locbase = sbrk(0);
        !            94:        while(!eof)
        !            95:                extdef();
        !            96:        outcode("B", EOFC);
        !            97:        strflg++;
        !            98:        outcode("B", EOFC);
        !            99:        blkend();
        !           100:        exit(nerror!=0);
        !           101: }
        !           102: 
        !           103: /*
        !           104:  * Look up the identifier in symbuf in the symbol table.
        !           105:  * If it hashes to the same spot as a keyword, try the keyword table
        !           106:  * first.
        !           107:  * Return is a ptr to the symbol table entry.
        !           108:  */
        !           109: lookup()
        !           110: {
        !           111:        unsigned ihash;
        !           112:        register struct nmlist *rp;
        !           113:        register char *sp, *np;
        !           114: 
        !           115:        ihash = hash(symbuf);
        !           116:        if (kwhash[ihash/LNBPW] & (1 << (ihash%LNBPW)))
        !           117:                if (findkw())
        !           118:                        return(KEYW);
        !           119:        rp = hshtab[ihash];
        !           120:        while (rp) {
        !           121:                np = rp->name;
        !           122:                for (sp=symbuf; sp<symbuf+NCPS;)
        !           123:                        if (*np++ != *sp++)
        !           124:                                goto no;
        !           125:                if (mossym != (rp->hflag&FKIND))
        !           126:                        goto no;
        !           127:                csym = rp;
        !           128:                return(NAME);
        !           129:        no:
        !           130:                rp = rp->nextnm;
        !           131:        }
        !           132:        rp = (struct nmlist *)Dblock(sizeof(struct nmlist));
        !           133:        rp->nextnm = hshtab[ihash];
        !           134:        hshtab[ihash] = rp;
        !           135:        rp->hclass = 0;
        !           136:        rp->htype = 0;
        !           137:        rp->hoffset = 0;
        !           138:        rp->hsubsp = NULL;
        !           139:        rp->hstrp = NULL;
        !           140:        rp->sparent = NULL;
        !           141:        rp->hblklev = blklev;
        !           142:        rp->hflag = mossym;
        !           143:        sp = symbuf;
        !           144:        for (np=rp->name; sp<symbuf+NCPS;)
        !           145:                *np++ = *sp++;
        !           146:        csym = rp;
        !           147:        return(NAME);
        !           148: }
        !           149: 
        !           150: /*
        !           151:  * Search the keyword table.
        !           152:  */
        !           153: findkw()
        !           154: {
        !           155:        register struct kwtab *kp;
        !           156:        register char *p1, *p2;
        !           157:        char *wp;
        !           158:        int firstc;
        !           159: 
        !           160:        wp = symbuf;
        !           161:        firstc = *wp;
        !           162:        for (kp=kwtab; (p2 = kp->kwname); kp++) {
        !           163:                p1 = wp;
        !           164:                while (*p1 == *p2++)
        !           165:                        if (*p1++ == '\0') {
        !           166:                                cval = kp->kwval;
        !           167:                                return(1);
        !           168:                        }
        !           169:        }
        !           170:        *wp = firstc;
        !           171:        return(0);
        !           172: }
        !           173: 
        !           174: 
        !           175: /*
        !           176:  * Return the next symbol from the input.
        !           177:  * peeksym is a pushed-back symbol, peekc is a pushed-back
        !           178:  * character (after peeksym).
        !           179:  * mosflg means that the next symbol, if an identifier,
        !           180:  * is a member of structure or a structure tag or an enum tag
        !           181:  */
        !           182: symbol()
        !           183: {
        !           184:        register c;
        !           185:        register char *sp;
        !           186:        register tline;
        !           187: 
        !           188:        if (peeksym>=0) {
        !           189:                c = peeksym;
        !           190:                peeksym = -1;
        !           191:                if (c==NAME)
        !           192:                        mosflg = 0;
        !           193:                return(c);
        !           194:        }
        !           195:        if (peekc) {
        !           196:                c = peekc;
        !           197:                peekc = 0;
        !           198:        } else
        !           199:                if (eof)
        !           200:                        return(EOFC);
        !           201:                else
        !           202:                        c = getchar();
        !           203: loop:
        !           204:        if (c==EOF) {
        !           205:                eof++;
        !           206:                return(EOFC);
        !           207:        }
        !           208:        switch(ctab[c]) {
        !           209: 
        !           210:        case SHARP:
        !           211:                if ((c=symbol())!=CON) {
        !           212:                        error("Illegal #");
        !           213:                        return(c);
        !           214:                }
        !           215:                tline = cval;
        !           216:                while (ctab[peekc]==SPACE)
        !           217:                        peekc = getchar();
        !           218:                if (peekc=='"') {
        !           219:                        sp = filename;
        !           220:                        while ((c = mapch('"')) >= 0)
        !           221:                                *sp++ = c;
        !           222:                        *sp++ = 0;
        !           223:                        peekc = getchar();
        !           224:                }
        !           225:                if (peekc != '\n') {
        !           226:                        error("Illegal #");
        !           227:                        while (getchar()!='\n' && eof==0)
        !           228:                                ;
        !           229:                }
        !           230:                peekc = 0;
        !           231:                line = tline;
        !           232:                return(symbol());
        !           233: 
        !           234:        case NEWLN:
        !           235:                line++;
        !           236: 
        !           237:        case SPACE:
        !           238:                c = getchar();
        !           239:                goto loop;
        !           240: 
        !           241:        case PLUS:
        !           242:                return(subseq(c,PLUS,INCBEF));
        !           243: 
        !           244:        case MINUS:
        !           245:                if (subseq(c, 0, 1))
        !           246:                        return(DECBEF);
        !           247:                return(subseq('>', MINUS, ARROW));
        !           248: 
        !           249:        case ASSIGN:
        !           250:                return(subseq(c, ASSIGN, EQUAL));
        !           251: 
        !           252:        case LESS:
        !           253:                if (subseq(c,0,1))
        !           254:                        return(LSHIFT);
        !           255:                return(subseq('=',LESS,LESSEQ));
        !           256: 
        !           257:        case GREAT:
        !           258:                if (subseq(c,0,1))
        !           259:                        return(RSHIFT);
        !           260:                return(subseq('=',GREAT,GREATEQ));
        !           261: 
        !           262:        case EXCLA:
        !           263:                return(subseq('=',EXCLA,NEQUAL));
        !           264: 
        !           265:        case BSLASH:
        !           266:                if (subseq('/', 0, 1))
        !           267:                        return(MAX);
        !           268:                goto unkn;
        !           269: 
        !           270:        case DIVIDE:
        !           271:                if (subseq('\\', 0, 1))
        !           272:                        return(MIN);
        !           273:                if (subseq('*',1,0))
        !           274:                        return(DIVIDE);
        !           275:                while ((c = spnextchar()) != EOFC) {
        !           276:                        peekc = 0;
        !           277:                        if (c=='*') {
        !           278:                                if (spnextchar() == '/') {
        !           279:                                        peekc = 0;
        !           280:                                        c = getchar();
        !           281:                                        goto loop;
        !           282:                                }
        !           283:                        }
        !           284:                }
        !           285:                eof++;
        !           286:                error("Nonterminated comment");
        !           287:                return(0);
        !           288: 
        !           289:        case PERIOD:
        !           290:        case DIGIT:
        !           291:                peekc = c;
        !           292:                return(getnum());
        !           293: 
        !           294:        case DQUOTE:
        !           295:                cval = isn++;
        !           296:                return(STRING);
        !           297: 
        !           298:        case SQUOTE:
        !           299:                return(getcc());
        !           300: 
        !           301:        case LETTER:
        !           302:                sp = symbuf;
        !           303:                while(ctab[c]==LETTER || ctab[c]==DIGIT) {
        !           304:                        if (sp<symbuf+NCPS)
        !           305:                                *sp++ = c;
        !           306:                        c = getchar();
        !           307:                }
        !           308:                while(sp<symbuf+NCPS)
        !           309:                        *sp++ = '\0';
        !           310:                mossym = mosflg;
        !           311:                mosflg = 0;
        !           312:                peekc = c;
        !           313:                if ((c=lookup())==KEYW && cval==SIZEOF)
        !           314:                        c = SIZEOF;
        !           315:                return(c);
        !           316: 
        !           317:        case AND:
        !           318:                return(subseq('&', AND, LOGAND));
        !           319: 
        !           320:        case OR:
        !           321:                return(subseq('|', OR, LOGOR));
        !           322: 
        !           323:        case UNKN:
        !           324:        unkn:
        !           325:                error("Unknown character");
        !           326:                c = getchar();
        !           327:                goto loop;
        !           328: 
        !           329:        }
        !           330:        return(ctab[c]);
        !           331: }
        !           332: 
        !           333: /*
        !           334:  * Read a number.  Return kind.
        !           335:  */
        !           336: getnum()
        !           337: {
        !           338:        register char *np;
        !           339:        register c, base;
        !           340:        int expseen, sym, ndigit;
        !           341:        char *nsyn;
        !           342:        int maxdigit;
        !           343: 
        !           344:        nsyn = "Number syntax";
        !           345:        lcval = 0;
        !           346:        base = 10;
        !           347:        maxdigit = 0;
        !           348:        np = numbuf;
        !           349:        ndigit = 0;
        !           350:        sym = CON;
        !           351:        expseen = 0;
        !           352:        if ((c=spnextchar()) == '0')
        !           353:                base = 8;
        !           354:        for (;; c = getchar()) {
        !           355:                *np++ = c;
        !           356:                if (ctab[c]==DIGIT || (base==16) && ('a'<=c&&c<='f'||'A'<=c&&c<='F')) {
        !           357:                        if (base==8)
        !           358:                                lcval <<= 3;
        !           359:                        else if (base==10)
        !           360:                                lcval = ((lcval<<2) + lcval)<<1;
        !           361:                        else
        !           362:                                lcval <<= 4;
        !           363:                        if (ctab[c]==DIGIT)
        !           364:                                c -= '0';
        !           365:                        else if (c>='a')
        !           366:                                c -= 'a'-10;
        !           367:                        else
        !           368:                                c -= 'A'-10;
        !           369:                        lcval += c;
        !           370:                        ndigit++;
        !           371:                        if (c>maxdigit)
        !           372:                                maxdigit = c;
        !           373:                        continue;
        !           374:                }
        !           375:                if (c=='.') {
        !           376:                        if (base==16 || sym==FCON)
        !           377:                                error(nsyn);
        !           378:                        sym = FCON;
        !           379:                        base = 10;
        !           380:                        continue;
        !           381:                }
        !           382:                if (ndigit==0) {
        !           383:                        sym = DOT;
        !           384:                        break;
        !           385:                }
        !           386:                if ((c=='e'||c=='E') && expseen==0) {
        !           387:                        expseen++;
        !           388:                        sym = FCON;
        !           389:                        if (base==16 || maxdigit>=10)
        !           390:                                error(nsyn);
        !           391:                        base = 10;
        !           392:                        *np++ = c = getchar();
        !           393:                        if (c!='+' && c!='-' && ctab[c]!=DIGIT)
        !           394:                                break;
        !           395:                } else if (c=='x' || c=='X') {
        !           396:                        if (base!=8 || lcval!=0 || sym!=CON)
        !           397:                                error(nsyn);
        !           398:                        base = 16;
        !           399:                } else if ((c=='l' || c=='L') && sym==CON) {
        !           400:                        c = getchar();
        !           401:                        sym = LCON;
        !           402:                        break;
        !           403:                } else
        !           404:                        break;
        !           405:        }
        !           406:        peekc = c;
        !           407:        if (maxdigit >= base)
        !           408:                error(nsyn);
        !           409:        if (sym==FCON) {
        !           410:                np[-1] = 0;
        !           411:                cval = np-numbuf;
        !           412:                return(FCON);
        !           413:        }
        !           414:        if (sym==CON && (lcval<0 || lcval>MAXINT&&base==10 || (lcval>>1)>MAXINT)) {
        !           415:                sym = LCON;
        !           416:        }
        !           417:        cval = lcval;
        !           418:        return(sym);
        !           419: }
        !           420: 
        !           421: /*
        !           422:  * If the next input character is c, return b and advance.
        !           423:  * Otherwise push back the character and return a.
        !           424:  */
        !           425: subseq(c,a,b)
        !           426: {
        !           427:        if (spnextchar() != c)
        !           428:                return(a);
        !           429:        peekc = 0;
        !           430:        return(b);
        !           431: }
        !           432: 
        !           433: /*
        !           434:  * Write out a string, either in-line
        !           435:  * or in the string temp file labelled by
        !           436:  * lab.
        !           437:  */
        !           438: putstr(lab, max)
        !           439: register max;
        !           440: {
        !           441:        register int c;
        !           442: 
        !           443:        nchstr = 0;
        !           444:        if (lab) {
        !           445:                strflg++;
        !           446:                outcode("BNB", LABEL, lab, BDATA);
        !           447:                max = 10000;
        !           448:        } else
        !           449:                outcode("B", BDATA);
        !           450:        while ((c = mapch('"')) >= 0) {
        !           451:                if (nchstr < max) {
        !           452:                        nchstr++;
        !           453:                        if (nchstr%15 == 0)
        !           454:                                outcode("0B", BDATA);
        !           455:                        outcode("1N", c & 0377);
        !           456:                }
        !           457:        }
        !           458:        if (nchstr < max) {
        !           459:                nchstr++;
        !           460:                outcode("10");
        !           461:        }
        !           462:        outcode("0");
        !           463:        strflg = 0;
        !           464: }
        !           465: 
        !           466: /*
        !           467:  * read a single-quoted character constant.
        !           468:  * The routine is sensitive to the layout of
        !           469:  * characters in a word.
        !           470:  */
        !           471: getcc()
        !           472: {
        !           473:        register int c, cc;
        !           474:        register char *ccp;
        !           475:        char realc;
        !           476: 
        !           477:        cval = 0;
        !           478:        ccp = (char *)&cval;
        !           479:        cc = 0;
        !           480:        while((c=mapch('\'')) >= 0)
        !           481:                if(cc++ < LNCPW)
        !           482:                        *ccp++ = c;
        !           483:        if (cc>LNCPW)
        !           484:                error("Long character constant");
        !           485:        if (cc==1) {
        !           486:                realc = cval;
        !           487:                cval = realc;
        !           488:        }
        !           489:        return(CON);
        !           490: }
        !           491: 
        !           492: /*
        !           493:  * Read a character in a string or character constant,
        !           494:  * detecting the end of the string.
        !           495:  * It implements the escape sequences.
        !           496:  */
        !           497: mapch(ac)
        !           498: {
        !           499:        register int a, c, n;
        !           500:        static mpeek;
        !           501: 
        !           502:        c = ac;
        !           503:        if (a = mpeek)
        !           504:                mpeek = 0;
        !           505:        else
        !           506:                a = getchar();
        !           507: loop:
        !           508:        if (a==c)
        !           509:                return(-1);
        !           510:        switch(a) {
        !           511: 
        !           512:        case '\n':
        !           513:        case '\0':
        !           514:                error("Nonterminated string");
        !           515:                peekc = a;
        !           516:                return(-1);
        !           517: 
        !           518:        case '\\':
        !           519:                switch (a=getchar()) {
        !           520: 
        !           521:                case 't':
        !           522:                        return('\t');
        !           523: 
        !           524:                case 'n':
        !           525:                        return('\n');
        !           526: 
        !           527:                case 'b':
        !           528:                        return('\b');
        !           529: 
        !           530:                case 'f':
        !           531:                        return('\014');
        !           532: 
        !           533:                case 'v':
        !           534:                        return('\013');
        !           535: 
        !           536:                case '0': case '1': case '2': case '3':
        !           537:                case '4': case '5': case '6': case '7':
        !           538:                        n = 0;
        !           539:                        c = 0;
        !           540:                        while (++c<=3 && '0'<=a && a<='7') {
        !           541:                                n <<= 3;
        !           542:                                n += a-'0';
        !           543:                                a = getchar();
        !           544:                        }
        !           545:                        mpeek = a;
        !           546:                        return(n);
        !           547: 
        !           548:                case 'r':
        !           549:                        return('\r');
        !           550: 
        !           551:                case '\n':
        !           552:                        line++;
        !           553:                        a = getchar();
        !           554:                        goto loop;
        !           555:                }
        !           556:        }
        !           557:        return(a);
        !           558: }
        !           559: 
        !           560: /*
        !           561:  * Read an expression and return a pointer to its tree.
        !           562:  * It's the classical bottom-up, priority-driven scheme.
        !           563:  * The initflg prevents the parse from going past
        !           564:  * "," or ":" because those delimiters are special
        !           565:  * in initializer (and some other) expressions.
        !           566:  */
        !           567: union tree *
        !           568: tree(eflag)
        !           569: {
        !           570:        int *op, opst[SSIZE], *pp, prst[SSIZE];
        !           571:        register int andflg, o;
        !           572:        register struct nmlist *cs;
        !           573:        int p, ps, os;
        !           574:        char *svtree;
        !           575:        static struct cnode garbage = { CON, INT, (int *)NULL, (union str *)NULL, 0 };
        !           576: 
        !           577:        svtree = starttree();
        !           578:        op = opst;
        !           579:        pp = prst;
        !           580:        *op = SEOF;
        !           581:        *pp = 06;
        !           582:        andflg = 0;
        !           583: 
        !           584: advanc:
        !           585:        switch (o=symbol()) {
        !           586: 
        !           587:        case NAME:
        !           588:                cs = csym;
        !           589:                if (cs->hclass==TYPEDEF)
        !           590:                        goto atype;
        !           591:                if (cs->hclass==ENUMCON) {
        !           592:                        *cp++ = cblock(cs->hoffset);
        !           593:                        goto tand;
        !           594:                }
        !           595:                if (cs->hclass==0 && cs->htype==0)
        !           596:                        if(nextchar()=='(') {
        !           597:                                /* set function */
        !           598:                                cs->hclass = EXTERN;
        !           599:                                cs->htype = FUNC;
        !           600:                        } else {
        !           601:                                cs->hclass = STATIC;
        !           602:                                error("%.8s undefined; func. %.8s", cs->name,
        !           603:                                        funcsym?funcsym->name:"(none)");
        !           604:                        }
        !           605:                *cp++ = nblock(cs);
        !           606:                goto tand;
        !           607: 
        !           608:        case FCON:
        !           609:                *cp++ = fblock(DOUBLE, copnum(cval));
        !           610:                goto tand;
        !           611: 
        !           612:        case LCON:
        !           613:                *cp = (union tree *)Tblock(sizeof(struct lnode));
        !           614:                (*cp)->l.op = LCON;
        !           615:                (*cp)->l.type = LONG;
        !           616:                (*cp)->l.lvalue = lcval;
        !           617:                cp++;
        !           618:                goto tand;
        !           619: 
        !           620:        case CON:
        !           621:                *cp++ = cblock(cval);
        !           622:                goto tand;
        !           623: 
        !           624:        /* fake a static char array */
        !           625:        case STRING:
        !           626:                putstr(cval, 0);
        !           627:                cs = (struct nmlist *)Tblock(sizeof(struct nmlist));
        !           628:                cs->hclass = STATIC;
        !           629:                cs->hoffset = cval;
        !           630:                *cp++ = block(NAME, unscflg? ARRAY+UNCHAR:ARRAY+CHAR, &nchstr,
        !           631:                  (union str *)NULL, (union tree *)cs, TNULL);
        !           632: 
        !           633:        tand:
        !           634:                if(cp>=cmst+CMSIZ) {
        !           635:                        error("Expression overflow");
        !           636:                        exit(1);
        !           637:                }
        !           638:                if (andflg)
        !           639:                        goto syntax;
        !           640:                andflg = 1;
        !           641:                goto advanc;
        !           642: 
        !           643:        case KEYW:
        !           644:        atype:
        !           645:                if (*op != LPARN || andflg)
        !           646:                        goto syntax;
        !           647:                peeksym = o;
        !           648:                *cp++ = xprtype();
        !           649:                if ((o=symbol()) != RPARN)
        !           650:                        goto syntax;
        !           651:                o = CAST;
        !           652:                --op;
        !           653:                --pp;
        !           654:                if (*op == SIZEOF) {
        !           655:                        andflg = 1;
        !           656:                        *pp = 100;
        !           657:                        goto advanc;
        !           658:                }
        !           659:                goto oponst;
        !           660: 
        !           661:        case INCBEF:
        !           662:        case DECBEF:
        !           663:                if (andflg)
        !           664:                        o += 2;
        !           665:                goto oponst;
        !           666: 
        !           667:        case COMPL:
        !           668:        case EXCLA:
        !           669:        case SIZEOF:
        !           670:                if (andflg)
        !           671:                        goto syntax;
        !           672:                goto oponst;
        !           673: 
        !           674:        case MINUS:
        !           675:                if (!andflg)
        !           676:                        o = NEG;
        !           677:                andflg = 0;
        !           678:                goto oponst;
        !           679: 
        !           680:        case AND:
        !           681:        case TIMES:
        !           682:                if (andflg)
        !           683:                        andflg = 0;
        !           684:                else if (o==AND)
        !           685:                        o = AMPER;
        !           686:                else
        !           687:                        o = STAR;
        !           688:                goto oponst;
        !           689: 
        !           690:        case LPARN:
        !           691:                if (andflg) {
        !           692:                        o = symbol();
        !           693:                        if (o==RPARN)
        !           694:                                o = MCALL;
        !           695:                        else {
        !           696:                                peeksym = o;
        !           697:                                o = CALL;
        !           698:                                andflg = 0;
        !           699:                        }
        !           700:                }
        !           701:                goto oponst;
        !           702: 
        !           703:        case RBRACK:
        !           704:        case RPARN:
        !           705:                if (!andflg)
        !           706:                        goto syntax;
        !           707:                goto oponst;
        !           708: 
        !           709:        case DOT:
        !           710:        case ARROW:
        !           711:                mosflg = FMOS;
        !           712:                break;
        !           713: 
        !           714:        case ASSIGN:
        !           715:                if (andflg==0 && PLUS<=*op && *op<=EXOR) {
        !           716:                        o = *op-- + ASPLUS - PLUS;
        !           717:                        pp--;
        !           718:                        goto oponst;
        !           719:                }
        !           720:                break;
        !           721: 
        !           722:        }
        !           723:        /* binaries */
        !           724:        if (andflg==0)
        !           725:                goto syntax;
        !           726:        andflg = 0;
        !           727: 
        !           728: oponst:
        !           729:        p = (opdope[o]>>9) & 037;
        !           730: opon1:
        !           731:        if (o==COLON && op[0]==COLON && op[-1]==QUEST) {
        !           732:                build(*op--);
        !           733:                build(*op--);
        !           734:                pp -= 2;
        !           735:        }
        !           736:        ps = *pp;
        !           737:        if (p>ps || p==ps && (opdope[o]&RASSOC)!=0) {
        !           738:                switch (o) {
        !           739: 
        !           740:                case INCAFT:
        !           741:                case DECAFT:
        !           742:                        p = 37;
        !           743:                        break;
        !           744:                case LPARN:
        !           745:                case LBRACK:
        !           746:                case CALL:
        !           747:                        p = 04;
        !           748:                }
        !           749:                if (initflg) {
        !           750:                        if ((o==COMMA && *op!=LPARN && *op!=CALL)
        !           751:                         || (o==COLON && *op!=QUEST)) {
        !           752:                                p = 00;
        !           753:                                goto opon1;
        !           754:                        }
        !           755:                }
        !           756:                if (op >= &opst[SSIZE-1]) {
        !           757:                        error("expression overflow");
        !           758:                        exit(1);
        !           759:                }
        !           760:                *++op = o;
        !           761:                *++pp = p;
        !           762:                goto advanc;
        !           763:        }
        !           764:        --pp;
        !           765:        os = *op--;
        !           766:        if (andflg==0 && p>5 && ((opdope[o]&BINARY)==0 || o>=INCBEF&&o<=DECAFT) && opdope[os]&BINARY)
        !           767:                goto syntax;
        !           768:        switch (os) {
        !           769: 
        !           770:        case SEOF:
        !           771:                peeksym = o;
        !           772:                build(0);               /* flush conversions */
        !           773:                if (eflag)
        !           774:                        endtree(svtree);
        !           775:                return(*--cp);
        !           776: 
        !           777:        case COMMA:
        !           778:                if (*op != CALL)
        !           779:                        os = SEQNC;
        !           780:                break;
        !           781: 
        !           782:        case CALL:
        !           783:                if (o!=RPARN)
        !           784:                        goto syntax;
        !           785:                build(os);
        !           786:                goto advanc;
        !           787: 
        !           788:        case MCALL:
        !           789:                *cp++ = block(NULLOP, INT, (int *)NULL,
        !           790:                  (union str *)NULL, TNULL, TNULL);
        !           791:                os = CALL;
        !           792:                break;
        !           793: 
        !           794:        case INCBEF:
        !           795:        case INCAFT:
        !           796:        case DECBEF:
        !           797:        case DECAFT:
        !           798:                *cp++ = cblock(1);
        !           799:                break;
        !           800: 
        !           801:        case LPARN:
        !           802:                if (o!=RPARN)
        !           803:                        goto syntax;
        !           804:                goto advanc;
        !           805: 
        !           806:        case LBRACK:
        !           807:                if (o!=RBRACK)
        !           808:                        goto syntax;
        !           809:                build(LBRACK);
        !           810:                goto advanc;
        !           811:        }
        !           812:        build(os);
        !           813:        goto opon1;
        !           814: 
        !           815: syntax:
        !           816:        error("Expression syntax");
        !           817:        errflush(o);
        !           818:        if (eflag)
        !           819:                endtree(svtree);
        !           820:        return((union tree *) &garbage);
        !           821: }
        !           822: 
        !           823: union tree *
        !           824: xprtype()
        !           825: {
        !           826:        struct nmlist typer, absname;
        !           827:        int sc;
        !           828:        register union tree **scp;
        !           829: 
        !           830:        scp = cp;
        !           831:        sc = DEFXTRN;           /* will cause error if class mentioned */
        !           832:        getkeywords(&sc, &typer);
        !           833:        absname.hclass = 0;
        !           834:        absname.hblklev = blklev;
        !           835:        absname.hsubsp = NULL;
        !           836:        absname.hstrp = NULL;
        !           837:        absname.htype = 0;
        !           838:        decl1(sc, &typer, 0, &absname);
        !           839:        cp = scp;
        !           840:        return(block(ETYPE, absname.htype, absname.hsubsp,
        !           841:           absname.hstrp, TNULL, TNULL));
        !           842: }
        !           843: 
        !           844: char *
        !           845: copnum(len)
        !           846: {
        !           847:        register char *s1, *s2, *s3;
        !           848: 
        !           849:        s1 = s2 = Tblock((len+LNCPW-1) & ~(LNCPW-1));
        !           850:        s3 = numbuf;
        !           851:        while (*s2++ = *s3++)
        !           852:                ;
        !           853:        return(s1);
        !           854: }

unix.superglobalmegacorp.com

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