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

Defined variables

sccsid defined in line 8; never used

Defined struct's

ct defined in line 22; used 4 times
Last modified: 1985-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1306
Valid CSS Valid XHTML 1.0 Strict