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

1.1     ! root        1: /*
        !             2:  * n0/stat.c
        !             3:  * C compiler.
        !             4:  * Statement compilation.
        !             5:  * The routines in this file compile C statements.
        !             6:  * This file also contains a number of small routines that are
        !             7:  * only used by the statement compilation code.
        !             8:  * This is the new VAX/VMS base version.
        !             9:  */
        !            10: 
        !            11: #ifdef   vax
        !            12: #include "INC$LIB:cc0.h"
        !            13: #else
        !            14: #include "cc0.h"
        !            15: #endif
        !            16: 
        !            17: /*
        !            18:  * Compile one statement.
        !            19:  * On entry, 's' contains the first symbol of the new statement.
        !            20:  * On exit, 's' contains the first token beyond the end of the statement.
        !            21:  */
        !            22: statement()
        !            23: {
        !            24:        register TREE   *tp;
        !            25:        register int    lab1, lab2;
        !            26:        TREE            *lp, *rp;
        !            27:        TREE            *itree, *ctree, *stree;
        !            28:        SBLOCK          *ssbp;
        !            29:        int             i, sclab, sblab, tt;
        !            30:        ival_t          v;
        !            31: 
        !            32: loop:
        !            33:        dbstat(s, line);
        !            34:        switch (s) {
        !            35: 
        !            36:        case EOF:
        !            37:                cerror("unexpected end of file");
        !            38:                break;
        !            39: 
        !            40:        case SEMI:
        !            41:                lex();
        !            42:                break;
        !            43: 
        !            44:        case LBRACE:
        !            45:                lex();
        !            46:                savelocals();
        !            47:                ++llex;
        !            48:                locals();
        !            49:                putautos();
        !            50:                while (s!=EOF && s!=RBRACE)
        !            51:                        statement();
        !            52:                mustbe(RBRACE);
        !            53:                --llex;
        !            54:                downlex();
        !            55:                dbstat(RBRACE, line);
        !            56:                restlocals();
        !            57:                break;
        !            58: 
        !            59:        case BREAK:
        !            60:                lex();
        !            61:                if (cblab == 0)
        !            62:                        cerror("break not in a loop");
        !            63:                jump(cblab);
        !            64:                mustbe(SEMI);
        !            65:                break;
        !            66: 
        !            67:        case CONTINUE:
        !            68:                lex();
        !            69:                if (cclab == 0)
        !            70:                        cerror("continue not in a loop");
        !            71:                jump(cclab);
        !            72:                mustbe(SEMI);
        !            73:                break;
        !            74: 
        !            75:        case CASE:
        !            76:                lex();
        !            77:                newtree(sizeof(TREE));
        !            78:                ++incase;
        !            79:                v = iconexpr();
        !            80:                --incase;
        !            81:                mustbe(COLON);
        !            82:                if (sbp == NULL)
        !            83:                        cerror("case not in a switch");
        !            84:                else
        !            85:                        newcase(v);
        !            86:                goto loop;
        !            87: 
        !            88:        case DEFAULT:
        !            89:                lex();
        !            90:                mustbe(COLON);
        !            91:                if (sbp == NULL)
        !            92:                        cerror("default label not in a switch");
        !            93:                else {
        !            94:                        if (sbp->sb_dlab != 0)
        !            95:                                cerror("only one default label allowed");
        !            96:                        sbp->sb_dlab = here();
        !            97:                }
        !            98:                goto loop;
        !            99: 
        !           100:        case GOTO:
        !           101:                lex();
        !           102:                if (s != ID) {
        !           103:                        cerror("missing label name in goto");
        !           104:                        skip();
        !           105:                } else {
        !           106:                        dogoto();
        !           107:                        lex();
        !           108:                        mustbe(SEMI);
        !           109:                }
        !           110:                break;
        !           111: 
        !           112:        case IF:
        !           113:                lex();
        !           114:                tp = pexpr();
        !           115:                truth(tp);
        !           116:                tput(FEXPR, lab1=newlab(), tp);
        !           117:                statement();
        !           118:                if (s == ELSE) {
        !           119:                        lab2 = newlab();
        !           120:                        jump(lab2);
        !           121:                        label(lab1);
        !           122:                        lex();
        !           123:                        statement();
        !           124:                        label(lab2);
        !           125:                        break;
        !           126:                }
        !           127:                label(lab1);
        !           128:                break;
        !           129: 
        !           130:        case DO:
        !           131:                sblab = cblab;
        !           132:                sclab = cclab;
        !           133:                cblab = newlab();
        !           134:                cclab = newlab();
        !           135:                lab1 = here();
        !           136:                lex();
        !           137:                statement();
        !           138:                label(cclab);
        !           139:                dbstat(s, line);
        !           140:                mustbe(WHILE);
        !           141:                tp = pexpr();
        !           142:                truth(tp);
        !           143:                tput(TEXPR, lab1, tp);
        !           144:                label(cblab);
        !           145:                mustbe(SEMI);
        !           146:                cclab = sclab;
        !           147:                cblab = sblab;
        !           148:                break;
        !           149: 
        !           150:        case WHILE:
        !           151:                sblab = cblab;
        !           152:                sclab = cclab;
        !           153:                cblab = newlab();
        !           154:                cclab = here();
        !           155:                lex();
        !           156:                tp = pexpr();
        !           157:                truth(tp);
        !           158:                tput(FEXPR, cblab, tp);
        !           159:                statement();
        !           160:                jump(cclab);
        !           161:                label(cblab);
        !           162:                cclab = sclab;
        !           163:                cblab = sblab;
        !           164:                break;
        !           165: 
        !           166:        case SWITCH:
        !           167:                lex();
        !           168:                tp = pexpr();
        !           169:                tt = tltype(tp);
        !           170:                if ((tt == T_LONG  && mytypes[T_INT]  == mytypes[T_LONG])
        !           171:                 || (tt == T_ULONG && mytypes[T_UINT] == mytypes[T_ULONG])) {
        !           172:                        if (isvariant(VSBOOK))
        !           173:                                cstrict("switch expression is long");
        !           174:                } else if (tt > T_UINT)
        !           175:                        cerror("switch of non integer");
        !           176:                if (tt != T_INT) {
        !           177:                        rp = NULL;
        !           178:                        if (tt == T_PTR)
        !           179:                                rp = bzcon(psize(tp));
        !           180:                        tp = bconvert(tp, T_INT, NULL, NULL, rp);
        !           181:                }
        !           182:                tput(SEXPR, 0, tp);
        !           183:                ssbp = sbp;
        !           184:                sbp = (SBLOCK *) new(sizeof(SBLOCK));
        !           185:                sbp->sb_dlab = 0;
        !           186:                sbp->sb_ncase = 0;
        !           187:                sblab = cblab;
        !           188:                cblab = newlab();
        !           189:                statement();
        !           190:                jump(cblab);
        !           191:                if (sbp->sb_dlab==0 && sbp->sb_ncase==0)
        !           192:                        cwarn("empty switch");
        !           193:                if (sbp->sb_dlab == 0)
        !           194:                        sbp->sb_dlab = cblab;
        !           195:                bput(SBODY);
        !           196:                iput((ival_t) sbp->sb_dlab);
        !           197:                iput((ival_t) sbp->sb_ncase);
        !           198:                for (i=0; i<sbp->sb_ncase; ++i) {
        !           199:                        iput((ival_t) sbp->sb_case[i].sc_val);
        !           200:                        iput((ival_t) sbp->sb_case[i].sc_lab);
        !           201:                }
        !           202:                label(cblab);
        !           203:                cblab = sblab;
        !           204:                free((char *) sbp);
        !           205:                sbp = ssbp;
        !           206:                break;
        !           207: 
        !           208:        case FOR:
        !           209:                lex();
        !           210:                mustbe(LPAREN);
        !           211:                newtree(sizeof(TREE));
        !           212:                itree = NULL;
        !           213:                if (s != SEMI)
        !           214:                        itree = expr();
        !           215:                mustbe(SEMI);
        !           216:                ctree = NULL;
        !           217:                if (s != SEMI) {
        !           218:                        ctree = expr();
        !           219:                        truth(ctree);
        !           220:                }
        !           221:                mustbe(SEMI);
        !           222:                stree = NULL;
        !           223:                if (s != RPAREN)
        !           224:                        stree = expr();
        !           225:                mustbe(RPAREN);
        !           226:                sblab = cblab;
        !           227:                sclab = cclab;
        !           228:                cblab = newlab();
        !           229:                cclab = newlab();
        !           230:                if (itree != NULL) {
        !           231:                        tput(EEXPR, 0, itree);
        !           232:                }
        !           233:                if (stree != NULL)
        !           234:                        jump(lab1 = newlab());
        !           235:                label(cclab);
        !           236:                if (stree != NULL) {
        !           237:                        tput(EEXPR, 0, stree);
        !           238:                        label(lab1);
        !           239:                }
        !           240:                if (ctree != NULL) {
        !           241:                        tput(FEXPR, cblab, ctree);
        !           242:                }
        !           243:                statement();
        !           244:                jump(cclab);
        !           245:                label(cblab);
        !           246:                cclab = sclab;
        !           247:                cblab = sblab;
        !           248:                break;
        !           249: 
        !           250:        case RETURN:
        !           251:                lex();
        !           252:                if (s != SEMI) {
        !           253:                        newtree(sizeof(TREE));
        !           254:                        tp = expr();
        !           255:                        if (cfsym==NULL) {
        !           256:                                cerror("return(e) not inside valid function");
        !           257:                                mustbe(SEMI);
        !           258:                                break;
        !           259:                        }
        !           260:                        lp = talloc();
        !           261:                        lp->t_op   = CONVERT;
        !           262:                        lp->t_type = cfsym->s_type;
        !           263:                        lp->t_dp   = cfsym->s_dp->d_dp;  /* Skip D_FUNC */
        !           264:                        lp->t_ip   = cfsym->s_ip;
        !           265:                        if (lp->t_dp==NULL && lp->t_type==T_VOID) {
        !           266:                                cerror("return(e) illegal in void function");
        !           267:                                mustbe(SEMI);
        !           268:                                break;
        !           269:                        }
        !           270:                        if ((tltype(lp)==T_STRUCT || tltype(tp)==T_STRUCT)
        !           271:                           && (lp->t_type!=tp->t_type||lp->t_dp!=tp->t_dp||lp->t_ip!=tp->t_ip)) {
        !           272:                                cerror("return type/function type mismatch");
        !           273:                                mustbe(SEMI);
        !           274:                                break;
        !           275:                        }
        !           276:                        if (bitcompat(tltype(lp), tltype(tp)))
        !           277:                                adjust(tp, lp->t_type, lp->t_dp, lp->t_ip);
        !           278:                        else {
        !           279:                                lp->t_lp = tp;
        !           280:                                tp = lp;
        !           281:                        }
        !           282:                        tput(REXPR, 0, tp);
        !           283:                }
        !           284:                jump(cflab);
        !           285:                mustbe(SEMI);
        !           286:                break;
        !           287: 
        !           288:        case ID:
        !           289:                if (spnextis(':')) {
        !           290:                        dolabel();
        !           291:                        lex();
        !           292:                        lex();
        !           293:                        goto loop;
        !           294:                }
        !           295: 
        !           296:        default:
        !           297:                newtree(sizeof(TREE));
        !           298:                tp = expr();
        !           299:                tput(EEXPR, 0, tp);
        !           300:                mustbe(SEMI);
        !           301:        }
        !           302: }
        !           303: 
        !           304: /*
        !           305:  * Check if the given tree can be used in a truth value context.
        !           306:  * Put out the appropriate diagnostics.
        !           307:  * What does this have to do with stat()?
        !           308:  */
        !           309: truth(tp)
        !           310: TREE   *tp;
        !           311: {
        !           312:        register int    tt, op;
        !           313: 
        !           314:        tt = tltype(tp);
        !           315:        op = tp->t_op;
        !           316:        if (tt>=T_STRUCT && tt<=T_FUNION)
        !           317:                cerror("structure or union used in truth context");
        !           318:        if (incpp)
        !           319:                return;
        !           320:        if (isvariant(VSRTVC)) {
        !           321:                if ((tt>=T_PTR && tt<=T_DOUBLE)
        !           322:                 || (op==EQ && tp->t_lp->t_type==T_DOUBLE))
        !           323:                        cstrict("risky type in truth context");
        !           324:        }
        !           325:        if (isvariant(VSCCON)) {
        !           326:                /* Catch typing error "if (i = 1) ..." for "if (i == 1)...". */
        !           327:                while (op == ASSIGN) {
        !           328:                        tp = tp->t_rp;
        !           329:                        op = tp->t_op;
        !           330:                }
        !           331:                if (op==ICON || op==LCON || op==DCON)
        !           332:                        cstrict("constant used in truth context");
        !           333:        }
        !           334: }
        !           335: 
        !           336: /*
        !           337:  * Read an expression enclosed in parentheses.
        !           338:  * Used to read the control expressions in 'if', 'do', 'while' and 'switch'.
        !           339:  */
        !           340: TREE *
        !           341: pexpr()
        !           342: {
        !           343:        register TREE   *tp;
        !           344: 
        !           345:        mustbe(LPAREN);
        !           346:        newtree(sizeof(TREE));
        !           347:        tp = expr();
        !           348:        mustbe(RPAREN);
        !           349:        return (tp);
        !           350: }
        !           351: 
        !           352: /*
        !           353:  * Labels.
        !           354:  */
        !           355: dolabel()
        !           356: {
        !           357:        register SYM    *sp;
        !           358:        register int    c;
        !           359: 
        !           360:        sp = deflookup(SL_LAB, 2);
        !           361:        c  = sp->s_class;
        !           362:        if (c==C_NONE || c==C_FREF) {
        !           363:                if (c == C_NONE)
        !           364:                        sp->s_value = newlab();
        !           365:                sp->s_class = C_LAB;
        !           366:                sp->s_dline = line;
        !           367:                label(sp->s_value);
        !           368:                dblabel(sp);
        !           369:        } else
        !           370:                cerror("illegal label \"%s\"", sp->s_id);
        !           371: }
        !           372: 
        !           373: /*
        !           374:  * The dreaded 'goto' statement.
        !           375:  */
        !           376: dogoto()
        !           377: {
        !           378:        register SYM    *sp;
        !           379:        register int    c;
        !           380: 
        !           381:        sp = deflookup(SL_LAB, 2);
        !           382:        c  = sp->s_class;
        !           383:        if (c == C_NONE) {
        !           384:                sp->s_class = C_FREF;
        !           385:                sp->s_value = newlab();
        !           386:        } else if (c!=C_LAB && c!=C_FREF)
        !           387:                cerror("identifier \"%s\" is not a label", sp->s_id);
        !           388:        jump(sp->s_value);
        !           389:        sp->s_flag |= S_USED;
        !           390: }
        !           391: 
        !           392: /*
        !           393:  * Append a new case to the current switch,
        !           394:  * adjusting the size of the switch block if necessary and possible.
        !           395:  */
        !           396: newcase(v)
        !           397: ival_t v;
        !           398: {
        !           399:        SBLOCK *ssbp;
        !           400:        register SCASE *scp, *ocp;
        !           401:        register int i;
        !           402: 
        !           403:        i = sbp->sb_ncase;
        !           404:        scp = sbp->sb_case;
        !           405:        while (--i >= 0) {
        !           406:                if (scp->sc_val == v) {
        !           407:                        cerror("duplicated case constant");
        !           408:                        return;
        !           409:                } else
        !           410:                        scp += 1;
        !           411:        }
        !           412:        i = sbp->sb_ncase;
        !           413:        scp = &sbp->sb_case[i];
        !           414:        if ((i % 32) == 0) {
        !           415:                ssbp = sbp;
        !           416:                sbp = new(sizeof(SBLOCK) + (i+32) * sizeof(SCASE));
        !           417:                sbp->sb_ncase = ssbp->sb_ncase;
        !           418:                sbp->sb_dlab = ssbp->sb_dlab;
        !           419:                scp = sbp->sb_case;
        !           420:                ocp = ssbp->sb_case;
        !           421:                while (--i >= 0) {
        !           422:                        scp->sc_val = ocp->sc_val;
        !           423:                        scp->sc_lab = ocp->sc_lab;
        !           424:                        scp += 1;
        !           425:                        ocp += 1;
        !           426:                }
        !           427:                free((char *) ssbp);
        !           428:                scp = &sbp->sb_case[sbp->sb_ncase];
        !           429:        }
        !           430:        scp->sc_val = v;
        !           431:        scp->sc_lab = here();
        !           432:        sbp->sb_ncase += 1;
        !           433: }
        !           434: 
        !           435: /* end of n0/stat.c */

unix.superglobalmegacorp.com

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