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
Defined struct's
ct
defined in line
21; used 2 times