Annotation of coherent/d/bin/cc/c/n0/cc0.c, revision 1.1.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.