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

##### Functions

    caseop            X

##### struct's

    ct                X

       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

- in /usr/src/ucb/pascal/pi/stat.c line 103

#### 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: 638 |