1: /*	@(#)case.c	2.3	SCCS id keyword	*/
   2: /* Copyright (c) 1979 Regents of the University of California */
   3: #
   4: /*
   5:  * pi - Pascal interpreter code translator
   6:  *
   7:  * Charles Haley, Bill Joy UCB
   8:  * Version 1.2 November 1978
   9:  */
  10: 
  11: #include "whoami"
  12: #include "0.h"
  13: #include "tree.h"
  14: #include "opcode.h"
  15: 
  16: /*
  17:  * The structure used to
  18:  * hold information about
  19:  * each case label.
  20:  */
  21: struct ct {
  22:     long    clong;
  23:     int cline;
  24: };
  25: 
  26: /*
  27:  * Caseop generates the
  28:  * pascal case statement code
  29:  */
  30: caseop(r)
  31:     int *r;
  32: {
  33:     register struct nl *p;
  34:     register struct ct *ctab;
  35:     register *cs;
  36:     int *cl;
  37:     double low, high;
  38:     short *brtab;
  39:     char *brtab0;
  40:     char *csend;
  41:     int w, i, j, m, n;
  42:     int nr, goc;
  43: 
  44:     goc = gocnt;
  45:     /*
  46: 	 * Obtain selector attributes:
  47: 	 *	p	type
  48: 	 *	w	width
  49: 	 *	low	lwb(p)
  50: 	 *	high	upb(p)
  51: 	 */
  52:     p = rvalue((int *) r[2], NLNIL);
  53:     if (p != NIL) {
  54:         if (isnta(p, "bcsi")) {
  55:             error("Case selectors cannot be %ss", nameof(p));
  56:             p = NIL;
  57:         } else {
  58:             cl = p;
  59:             if (p->class != RANGE)
  60:                 cl = p->type;
  61:             if (cl == NIL)
  62:                 p = NIL;
  63:             else {
  64:                 w = width(p);
  65: #ifdef DEBUG
  66:                 if (hp21mx)
  67:                     w = 2;
  68: #endif
  69:                 low = cl->range[0];
  70:                 high = cl->range[1];
  71:             }
  72:         }
  73:     }
  74:     /*
  75: 	 * Count # of cases
  76: 	 */
  77:     n = 0;
  78:     for (cl = r[3]; cl != NIL; cl = cl[2]) {
  79:         cs = cl[1];
  80:         if (cs == NIL)
  81:             continue;
  82:         for (cs = cs[2]; cs != NIL; cs = cs[2])
  83:             n++;
  84:     }
  85:     /*
  86: 	 * Allocate case table space
  87: 	 */
  88:     ctab = i = malloc(n * sizeof *ctab);
  89:     if (i == 0) {
  90:         error("Ran out of memory (case)");
  91:         pexit(DIED);
  92:     }
  93:     /*
  94: 	 * Check the legality of the
  95: 	 * labels and count the number
  96: 	 * of good labels
  97: 	 */
  98:     m = 0;
  99:     for (cl = r[3]; cl != NIL; cl = cl[2]) {
 100:         cs = cl[1];
 101:         if (cs == NIL)
 102:             continue;
 103:         line = cs[1];
 104:         for (cs = cs[2]; cs != NIL; cs = cs[2]) {
 105:             gconst(cs[1]);
 106:             if (p == NIL || con.ctype == NIL)
 107:                 continue;
 108:             if (incompat(con.ctype, p, NIL)) {
 109:                 cerror("Case label type clashed with case selector expression type");
 110:                 continue;
 111:             }
 112:             if (con.crval < low || con.crval > high) {
 113:                 error("Case label out of range");
 114:                 continue;
 115:             }
 116:             ctab[m].clong = con.crval;
 117:             ctab[m].cline = line;
 118:             m++;
 119:         }
 120:     }
 121: 
 122:     /*
 123: 	 * Check for duplicate labels
 124: 	 */
 125:     for (i = 0; i < m; i++)
 126:         for (j = 0; j < m; j++)
 127:             if (ctab[i].clong == ctab[j].clong) {
 128:                 if (i == j)
 129:                     continue;
 130:                 if (j < i)
 131:                     break;
 132:                 error("Multiply defined label in case, lines %d and %d", ctab[i].cline, ctab[j].cline);
 133:             }
 134:     /*
 135: 	 * Put out case operator and
 136: 	 * leave space for the
 137: 	 * branch table
 138: 	 */
 139:     if (p != NIL) {
 140:         put2(O_CASE1OP + (w >> 1), n);
 141:         brtab = brtab0 = lc;
 142:         putspace(n * 2);
 143:         put1(O_CASEBEG);
 144:         for (i=0; i<m; i++)
 145:             put( 3 , O_CASE1 + (w >> 1), ctab[i].clong);
 146:         put1(O_CASEEND);
 147:     }
 148:     csend = getlab();
 149:     put2(O_TRA, csend);
 150:     /*
 151: 	 * Free the case
 152: 	 * table space.
 153: 	 */
 154:     free(ctab);
 155:     /*
 156: 	 * Generate code for each
 157: 	 * statement. Patch branch
 158: 	 * table to beginning of each
 159: 	 * statement and follow each
 160: 	 * statement with a branch back
 161: 	 * to the TRA above.
 162: 	 */
 163:     nr = 1;
 164:     for (cl = r[3]; cl != NIL; cl = cl[2]) {
 165:         cs = cl[1];
 166:         if (cs == NIL)
 167:             continue;
 168:         if (p != NIL)
 169:             for (cs = cs[2]; cs != NIL; cs = cs[2]) {
 170:                 patchfil(brtab - 1, lc - brtab0);
 171:                 brtab++;
 172:             }
 173:         cs = cl[1];
 174:         putcnt();
 175:         level++;
 176:         statement(cs[3]);
 177:         nr &= noreach;
 178:         noreach = 0;
 179:         put2(O_TRA, csend);
 180:         level--;
 181:         if (gotos[cbn])
 182:             ungoto();
 183:     }
 184:     /*
 185: 	 * Patch the termination branch
 186: 	 */
 187:     patch(csend);
 188:     noreach = nr;
 189:     if (goc != gocnt)
 190:         putcnt();
 191: }

Defined functions

caseop defined in line 30; used 1 times

Defined struct's

ct defined in line 21; used 2 times
  • in line 34(2)
Last modified: 1981-07-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 845
Valid CSS Valid XHTML 1.0 Strict