|
|
1.1 root 1: /* Copyright (c) 1979 Regents of the University of California */
2:
3: static char sccsid[] = "@(#)type.c 1.4 9/4/80";
4:
5: #include "whoami.h"
6: #include "0.h"
7: #include "tree.h"
8: #include "objfmt.h"
9:
10: /*
11: * Type declaration part
12: */
13: typebeg()
14: {
15:
16: /*
17: * this allows for multiple
18: * declaration parts unless
19: * standard option has been
20: * specified.
21: * If routine segment is being
22: * compiled, do level one processing.
23: */
24:
25: #ifndef PI1
26: if (!progseen)
27: level1();
28: if ( parts[ cbn ] & ( VPRT | RPRT ) ) {
29: if ( opt( 's' ) ) {
30: standard();
31: } else {
32: warning();
33: }
34: error("Type declarations should precede var and routine declarations");
35: }
36: if (parts[ cbn ] & TPRT) {
37: if ( opt( 's' ) ) {
38: standard();
39: } else {
40: warning();
41: }
42: error("All types should be declared in one type part");
43: }
44: parts[ cbn ] |= TPRT;
45: #endif
46: /*
47: * Forechain is the head of a list of types that
48: * might be self referential. We chain them up and
49: * process them later.
50: */
51: forechain = NIL;
52: #ifdef PI0
53: send(REVTBEG);
54: #endif
55: }
56:
57: type(tline, tid, tdecl)
58: int tline;
59: char *tid;
60: register int *tdecl;
61: {
62: register struct nl *np;
63:
64: np = gtype(tdecl);
65: line = tline;
66: #ifndef PI0
67: enter(defnl(tid, TYPE, np, 0))->nl_flags |= NMOD;
68: #else
69: enter(defnl(tid, TYPE, np, 0));
70: send(REVTYPE, tline, tid, tdecl);
71: #endif
72:
73: #ifdef PC
74: if (cbn == 1) {
75: stabgtype( tid , line );
76: }
77: #endif PC
78:
79: # ifdef PTREE
80: {
81: pPointer Type = TypeDecl( tid , tdecl );
82: pPointer *Types;
83:
84: pSeize( PorFHeader[ nesting ] );
85: Types = &( pDEF( PorFHeader[ nesting ] ).PorFTypes );
86: *Types = ListAppend( *Types , Type );
87: pRelease( PorFHeader[ nesting ] );
88: }
89: # endif
90: }
91:
92: typeend()
93: {
94:
95: #ifdef PI0
96: send(REVTEND);
97: #endif
98: foredecl();
99: }
100:
101: /*
102: * Return a type pointer (into the namelist)
103: * from a parse tree for a type, building
104: * namelist entries as needed.
105: */
106: struct nl *
107: gtype(r)
108: register int *r;
109: {
110: register struct nl *np;
111: register char *cp;
112: register int oline, w;
113:
114: if (r == NIL)
115: return (NIL);
116: oline = line;
117: if (r[0] != T_ID)
118: oline = line = r[1];
119: switch (r[0]) {
120: default:
121: panic("type");
122: case T_TYID:
123: r++;
124: case T_ID:
125: np = lookup(r[1]);
126: if (np == NIL)
127: break;
128: if (np->class != TYPE) {
129: #ifndef PI1
130: error("%s is a %s, not a type as required", r[1], classes[np->class]);
131: #endif
132: np = NIL;
133: break;
134: }
135: np = np->type;
136: break;
137: case T_TYSCAL:
138: np = tyscal(r);
139: break;
140: case T_TYRANG:
141: np = tyrang(r);
142: break;
143: case T_TYPTR:
144: np = defnl(0, PTR, 0, 0 );
145: np -> ptr[0] = r[2];
146: np->nl_next = forechain;
147: forechain = np;
148: break;
149: case T_TYPACK:
150: np = gtype(r[2]);
151: break;
152: case T_TYARY:
153: np = tyary(r);
154: break;
155: case T_TYREC:
156: np = tyrec(r[2], 0);
157: # ifdef PTREE
158: /*
159: * mung T_TYREC[3] to point to the record
160: * for RecTCopy
161: */
162: r[3] = np;
163: # endif
164: break;
165: case T_TYFILE:
166: np = gtype(r[2]);
167: if (np == NIL)
168: break;
169: #ifndef PI1
170: if (np->nl_flags & NFILES)
171: error("Files cannot be members of files");
172: #endif
173: np = defnl(0, FILET, np, 0);
174: np->nl_flags |= NFILES;
175: break;
176: case T_TYSET:
177: np = gtype(r[2]);
178: if (np == NIL)
179: break;
180: if (np->type == nl+TDOUBLE) {
181: #ifndef PI1
182: error("Set of real is not allowed");
183: #endif
184: np = NIL;
185: break;
186: }
187: if (np->class != RANGE && np->class != SCAL) {
188: #ifndef PI1
189: error("Set type must be range or scalar, not %s", nameof(np));
190: #endif
191: np = NIL;
192: break;
193: }
194: #ifndef PI1
195: if (width(np) > 2)
196: error("Implementation restriction: sets must be indexed by 16 bit quantities");
197: #endif
198: np = defnl(0, SET, np, 0);
199: break;
200: }
201: line = oline;
202: w = lwidth(np);
203: if (w >= TOOMUCH) {
204: error("Storage requirement of %s exceeds the implementation limit of %d by %d bytes",
205: nameof(np), TOOMUCH-1, w-TOOMUCH+1);
206: np = NIL;
207: }
208: return (np);
209: }
210:
211: /*
212: * Scalar (enumerated) types
213: */
214: tyscal(r)
215: int *r;
216: {
217: register struct nl *np, *op, *zp;
218: register *v;
219: int i;
220:
221: np = defnl(0, SCAL, 0, 0);
222: np->type = np;
223: v = r[2];
224: if (v == NIL)
225: return (NIL);
226: i = -1;
227: zp = np;
228: for (; v != NIL; v = v[2]) {
229: op = enter(defnl(v[1], CONST, np, ++i));
230: #ifndef PI0
231: op->nl_flags |= NMOD;
232: #endif
233: op->value[1] = i;
234: zp->chain = op;
235: zp = op;
236: }
237: np->range[1] = i;
238: return (np);
239: }
240:
241: /*
242: * Declare a subrange.
243: */
244: tyrang(r)
245: register int *r;
246: {
247: register struct nl *lp, *hp;
248: double high;
249: int c, c1;
250:
251: gconst(r[3]);
252: hp = con.ctype;
253: high = con.crval;
254: gconst(r[2]);
255: lp = con.ctype;
256: if (lp == NIL || hp == NIL)
257: return (NIL);
258: if (norange(lp) || norange(hp))
259: return (NIL);
260: c = classify(lp);
261: c1 = classify(hp);
262: if (c != c1) {
263: #ifndef PI1
264: error("Can't mix %ss and %ss in subranges", nameof(lp), nameof(hp));
265: #endif
266: return (NIL);
267: }
268: if (c == TSCAL && scalar(lp) != scalar(hp)) {
269: #ifndef PI1
270: error("Scalar types must be identical in subranges");
271: #endif
272: return (NIL);
273: }
274: if (con.crval > high) {
275: #ifndef PI1
276: error("Range lower bound exceeds upper bound");
277: #endif
278: return (NIL);
279: }
280: lp = defnl(0, RANGE, hp->type, 0);
281: lp->range[0] = con.crval;
282: lp->range[1] = high;
283: return (lp);
284: }
285:
286: norange(p)
287: register struct nl *p;
288: {
289: if (isa(p, "d")) {
290: #ifndef PI1
291: error("Subrange of real is not allowed");
292: #endif
293: return (1);
294: }
295: if (isnta(p, "bcsi")) {
296: #ifndef PI1
297: error("Subrange bounds must be Boolean, character, integer or scalar, not %s", nameof(p));
298: #endif
299: return (1);
300: }
301: return (0);
302: }
303:
304: /*
305: * Declare arrays and chain together the dimension specification
306: */
307: struct nl *
308: tyary(r)
309: int *r;
310: {
311: struct nl *np;
312: register *tl;
313: register struct nl *tp, *ltp;
314: int i;
315:
316: tp = gtype(r[3]);
317: if (tp == NIL)
318: return (NIL);
319: np = defnl(0, ARRAY, tp, 0);
320: np->nl_flags |= (tp->nl_flags) & NFILES;
321: ltp = np;
322: i = 0;
323: for (tl = r[2]; tl != NIL; tl = tl[2]) {
324: tp = gtype(tl[1]);
325: if (tp == NIL) {
326: np = NIL;
327: continue;
328: }
329: if (tp->class == RANGE && tp->type == nl+TDOUBLE) {
330: #ifndef PI1
331: error("Index type for arrays cannot be real");
332: #endif
333: np = NIL;
334: continue;
335: }
336: if (tp->class != RANGE && tp->class != SCAL) {
337: #ifndef PI1
338: error("Array index type is a %s, not a range or scalar as required", classes[tp->class]);
339: #endif
340: np = NIL;
341: continue;
342: }
343: if (tp->class == RANGE && bytes(tp->range[0], tp->range[1]) > 2) {
344: #ifndef PI1
345: error("Value of dimension specifier too large or small for this implementation");
346: #endif
347: continue;
348: }
349: tp = nlcopy(tp);
350: i++;
351: ltp->chain = tp;
352: ltp = tp;
353: }
354: if (np != NIL)
355: np->value[0] = i;
356: return (np);
357: }
358:
359: /*
360: * Delayed processing for pointers to
361: * allow self-referential and mutually
362: * recursive pointer constructs.
363: */
364: foredecl()
365: {
366: register struct nl *p, *q;
367:
368: for (p = forechain; p != NIL; p = p->nl_next) {
369: if (p->class == PTR && p -> ptr[0] != 0)
370: {
371: p->type = gtype(p -> ptr[0]);
372: #ifndef PI1
373: if (p->type != NIL && ( ( p->type )->nl_flags & NFILES))
374: error("Files cannot be members of dynamic structures");
375: #endif
376: # ifdef PTREE
377: {
378: if ( pUSE( p -> inTree ).PtrTType == pNIL ) {
379: pPointer PtrTo = tCopy( p -> ptr[0] );
380:
381: pDEF( p -> inTree ).PtrTType = PtrTo;
382: }
383: }
384: # endif
385: p -> ptr[0] = 0;
386: }
387: }
388: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.