Commit | Line | Data |
---|---|---|
0fc6e47b KB |
1 | /*- |
2 | * Copyright (c) 1980 The Regents of the University of California. | |
3 | * All rights reserved. | |
4 | * | |
5 | * %sccs.include.redist.c% | |
252367af | 6 | */ |
dea6491f | 7 | |
72fbef68 | 8 | #ifndef lint |
0fc6e47b KB |
9 | static char sccsid[] = "@(#)type.c 5.2 (Berkeley) %G%"; |
10 | #endif /* not lint */ | |
dea6491f PK |
11 | |
12 | #include "whoami.h" | |
13 | #include "0.h" | |
14 | #include "tree.h" | |
15 | #include "objfmt.h" | |
72fbef68 | 16 | #include "tree_ty.h" |
dea6491f PK |
17 | |
18 | /* | |
19 | * Type declaration part | |
20 | */ | |
72fbef68 | 21 | /*ARGSUSED*/ |
7204688c PK |
22 | typebeg( lineofytype , r ) |
23 | int lineofytype; | |
dea6491f | 24 | { |
7204688c PK |
25 | static bool type_order = FALSE; |
26 | static bool type_seen = FALSE; | |
dea6491f PK |
27 | |
28 | /* | |
af97bcfa | 29 | * this allows for multiple |
dea6491f PK |
30 | * declaration parts unless |
31 | * standard option has been | |
32 | * specified. | |
33 | * If routine segment is being | |
34 | * compiled, do level one processing. | |
35 | */ | |
36 | ||
37 | #ifndef PI1 | |
af97bcfa PK |
38 | if (!progseen) |
39 | level1(); | |
7204688c | 40 | line = lineofytype; |
af97bcfa PK |
41 | if ( parts[ cbn ] & ( VPRT | RPRT ) ) { |
42 | if ( opt( 's' ) ) { | |
dea6491f | 43 | standard(); |
7204688c | 44 | error("Type declarations should precede var and routine declarations"); |
af97bcfa | 45 | } else { |
7204688c PK |
46 | if ( !type_order ) { |
47 | type_order = TRUE; | |
48 | warning(); | |
49 | error("Type declarations should precede var and routine declarations"); | |
50 | } | |
af97bcfa | 51 | } |
dea6491f | 52 | } |
af97bcfa PK |
53 | if (parts[ cbn ] & TPRT) { |
54 | if ( opt( 's' ) ) { | |
dea6491f | 55 | standard(); |
7204688c | 56 | error("All types should be declared in one type part"); |
af97bcfa | 57 | } else { |
7204688c PK |
58 | if ( !type_seen ) { |
59 | type_seen = TRUE; | |
60 | warning(); | |
61 | error("All types should be declared in one type part"); | |
62 | } | |
af97bcfa | 63 | } |
dea6491f | 64 | } |
af97bcfa | 65 | parts[ cbn ] |= TPRT; |
dea6491f PK |
66 | #endif |
67 | /* | |
68 | * Forechain is the head of a list of types that | |
69 | * might be self referential. We chain them up and | |
70 | * process them later. | |
71 | */ | |
72 | forechain = NIL; | |
73 | #ifdef PI0 | |
74 | send(REVTBEG); | |
75 | #endif | |
76 | } | |
77 | ||
78 | type(tline, tid, tdecl) | |
79 | int tline; | |
80 | char *tid; | |
72fbef68 | 81 | register struct tnode *tdecl; |
dea6491f PK |
82 | { |
83 | register struct nl *np; | |
9ade1e6e | 84 | struct nl *tnp; |
dea6491f PK |
85 | |
86 | np = gtype(tdecl); | |
87 | line = tline; | |
9ade1e6e | 88 | tnp = defnl(tid, TYPE, np, 0); |
dea6491f | 89 | #ifndef PI0 |
1ea9369a | 90 | enter(tnp)->nl_flags |= (char) NMOD; |
dea6491f | 91 | #else |
1ea9369a | 92 | (void) enter(tnp); |
dea6491f PK |
93 | send(REVTYPE, tline, tid, tdecl); |
94 | #endif | |
95 | ||
96 | #ifdef PC | |
b721c131 | 97 | if (cbn == 1) { |
9ade1e6e KM |
98 | stabgtype(tid, np, line); |
99 | } else { | |
100 | stabltype(tid, np); | |
b721c131 | 101 | } |
dea6491f PK |
102 | #endif PC |
103 | ||
104 | # ifdef PTREE | |
105 | { | |
106 | pPointer Type = TypeDecl( tid , tdecl ); | |
107 | pPointer *Types; | |
108 | ||
109 | pSeize( PorFHeader[ nesting ] ); | |
110 | Types = &( pDEF( PorFHeader[ nesting ] ).PorFTypes ); | |
111 | *Types = ListAppend( *Types , Type ); | |
112 | pRelease( PorFHeader[ nesting ] ); | |
113 | } | |
114 | # endif | |
115 | } | |
116 | ||
117 | typeend() | |
118 | { | |
119 | ||
120 | #ifdef PI0 | |
121 | send(REVTEND); | |
122 | #endif | |
123 | foredecl(); | |
124 | } | |
125 | \f | |
126 | /* | |
127 | * Return a type pointer (into the namelist) | |
128 | * from a parse tree for a type, building | |
129 | * namelist entries as needed. | |
130 | */ | |
131 | struct nl * | |
132 | gtype(r) | |
72fbef68 | 133 | register struct tnode *r; |
dea6491f PK |
134 | { |
135 | register struct nl *np; | |
6cbd3a07 | 136 | register int oline; |
72fbef68 | 137 | #ifdef OBJ |
6cbd3a07 | 138 | long w; |
72fbef68 | 139 | #endif |
dea6491f | 140 | |
72fbef68 RT |
141 | if (r == TR_NIL) |
142 | return (NLNIL); | |
dea6491f | 143 | oline = line; |
72fbef68 RT |
144 | if (r->tag != T_ID) |
145 | oline = line = r->lined.line_no; | |
146 | switch (r->tag) { | |
dea6491f PK |
147 | default: |
148 | panic("type"); | |
149 | case T_TYID: | |
b850626e | 150 | r = (struct tnode *) (&(r->tyid_node.line_no)); |
dea6491f | 151 | case T_ID: |
72fbef68 RT |
152 | np = lookup(r->char_const.cptr); |
153 | if (np == NLNIL) | |
dea6491f PK |
154 | break; |
155 | if (np->class != TYPE) { | |
156 | #ifndef PI1 | |
72fbef68 | 157 | error("%s is a %s, not a type as required", r->char_const.cptr, classes[np->class]); |
dea6491f | 158 | #endif |
72fbef68 | 159 | np = NLNIL; |
dea6491f PK |
160 | break; |
161 | } | |
162 | np = np->type; | |
163 | break; | |
164 | case T_TYSCAL: | |
165 | np = tyscal(r); | |
166 | break; | |
9965cdc3 KM |
167 | case T_TYCRANG: |
168 | np = tycrang(r); | |
169 | break; | |
dea6491f PK |
170 | case T_TYRANG: |
171 | np = tyrang(r); | |
172 | break; | |
173 | case T_TYPTR: | |
72fbef68 RT |
174 | np = defnl((char *) 0, PTR, NLNIL, 0 ); |
175 | np -> ptr[0] = ((struct nl *) r->ptr_ty.id_node); | |
dea6491f PK |
176 | np->nl_next = forechain; |
177 | forechain = np; | |
178 | break; | |
179 | case T_TYPACK: | |
72fbef68 | 180 | np = gtype(r->comp_ty.type); |
dea6491f | 181 | break; |
9965cdc3 | 182 | case T_TYCARY: |
dea6491f PK |
183 | case T_TYARY: |
184 | np = tyary(r); | |
185 | break; | |
186 | case T_TYREC: | |
72fbef68 | 187 | np = tyrec(r->comp_ty.type, 0); |
dea6491f PK |
188 | # ifdef PTREE |
189 | /* | |
190 | * mung T_TYREC[3] to point to the record | |
191 | * for RecTCopy | |
192 | */ | |
72fbef68 | 193 | r->comp_ty.nl_entry = np; |
dea6491f PK |
194 | # endif |
195 | break; | |
196 | case T_TYFILE: | |
72fbef68 RT |
197 | np = gtype(r->comp_ty.type); |
198 | if (np == NLNIL) | |
dea6491f PK |
199 | break; |
200 | #ifndef PI1 | |
201 | if (np->nl_flags & NFILES) | |
202 | error("Files cannot be members of files"); | |
203 | #endif | |
72fbef68 | 204 | np = defnl((char *) 0, FILET, np, 0); |
dea6491f PK |
205 | np->nl_flags |= NFILES; |
206 | break; | |
207 | case T_TYSET: | |
72fbef68 RT |
208 | np = gtype(r->comp_ty.type); |
209 | if (np == NLNIL) | |
dea6491f PK |
210 | break; |
211 | if (np->type == nl+TDOUBLE) { | |
212 | #ifndef PI1 | |
213 | error("Set of real is not allowed"); | |
214 | #endif | |
72fbef68 | 215 | np = NLNIL; |
dea6491f PK |
216 | break; |
217 | } | |
218 | if (np->class != RANGE && np->class != SCAL) { | |
219 | #ifndef PI1 | |
220 | error("Set type must be range or scalar, not %s", nameof(np)); | |
221 | #endif | |
72fbef68 | 222 | np = NLNIL; |
dea6491f PK |
223 | break; |
224 | } | |
225 | #ifndef PI1 | |
226 | if (width(np) > 2) | |
227 | error("Implementation restriction: sets must be indexed by 16 bit quantities"); | |
228 | #endif | |
72fbef68 | 229 | np = defnl((char *) 0, SET, np, 0); |
dea6491f PK |
230 | break; |
231 | } | |
232 | line = oline; | |
26e3c908 | 233 | #ifndef PC |
72fbef68 | 234 | w = lwidth(np); |
dea6491f | 235 | if (w >= TOOMUCH) { |
6cbd3a07 | 236 | error("Storage requirement of %s exceeds the implementation limit of %D by %D bytes", |
72fbef68 RT |
237 | nameof(np), (char *) (long)(TOOMUCH-1), (char *) (long)(w-TOOMUCH+1)); |
238 | np = NLNIL; | |
dea6491f | 239 | } |
26e3c908 | 240 | #endif |
dea6491f PK |
241 | return (np); |
242 | } | |
243 | ||
244 | /* | |
245 | * Scalar (enumerated) types | |
246 | */ | |
72fbef68 | 247 | struct nl * |
dea6491f | 248 | tyscal(r) |
72fbef68 | 249 | struct tnode *r; /* T_TYSCAL */ |
dea6491f PK |
250 | { |
251 | register struct nl *np, *op, *zp; | |
72fbef68 | 252 | register struct tnode *v; |
dea6491f PK |
253 | int i; |
254 | ||
72fbef68 | 255 | np = defnl((char *) 0, SCAL, NLNIL, 0); |
dea6491f | 256 | np->type = np; |
72fbef68 RT |
257 | v = r->comp_ty.type; |
258 | if (v == TR_NIL) | |
259 | return (NLNIL); | |
dea6491f PK |
260 | i = -1; |
261 | zp = np; | |
72fbef68 RT |
262 | for (; v != TR_NIL; v = v->list_node.next) { |
263 | op = enter(defnl((char *) v->list_node.list, CONST, np, ++i)); | |
dea6491f PK |
264 | #ifndef PI0 |
265 | op->nl_flags |= NMOD; | |
266 | #endif | |
267 | op->value[1] = i; | |
268 | zp->chain = op; | |
269 | zp = op; | |
270 | } | |
271 | np->range[1] = i; | |
272 | return (np); | |
273 | } | |
274 | ||
9965cdc3 KM |
275 | /* |
276 | * Declare a subrange for conformant arrays. | |
277 | */ | |
c3f40dfa | 278 | struct nl * |
9965cdc3 | 279 | tycrang(r) |
c3f40dfa | 280 | register struct tnode *r; |
9965cdc3 KM |
281 | { |
282 | register struct nl *p, *op, *tp; | |
283 | ||
284 | tp = gtype(r->crang_ty.type); | |
c3f40dfa PA |
285 | if ( tp == NLNIL ) |
286 | return (NLNIL); | |
9965cdc3 KM |
287 | /* |
288 | * Just make a new type -- the lower and upper bounds must be | |
289 | * set by params(). | |
290 | */ | |
291 | p = defnl ( 0, CRANGE, tp, 0 ); | |
292 | return(p); | |
293 | } | |
294 | ||
dea6491f PK |
295 | /* |
296 | * Declare a subrange. | |
297 | */ | |
72fbef68 | 298 | struct nl * |
dea6491f | 299 | tyrang(r) |
72fbef68 | 300 | register struct tnode *r; /* T_TYRANG */ |
dea6491f PK |
301 | { |
302 | register struct nl *lp, *hp; | |
303 | double high; | |
304 | int c, c1; | |
305 | ||
72fbef68 | 306 | gconst(r->rang_ty.const2); |
dea6491f PK |
307 | hp = con.ctype; |
308 | high = con.crval; | |
72fbef68 | 309 | gconst(r->rang_ty.const1); |
dea6491f | 310 | lp = con.ctype; |
72fbef68 RT |
311 | if (lp == NLNIL || hp == NLNIL) |
312 | return (NLNIL); | |
dea6491f | 313 | if (norange(lp) || norange(hp)) |
72fbef68 | 314 | return (NLNIL); |
dea6491f PK |
315 | c = classify(lp); |
316 | c1 = classify(hp); | |
317 | if (c != c1) { | |
318 | #ifndef PI1 | |
319 | error("Can't mix %ss and %ss in subranges", nameof(lp), nameof(hp)); | |
320 | #endif | |
72fbef68 | 321 | return (NLNIL); |
dea6491f PK |
322 | } |
323 | if (c == TSCAL && scalar(lp) != scalar(hp)) { | |
324 | #ifndef PI1 | |
325 | error("Scalar types must be identical in subranges"); | |
326 | #endif | |
72fbef68 | 327 | return (NLNIL); |
dea6491f PK |
328 | } |
329 | if (con.crval > high) { | |
330 | #ifndef PI1 | |
331 | error("Range lower bound exceeds upper bound"); | |
332 | #endif | |
72fbef68 | 333 | return (NLNIL); |
dea6491f | 334 | } |
72fbef68 | 335 | lp = defnl((char *) 0, RANGE, hp->type, 0); |
dea6491f PK |
336 | lp->range[0] = con.crval; |
337 | lp->range[1] = high; | |
338 | return (lp); | |
339 | } | |
340 | ||
341 | norange(p) | |
342 | register struct nl *p; | |
343 | { | |
344 | if (isa(p, "d")) { | |
345 | #ifndef PI1 | |
346 | error("Subrange of real is not allowed"); | |
347 | #endif | |
348 | return (1); | |
349 | } | |
350 | if (isnta(p, "bcsi")) { | |
351 | #ifndef PI1 | |
352 | error("Subrange bounds must be Boolean, character, integer or scalar, not %s", nameof(p)); | |
353 | #endif | |
354 | return (1); | |
355 | } | |
356 | return (0); | |
357 | } | |
358 | ||
359 | /* | |
360 | * Declare arrays and chain together the dimension specification | |
361 | */ | |
362 | struct nl * | |
363 | tyary(r) | |
72fbef68 | 364 | struct tnode *r; |
dea6491f PK |
365 | { |
366 | struct nl *np; | |
9965cdc3 | 367 | register struct tnode *tl, *s; |
dea6491f | 368 | register struct nl *tp, *ltp; |
9965cdc3 | 369 | int i, n; |
dea6491f | 370 | |
9965cdc3 KM |
371 | s = r; |
372 | /* Count the dimensions */ | |
373 | for (n = 0; s->tag == T_TYARY || s->tag == T_TYCARY; | |
374 | s = s->ary_ty.type, n++) | |
375 | /* NULL STATEMENT */; | |
376 | tp = gtype(s); | |
72fbef68 RT |
377 | if (tp == NLNIL) |
378 | return (NLNIL); | |
379 | np = defnl((char *) 0, ARRAY, tp, 0); | |
dea6491f PK |
380 | np->nl_flags |= (tp->nl_flags) & NFILES; |
381 | ltp = np; | |
382 | i = 0; | |
9965cdc3 KM |
383 | for (s = r; s->tag == T_TYARY || s->tag == T_TYCARY; |
384 | s = s->ary_ty.type) { | |
385 | for (tl = s->ary_ty.type_list; tl != TR_NIL; tl=tl->list_node.next){ | |
72fbef68 RT |
386 | tp = gtype(tl->list_node.list); |
387 | if (tp == NLNIL) { | |
388 | np = NLNIL; | |
dea6491f PK |
389 | continue; |
390 | } | |
9965cdc3 KM |
391 | if ((tp->class == RANGE || tp->class == CRANGE) && |
392 | tp->type == nl+TDOUBLE) { | |
dea6491f PK |
393 | #ifndef PI1 |
394 | error("Index type for arrays cannot be real"); | |
395 | #endif | |
72fbef68 | 396 | np = NLNIL; |
dea6491f PK |
397 | continue; |
398 | } | |
9965cdc3 | 399 | if (tp->class != RANGE && tp->class != SCAL && tp->class !=CRANGE){ |
dea6491f PK |
400 | #ifndef PI1 |
401 | error("Array index type is a %s, not a range or scalar as required", classes[tp->class]); | |
402 | #endif | |
72fbef68 | 403 | np = NLNIL; |
dea6491f PK |
404 | continue; |
405 | } | |
26e3c908 | 406 | #ifndef PC |
dea6491f PK |
407 | if (tp->class == RANGE && bytes(tp->range[0], tp->range[1]) > 2) { |
408 | #ifndef PI1 | |
409 | error("Value of dimension specifier too large or small for this implementation"); | |
410 | #endif | |
411 | continue; | |
412 | } | |
26e3c908 | 413 | #endif |
9965cdc3 KM |
414 | if (tp->class != CRANGE) |
415 | tp = nlcopy(tp); | |
dea6491f PK |
416 | i++; |
417 | ltp->chain = tp; | |
418 | ltp = tp; | |
9965cdc3 | 419 | } |
dea6491f | 420 | } |
72fbef68 | 421 | if (np != NLNIL) |
dea6491f PK |
422 | np->value[0] = i; |
423 | return (np); | |
424 | } | |
425 | ||
426 | /* | |
427 | * Delayed processing for pointers to | |
428 | * allow self-referential and mutually | |
429 | * recursive pointer constructs. | |
430 | */ | |
431 | foredecl() | |
432 | { | |
72fbef68 | 433 | register struct nl *p; |
dea6491f | 434 | |
72fbef68 | 435 | for (p = forechain; p != NLNIL; p = p->nl_next) { |
dea6491f PK |
436 | if (p->class == PTR && p -> ptr[0] != 0) |
437 | { | |
72fbef68 | 438 | p->type = gtype((struct tnode *) p -> ptr[0]); |
dea6491f PK |
439 | # ifdef PTREE |
440 | { | |
441 | if ( pUSE( p -> inTree ).PtrTType == pNIL ) { | |
442 | pPointer PtrTo = tCopy( p -> ptr[0] ); | |
443 | ||
444 | pDEF( p -> inTree ).PtrTType = PtrTo; | |
445 | } | |
446 | } | |
9ade1e6e KM |
447 | # endif |
448 | # ifdef PC | |
449 | fixfwdtype(p); | |
dea6491f PK |
450 | # endif |
451 | p -> ptr[0] = 0; | |
452 | } | |
453 | } | |
454 | } |