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

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

unix.superglobalmegacorp.com

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