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

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

unix.superglobalmegacorp.com

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