Annotation of coherent/b/bin/c/n0/cc0.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * n0/cc0.c
        !             3:  * C compiler.
        !             4:  * Syntax analyser mainline.
        !             5:  * Impure stuff.
        !             6:  */
        !             7: 
        !             8: #ifdef   vax
        !             9: #include "INC$LIB:cc0.h"
        !            10: #else
        !            11: #include "cc0.h"
        !            12: #endif
        !            13: #include <path.h>
        !            14: 
        !            15: /*
        !            16:  * Impure areas.
        !            17:  * All external impure data is here
        !            18:  * and is reinitialized by the overlaid version of the mainline.
        !            19:  * This permits the compiler to be called many times if loaded as a big block.
        !            20:  */
        !            21: #if    !OVERLAID
        !            22: int    line = 1;               /* Source line */
        !            23: char   file[NFNAME];           /* Current source file name */
        !            24: char   basefile[NFNAME];       /* Original source file name */
        !            25: char   id[NCSYMB];             /* Identifier buffer */
        !            26: FILE   *ifp;                   /* Input file pointer */
        !            27: FILE   *ofp;                   /* Output file pointer */
        !            28: VARIANT        variant;                /* Variant template */
        !            29: #endif
        !            30: 
        !            31: /* Cpp variables */
        !            32: char   dbuf[NDBUF];            /* Substitution buffer */
        !            33: char   *dputp = dbuf;                  /* Define buffer pointer */
        !            34: char   *dpshp = dbuf+sizeof(dbuf);     /* Define buffer pointer */
        !            35: DSTACK dstack[NDLEV];          /* Substitution stack  */
        !            36: DSTACK *dlistp=dstack;         /* Substitution list */
        !            37: DSTACK *dstackp=dstack+NDLEV-1;        /* Input stack */
        !            38: ISTACK istack[NLEV];           /* Include stack */
        !            39: ISTACK *istackp=istack+NLEV;   /* Include stack pointer */
        !            40: CSTACK cstack[NLEV];           /* Condition stack pointer */
        !            41: CSTACK *cstackp=cstack+NLEV;   /* Condition stack pointer */
        !            42: int    cstate;                 /* Conditional state == true */
        !            43: int    ndirs;                  /* Number of include directories */
        !            44: char   *incdirs[NDIRS+3];      /* Include directory list */
        !            45: char   deftrue[]  = "1";
        !            46: char   deffalse[] = "0";
        !            47: long   curtime;                /* NB should be time_t */
        !            48: 
        !            49: int    incpp;                  /* "in a cpp control" flag */
        !            50: int    instring;               /* "in a string" flag */
        !            51: int    notskip;                /* count of not skipped chars */
        !            52: int    lastchar;               /* Last character read from a file */
        !            53: int    ininit;                 /* "in an initializer" flag */
        !            54: int    incase;                 /* "in a case" flag */
        !            55: int    nargs;                  /* # of args this function */
        !            56: SYM    *args[NARGS];           /* The args themselves */
        !            57: int    llex;                   /* Lexical level */
        !            58: int    lsym = SL_MOS;          /* Symbol table level */
        !            59: ival_t ival;                   /* Return for lex */
        !            60: lval_t lval;                   /* Return for lex */
        !            61: dval_t dval;                   /* Return for lex */
        !            62: short  tval;                   /* Return for lex int/long constant type */
        !            63: unsigned       idhash;         /* Hash number for symbol */
        !            64: unsigned       idhide;         /* Hide set for symbol */
        !            65: HIDESET        *hidefree, *hidesets;   /* Hide set management */
        !            66: int    idsize;                 /* Length of symbol */
        !            67: TOK    *tfile;                 /* Source file token */
        !            68: TOK    *idp;                   /* Hashed identifier token */
        !            69: TOK    *hash0[NHASH];          /* Hash table */
        !            70: int    cblab;                  /* Break label */
        !            71: int    cclab;                  /* Continue label */
        !            72: SBLOCK *sbp;                   /* Current switch block */
        !            73: SYM    *cfsym;                 /* Current symbol */
        !            74: int     cflab;                  /* Current return label */
        !            75: int    s;                      /* Lexical window */
        !            76: 
        !            77: /* Externals. */
        !            78: extern char *index();
        !            79: extern char *getenv();
        !            80: 
        !            81: /*
        !            82:  * It all starts here.
        !            83:  * Open the source file.
        !            84:  * Open the output stream file.
        !            85:  * Put reserved words into the symbol table.
        !            86:  * Parse externals until end of file.
        !            87:  * Finish off the output stream and exit.
        !            88:  */
        !            89: #if    OVERLAID
        !            90: /*
        !            91:  * This is the mainline of the syntax analysis phase
        !            92:  * if the compiler is being run as an overlay job.
        !            93:  */
        !            94: cc0(argc, argv) int argc; char *argv[];
        !            95: #else
        !            96: main(argc, argv) int argc; char *argv[];
        !            97: #endif
        !            98: {
        !            99:        register char   *p;
        !           100:        register int    i;
        !           101:        char *argv2;
        !           102: 
        !           103:        passname = "cc0";
        !           104: #if    OVERLAID
        !           105:        if (setjmp(death) != 0) {
        !           106:                llex = -1;
        !           107:                downlex();
        !           108:                cppfinal();
        !           109:                return ABORT;
        !           110:        }
        !           111: #if    MONOLITHIC
        !           112:        /*
        !           113:         * The impure area must be reinitialized if monolithic,
        !           114:         * because the code can be called again and again.
        !           115:         */
        !           116:        line   = 1;
        !           117:        llex = 0;
        !           118:        incpp = 0;
        !           119:        instring = 0;
        !           120:        notskip = 0;
        !           121:        lastchar = 0;
        !           122:        ininit = 0;
        !           123:        incase = 0;
        !           124:        cblab = 0;
        !           125:        cclab = 0;
        !           126:        sbp = NULL;
        !           127:        cfsym = NULL;
        !           128:        lsym = SL_MOS;
        !           129:        ndirs = 0;
        !           130:        dputp = dbuf;
        !           131:        dpshp = dbuf+sizeof(dbuf);
        !           132:        dstackp = dstack + NDLEV-1;
        !           133:        dlistp = dstack;
        !           134:        istackp = istack + NLEV;
        !           135:        cstackp = cstack + NLEV;
        !           136:        cstate = 0;
        !           137: #endif
        !           138: #else
        !           139:        if (argc < 4)
        !           140:                usage();
        !           141:        getvariant(argv[1]);
        !           142:        if (isvariant(VCPP) && strcmp(argv[2], "-") == 0)
        !           143:                ifp = stdin;
        !           144:        else if ((ifp = fopen(argv[2], "r")) == NULL) {
        !           145:                fprintf(stderr, "%s: cannot open.\n", argv[2]);
        !           146:                exit(BAD);
        !           147:        }
        !           148:        if (isvariant(VCPP)) {
        !           149:                if (strcmp(argv[3], "-") == 0)
        !           150:                        ofp = stdout;
        !           151:                else if ((ofp = fopen(argv[3], "w")) == NULL) {
        !           152:                        fprintf(stderr, "%s: cannot create.\n", argv[3]);
        !           153:                        exit(BAD);
        !           154:                }
        !           155:        } else if ((ofp=fopen(argv[3], SWMODE)) == NULL) {
        !           156:                fprintf(stderr, "%s: cannot create.\n", argv[3]);
        !           157:                exit(BAD);
        !           158:        }
        !           159: #endif
        !           160:        argv2 = new(strlen(argv[2]) + 1);
        !           161:        strcpy(argv2, argv[2]);         /* impure copy for source directory */
        !           162:        vinit();
        !           163:        kinit();
        !           164:        time(&curtime);
        !           165:        newtree(sizeof(TREE));
        !           166: 
        !           167:        /* Wired-in cpp definitions. */
        !           168:        cppd(MACHINE, deftrue);
        !           169:        cppd(SYSTEM, deftrue);
        !           170:        cppd(LOCATION, deftrue);
        !           171:        cppd(FPFORMAT, deftrue);
        !           172:        /* And again, this time ISO-compliant versions for nigel. */
        !           173:        cppd("_"  MACHINE  "__", deftrue);      /* NB MACHINE has leading '_' */
        !           174:        cppd("__" SYSTEM   "__", deftrue);
        !           175:        cppd("__" LOCATION "__", deftrue);
        !           176:        cppd("_"  FPFORMAT "__", deftrue);      /* NB FPFORMAT has leading '_' */
        !           177: 
        !           178:        cppi(argv2);                    /* source directory will be parsed later */
        !           179:        for (i=4; i<argc; ++i) {
        !           180:                if (argv[i][0] != '-')
        !           181:                        break;
        !           182:                switch (argv[i][1]) {
        !           183:                case 'I':       cppi(argv[i]+2);        break;
        !           184:                case 'U':       cppu(argv[i]+2);        break;
        !           185:                case 'D':
        !           186:                        if (p = index(argv[i]+2, '=')) {
        !           187:                                *p = '\0';
        !           188:                                cppd(argv[i]+2, p+1);
        !           189:                                *p = '=';
        !           190:                                break;
        !           191:                        } else {
        !           192:                                cppd(argv[i]+2, deftrue);
        !           193:                                break;
        !           194:                        }
        !           195:                default:
        !           196: #if    OVERLAID
        !           197:                        cbotch("cpp args");
        !           198: #else
        !           199:                        usage();
        !           200: #endif
        !           201:                }
        !           202:        }
        !           203:        if ((p = getenv("INCDIR")) == 0)
        !           204:                p = DEFDISK;
        !           205:        cppi(p);
        !           206:        cppi(argv2);            /* second copy of source directory */
        !           207:        setid(argv2);
        !           208:        setfname();
        !           209:        strncpy(basefile, idp->t_id, NFNAME);   /* save again for __BASE_FILE__ */
        !           210:        /* Now parse the source file directory */
        !           211:        i = 0;
        !           212:        for (p = argv2; *p != 0; p += 1)
        !           213:                if (*p == PATHSEP)
        !           214:                        i = p-argv2;
        !           215:        argv2[i] = '\0';
        !           216:        emptyfilep();
        !           217:        if (notvariant(VCPP)) {
        !           218:                dbfname(file);
        !           219:                setmname();
        !           220:                labgen = 0;
        !           221:                oldseg = -1;
        !           222:                while (lex() != EOF)
        !           223:                        xdef();
        !           224:                llex = -1;
        !           225:                downlex();
        !           226:                bput(FINISH);
        !           227:        } else
        !           228:                cppwork();
        !           229:        free(argv2);
        !           230: #if    OVERLAID
        !           231:        cppfinal();
        !           232:        return (nerr != 0) ? BAD : OK;
        !           233: #else
        !           234:        exit (nerr != 0) ? BAD : OK;
        !           235: #endif
        !           236: }
        !           237: 
        !           238: #if    !OVERLAID
        !           239: /*
        !           240:  * Print usage message.
        !           241:  */
        !           242: usage()
        !           243: {
        !           244:        fprintf(stderr,
        !           245:        "Usage: cc0 variant in out [-Dname[=value]] [-Idirectory] [-Uname]\n"
        !           246:        );
        !           247:        exit(BAD);
        !           248: }
        !           249: #endif
        !           250: 
        !           251: #if    OVERLAID
        !           252: cppfinal()
        !           253: {
        !           254:        register SYM *sp, **spp;
        !           255:        register int i, flag;
        !           256:        register TOK **tpp, *tp;
        !           257: 
        !           258:        /* Clean up malloc'ed TOK and SYM symbol table entries. */
        !           259:        for (i = 0; i < NHASH; ++i) {
        !           260:                for (tpp = &hash0[i]; (tp = *tpp) != NULL; ) {
        !           261:                        flag = 0;
        !           262:                        for (spp = &tp->t_sym; (sp = *spp) != NULL; ) {
        !           263:                                flag = (sp->s_slevel == SL_CPP
        !           264:                                     && (sp->s_value == XUSER || sp->s_value == XUSERA));
        !           265:                                if (flag) {
        !           266:                                        *spp = sp->s_sp;
        !           267:                                        free(sp);
        !           268:                                } else
        !           269:                                        spp = &sp->s_sp;
        !           270:                        }
        !           271:                        if (flag) {
        !           272:                                *tpp = tp->t_tp;
        !           273:                                free(tp);
        !           274:                        } else
        !           275:                                tpp = &tp->t_tp;
        !           276:                }
        !           277:                hash0[i] = NULL;
        !           278:        }
        !           279:        freetree();             /* free tree pool */
        !           280:        freehide();             /* clean up hide sets */
        !           281: }
        !           282: #endif
        !           283: 
        !           284: /*
        !           285:  * Given the file name token in idp,
        !           286:  * inform the usual parties of the change.
        !           287:  */
        !           288: setfname()
        !           289: {
        !           290:        tfile = idp;
        !           291:        strncpy(file, idp->t_id, NFNAME);
        !           292:        if (notvariant(VCPP)) {
        !           293:                bput(FNAME);
        !           294:                sput(file);
        !           295:        } else if (notvariant(VCPPE))
        !           296:                fprintf(ofp, "#line %d \"%s\"\n", line, file);
        !           297: }
        !           298: 
        !           299: /*
        !           300:  * Given a file name string,
        !           301:  * make up the associated module name.
        !           302:  * And then send it on it's way.
        !           303:  * This routine is tinkered for UDI, DEC systems, MS-DOS
        !           304:  * and for the Coherent-like systems.
        !           305:  * Of course, the MNAME item is pointless
        !           306:  * to all systems except .omf, but we do
        !           307:  * it anyway.
        !           308:  * NB, id[] is used as a buffer
        !           309:  * to construct the module name.
        !           310:  */
        !           311: setmname()
        !           312: {
        !           313:        register char *tp, *p1, *p2;
        !           314: 
        !           315:        tp = id;
        !           316:        p1 = file;
        !           317:        while (*p1 != 0)
        !           318:                ++p1;
        !           319:        p2 = p1;
        !           320:        while (p1>file
        !           321:            && (p1[-1]!=':' && p1[-1]!='/' && p1[-1]!=']' && p1[-1]!='\\'))
        !           322:                --p1;
        !           323:        while (p2>p1 && p2[0]!='.')
        !           324:                --p2;
        !           325:        while (p1 < p2)
        !           326:                *tp++ = *p1++;
        !           327:        *tp = 0;
        !           328:        bput(MNAME);
        !           329:        sput(id);
        !           330: }
        !           331: 
        !           332: /*
        !           333:  * Process an external declaration.
        !           334:  * On entry, 's' contains the first token of the external.
        !           335:  * On exit, 's' contains the last token in the declaration.
        !           336:  */
        !           337: xdef()
        !           338: {
        !           339:        register SYM    *sp;
        !           340:        SYM             *nsp;
        !           341:        DIM             *dp, *ndp;
        !           342:        INFO            *ip;
        !           343:        int             c;
        !           344:        int             t;
        !           345:        int             rf;
        !           346:        int             seg;
        !           347: 
        !           348:        if (s == SEMI)
        !           349:                return;
        !           350:        gcandt(&c, &t, &dp, &ip, &rf);
        !           351:        if (c == C_NONE)
        !           352:                c = C_GDEF;
        !           353:        else if (c == C_SIN)
        !           354:                c = C_SEX;
        !           355:        else if (c!=C_GREF && c!=C_TYPE) {
        !           356:                cerror("bad external storage class");
        !           357:                c = C_GDEF;
        !           358:        }
        !           359:        if (s == SEMI) {
        !           360:                xdropinfo(t, ip);
        !           361:                return;
        !           362:        }
        !           363:        if (t == T_NONE)
        !           364:                t = T_INT;
        !           365:        for (;;) {
        !           366:                nargs = 0;
        !           367:                if (!gdecl(&nsp, &ndp, dp, c, SL_VAR)) {
        !           368:                        cerror("external syntax");
        !           369:                        while (s!=EOF && s!=SEMI && s!=LBRACE && s!=RBRACE)
        !           370:                                skip();
        !           371:                        if (s == LBRACE)
        !           372:                                statement();
        !           373:                        break;
        !           374:                }
        !           375:                sp = nsp;
        !           376:                sp = declare(sp, c, t, ndp, ip, rf);
        !           377:                if (c!=C_GREF && sp->s_class!=C_GREF && sp->s_class!=C_TYPE) {
        !           378:                        if (isfunc(sp)) {
        !           379:                                xfunc(sp);
        !           380:                                break;
        !           381:                        }
        !           382:                        seg = SPURE;
        !           383:                        if (s==EOF || s==COMMA || s==SEMI) {
        !           384:                                if ((rf&S_RONLY) == 0)
        !           385:                                        seg = SBSS;
        !           386:                                sp->s_seg = seg;
        !           387:                                if (isvariant(VCOMM)
        !           388:                                 && sp->s_class == C_GDEF
        !           389:                                 && seg == SBSS) {
        !           390:                                        sp->s_class = C_GREF;
        !           391:                                        bput(COMM);
        !           392:                                        nput(sp->s_id);
        !           393:                                } else {
        !           394:                                        newseg(seg);
        !           395:                                        align(sp);
        !           396:                                        xlabel(sp);
        !           397:                                        bput(BLOCK);
        !           398:                                }
        !           399:                                zput(ssize(sp));
        !           400:                        } else {
        !           401:                                if ((rf&S_RONLY) == 0)
        !           402:                                        seg = SDATA;
        !           403:                                sp->s_seg = seg;
        !           404:                                newseg(seg);
        !           405:                                align(sp);
        !           406:                                xlabel(sp);
        !           407:                                /*
        !           408:                                 * The following gives a warning rather than an
        !           409:                                 * error (over steve's objection) so programs
        !           410:                                 * using old style initializers e.g. "int i 1;"
        !           411:                                 * will compile; see K&R "Anachronisms" p. 212.
        !           412:                                 */
        !           413:                                if (s != ASSIGN)
        !           414:                                        cwarn("missing '='");
        !           415:                                else
        !           416:                                        lex();
        !           417:                                init(sp, sp->s_dp, (sizeof_t)0, 1);
        !           418:                        }
        !           419:                        dbdecl(sp);
        !           420:                }
        !           421:                if (s != COMMA) {
        !           422:                        if (s != SEMI) {
        !           423:                                if (c==C_TYPE)
        !           424:                                        cerror("illegal typedef");
        !           425:                                else
        !           426:                                        cerror("missing semicolon");
        !           427:                        }
        !           428:                        break;
        !           429:                }
        !           430:                lex();
        !           431:        }
        !           432:        xdropinfo(t, ip);
        !           433: }
        !           434: 
        !           435: /*
        !           436:  * Test if the symbol pointed to by 'sp' is a function.
        !           437:  */
        !           438: isfunc(sp)
        !           439: SYM    *sp;
        !           440: {
        !           441:        register DIM    *dp;
        !           442: 
        !           443:        return ((dp=sp->s_dp)!=NULL && dp->d_type==D_FUNC);
        !           444: }
        !           445: 
        !           446: /*
        !           447:  * Compile a function.
        !           448:  * 'sp' points at the symbol table node for the function name.
        !           449:  * 's' is the first token after the function declaration.
        !           450:  */
        !           451: xfunc(sp)
        !           452: register SYM   *sp;
        !           453: {
        !           454:        register SYM    *fsp;
        !           455:        SYM             *nfsp;
        !           456:        DIM             *dp, *fdp;
        !           457:        INFO            *ip;
        !           458:        int             c;
        !           459:        int             t;
        !           460:        int             rf;
        !           461:        int             fline;
        !           462: 
        !           463:        fline = line;
        !           464:        for (;;) {
        !           465:                gcandt(&c, &t, &dp, &ip, &rf);
        !           466:                if (c==C_NONE && t==T_NONE)
        !           467:                        break;
        !           468:                if (c == C_NONE)
        !           469:                        c = C_PAUTO;
        !           470:                else if (c == C_REG)
        !           471:                        c = C_PREG;
        !           472:                else {
        !           473:                        cerror("bad argument storage class");
        !           474:                        c = C_PAUTO;
        !           475:                }
        !           476:                if (t == T_NONE)
        !           477:                        t = T_INT;
        !           478:                for (;;) {
        !           479:                        if (gdecl(&nfsp, &fdp, dp, c, SL_VAR)) {
        !           480:                                fsp = nfsp;
        !           481:                                fsp = declare(fsp, c, t, fdp, ip, rf);
        !           482:                        }
        !           483:                        if (s != COMMA)
        !           484:                                break;
        !           485:                        lex();
        !           486:                }
        !           487:                xdropinfo(t, ip);
        !           488:                mustbe(SEMI);
        !           489:        }
        !           490:        initlocals();
        !           491:        bindargs();
        !           492:        newseg(SCODE);
        !           493:        sp->s_seg = SCODE;
        !           494:        xlabel(sp);
        !           495:        bput(PROLOG);
        !           496:        loadargs();
        !           497:        dbdecl(sp);
        !           498:        dbargs();
        !           499:        dbstat(LBRACE, line);
        !           500:        cfsym = sp;
        !           501:        cflab = newlab();
        !           502:        if (s != LBRACE)
        !           503:                cerror("compound statement required");
        !           504:        else
        !           505:                lex();
        !           506:        llex = LL_AUTO;
        !           507:        locals();
        !           508:        putautos();
        !           509:        while (s!=EOF && s!=RBRACE)
        !           510:                statement();
        !           511:        if (s != RBRACE)
        !           512:                cerror("missing right brace");
        !           513:        llex = LL_EXT;
        !           514:        downlex();
        !           515:        label(cflab);
        !           516:        dbstat(RBRACE, line);
        !           517:        bput(EPILOG);
        !           518:        cfsym = NULL;
        !           519: }
        !           520: 
        !           521: /*
        !           522:  * Emit an external label.
        !           523:  */
        !           524: xlabel(sp)
        !           525: register SYM   *sp;
        !           526: {
        !           527:        bput((sp->s_class==C_GDEF) ? GLABEL : SLABEL);
        !           528:        nput(sp->s_id);
        !           529: }
        !           530: 
        !           531: /*
        !           532:  * Conditionally drop a structure information block.
        !           533:  * Sometimes a non null info pointer is a symbol table pointer!
        !           534:  */
        !           535: xdropinfo(t, ip)
        !           536: register int   t;
        !           537: register INFO  *ip;
        !           538: {
        !           539:        if (t==T_FSTRUCT || t==T_FUNION || t==T_FENUM)
        !           540:                return;
        !           541:        dropinfo(ip);
        !           542: }
        !           543: 
        !           544: /* end of n0/cc0.c */

unix.superglobalmegacorp.com

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