# 2.11BSD#431 - /usr/src/ucb/PORT/pascal/src/case.c

##### Functions

    caseop            X

##### struct's

    ct                X

       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

#### Defined functions

caseop defined in line 32; used 1 times

- in /usr/src/ucb/PORT/pascal/src/stat.c line 118

#### Defined variables

sccsid defined in line 8; never used

#### Defined struct's

ct defined in line 22; used 4 times

- in line 36(2), 108(2)

Last modified: 1985-06-05 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 939 |