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