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