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