Annotation of 43BSDReno/pgrm/pascal/src/case.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1980 Regents of the University of California.
        !             3:  * All rights reserved.  The Berkeley software License Agreement
        !             4:  * specifies the terms and conditions for redistribution.
        !             5:  */
        !             6: 
        !             7: #ifndef lint
        !             8: static char sccsid[] = "@(#)case.c     5.2 (Berkeley) 6/5/85";
        !             9: #endif not lint
        !            10: 
        !            11: #include "whoami.h"
        !            12: #include "0.h"
        !            13: #include "tree.h"
        !            14: #include "opcode.h"
        !            15: #include "tree_ty.h"
        !            16: 
        !            17: /*
        !            18:  * The structure used to
        !            19:  * hold information about
        !            20:  * each case label.
        !            21:  */
        !            22: struct ct {
        !            23:        long    clong;
        !            24:        int     cline;
        !            25: };
        !            26: 
        !            27: #ifdef OBJ
        !            28: /*
        !            29:  * Caseop generates the
        !            30:  * pascal case statement code
        !            31:  */
        !            32: caseop(rnode)
        !            33:        WHI_CAS *rnode;
        !            34: {
        !            35:        register struct nl *p;
        !            36:        register struct ct *ctab;
        !            37:        register struct tnode *cs;
        !            38:        extern char *lc;
        !            39:        double low, high;
        !            40:        short *brtab;
        !            41:        char *brtab0;
        !            42:        char *csend;
        !            43:        int w, j, m, n;
        !            44:        int goc;
        !            45:        bool nr;
        !            46: 
        !            47:        goc = gocnt;
        !            48:        /*
        !            49:         * Obtain selector attributes:
        !            50:         *      p       type
        !            51:         *      w       width
        !            52:         *      low     lwb(p)
        !            53:         *      high    upb(p)
        !            54:         */
        !            55:        p = rvalue(rnode->expr, NLNIL , RREQ );
        !            56: 
        !            57:        {
        !            58:            register struct nl  *cl;
        !            59: 
        !            60:        if (p != NLNIL) {
        !            61:                if (isnta(p, "bcsi")) {
        !            62:                        error("Case selectors cannot be %ss", nameof(p));
        !            63:                        p = NLNIL;
        !            64:                } else {
        !            65:                        cl = p;
        !            66:                        if (p->class != (char) RANGE)
        !            67:                                cl = p->type;
        !            68:                        if (cl == NLNIL)
        !            69:                                p = NLNIL;
        !            70:                        else {
        !            71:                                w = width(p);
        !            72: #ifdef DEBUG
        !            73:                                if (hp21mx)
        !            74:                                        w = 2;
        !            75: #endif
        !            76:                                low = cl->range[0];
        !            77:                                high = cl->range[1];
        !            78:                        }
        !            79:                }
        !            80:        }
        !            81:        } /* local declaration */
        !            82:        {
        !            83:            struct tnode        *cl;    /* list node */
        !            84:        /*
        !            85:         * Count # of cases
        !            86:         */
        !            87:        n = 0;
        !            88:        for (cl = rnode->stmnt_list; cl != TR_NIL;
        !            89:                cl = cl->list_node.next) {
        !            90:                cs = cl->list_node.list;;
        !            91:                if (cs == TR_NIL)
        !            92:                        continue;
        !            93:                for (cs = cs->c_stmnt.const_list; cs != TR_NIL;
        !            94:                                cs = cs->list_node.next)
        !            95:                        n++;
        !            96:        }
        !            97:        } /* local declaration */
        !            98:        /*
        !            99:         * Allocate case table space
        !           100:         */
        !           101:        {
        !           102:                char *i;
        !           103:        i = malloc((unsigned) n * sizeof *ctab);
        !           104:        if (i == 0) {
        !           105:                error("Ran out of memory (case)");
        !           106:                pexit(DIED);
        !           107:        }
        !           108:        ctab = (struct ct *) i;
        !           109:        }
        !           110:        /*
        !           111:         * Check the legality of the
        !           112:         * labels and count the number
        !           113:         * of good labels
        !           114:         */
        !           115:        {
        !           116:            register struct tnode *cl;
        !           117:        m = 0;
        !           118:        for (cl = rnode->stmnt_list; cl != TR_NIL;
        !           119:                cl = cl->list_node.next) {
        !           120:                cs = cl->list_node.list;
        !           121:                if (cs == TR_NIL)
        !           122:                        continue;
        !           123:                line = cs->c_stmnt.line_no;
        !           124:                for (cs = cs->c_stmnt.const_list; cs != TR_NIL;
        !           125:                                cs =  cs->list_node.next) {
        !           126:                        gconst(cs->list_node.list);
        !           127:                        if (p == NLNIL || con.ctype == NIL)
        !           128:                                continue;
        !           129:                        if (incompat(con.ctype, p, TR_NIL )) {
        !           130:                                cerror("Case label type clashed with case selector expression type");
        !           131:                                continue;
        !           132:                        }
        !           133:                        if (con.crval < low || con.crval > high) {
        !           134:                                error("Case label out of range");
        !           135:                                continue;
        !           136:                        }
        !           137:                        ctab[m].clong = con.crval;
        !           138:                        ctab[m].cline = line;
        !           139:                        m++;
        !           140:                }
        !           141:        }
        !           142:        } /* decl of cl */
        !           143:        {
        !           144:                register int i;
        !           145:        /*
        !           146:         * Check for duplicate labels
        !           147:         */
        !           148:        for (i = 0; i < m; i++)
        !           149:                for (j = 0; j < m; j++)
        !           150:                        if (ctab[i].clong == ctab[j].clong) {
        !           151:                                if (i == j)
        !           152:                                        continue;
        !           153:                                if (j < i)
        !           154:                                        break;
        !           155:                                error("Multiply defined label in case, lines %d and %d", (char *) ctab[i].cline, (char *) ctab[j].cline);
        !           156:                        }
        !           157:        }
        !           158:        /*
        !           159:         * Put out case operator and
        !           160:         * leave space for the
        !           161:         * branch table
        !           162:         */
        !           163:        if (p != NLNIL) {
        !           164:                (void) put(2, O_CASE1OP + (w >> 1), n);
        !           165:                brtab0 = lc;
        !           166:                brtab = ((short *) brtab0);
        !           167:                putspace(n * 2);
        !           168:                (void) put(1, O_CASEBEG);
        !           169:                {
        !           170:                    int i;
        !           171:                for (i=0; i<m; i++)
        !           172:                        if (w <= 2)
        !           173:                                (void) put(2 ,O_CASE1 + (w >> 1), (int)ctab[i].clong);
        !           174:                        else
        !           175:                                (void) put(2 ,O_CASE4, ctab[i].clong);
        !           176:                }
        !           177:                (void) put(1, O_CASEEND);
        !           178:        }
        !           179:        csend = getlab();
        !           180:        (void) put(2, O_TRA, csend);
        !           181:        /*
        !           182:         * Free the case
        !           183:         * table space.
        !           184:         */
        !           185:        free((char *) ctab);
        !           186:        /*
        !           187:         * Generate code for each
        !           188:         * statement. Patch branch
        !           189:         * table to beginning of each
        !           190:         * statement and follow each
        !           191:         * statement with a branch back
        !           192:         * to the TRA above.
        !           193:         */
        !           194:        {
        !           195:            register struct tnode *cl;
        !           196:        nr = TRUE;
        !           197:        for (cl = rnode->stmnt_list; cl != TR_NIL;
        !           198:                        cl = cl->list_node.next) {
        !           199:                cs = cl->list_node.list;
        !           200:                if (cs == TR_NIL)
        !           201:                        continue;
        !           202:                if (p != NLNIL)
        !           203:                        for (cs = cs->c_stmnt.const_list; cs != TR_NIL;
        !           204:                                cs =  cs->list_node.next) {
        !           205: #ifdef ADDR16
        !           206:                                patchfil(((char *) (brtab - 1)),
        !           207:                                        (long)(lc - brtab0), 1);
        !           208: #endif ADDR16
        !           209: #ifdef ADDR32
        !           210:                                
        !           211:                                patchfil( ((unsigned long) (brtab - 1)),
        !           212:                                        (long)(lc - brtab0), 1);
        !           213: #endif ADDR32
        !           214:                                brtab++;
        !           215:                        }
        !           216:                cs = cl->list_node.list;
        !           217:                putcnt();
        !           218:                level++;
        !           219:                statement(cs->c_stmnt.stmnt);
        !           220:                nr = (bool)(noreach && nr);
        !           221:                noreach = FALSE;
        !           222:                (void) put(2, O_TRA, csend);
        !           223:                level--;
        !           224:                if (gotos[cbn])
        !           225:                        ungoto();
        !           226:        }
        !           227:        } /* decl of cl */
        !           228:        /*
        !           229:         * Patch the termination branch
        !           230:         */
        !           231: #ifdef ADDR16
        !           232:        patch((char *) csend);
        !           233: #endif ADDR16
        !           234: #ifdef ADDR32
        !           235:        patch((unsigned long) csend);
        !           236: #endif ADDR32
        !           237:        noreach = nr;
        !           238:        if (goc != gocnt)
        !           239:                putcnt();
        !           240: }
        !           241: #endif OBJ

unix.superglobalmegacorp.com

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