BSD 4_1_snap development
[unix-history] / usr / src / cmd / efl / dcl.c
CommitLineData
9366cd74
C
1#include "defs"
2
3
4static char mess[ ] = "inconsistent attributes";
5
6attatt(a1 , a2)
7register struct atblock *a1, *a2;
8{
9#define MERGE1(x) {if(a1->x==0) a1->x = a2->x; else if(a2->x!=0 && a1->x!=a2->x) dclerr(mess,"x"+2); }
10
11MERGE1(attype);
12MERGE1(attypep);
13MERGE1(atprec);
14MERGE1(atclass);
15MERGE1(atext);
16MERGE1(atcommon);
17MERGE1(atdim);
18
19if(a1->atprec!=0 && (a1->attype==TYREAL || a1->attype==TYCOMPLEX) )
20 a1->attype += (TYLREAL-TYREAL);
21
22cfree(a2);
23}
24
25
26
27attvars(a , v)
28register struct atblock * a;
29register chainp v;
30{
31register chainp p;
32
33for(p=v; p!=0 ; p = p->nextp)
34 attvr1(a, p->datap);
35
36if(a->attype == TYFIELD)
37 cfree(a->attypep);
38else if(a->attype == TYCHAR)
39 frexpr(a->attypep);
40
41cfree(a);
42}
43
44#define MERGE(x,y) {if(v->y==0) v->y = a->x; else if(a->x!=0 && a->x!=v->y) dclerr(mess,"x"+2); }
45
46
47
48
49
50attvr1(a, v)
51register struct atblock * a;
52register struct varblock * v;
53{
54register chainp p;
55
56if(v->vdcldone)
57 {
58 dclerr("attempt to declare variable after use", v->sthead->namep);
59 return;
60 }
61v->vdclstart = 1;
62if(v->vclass == CLMOS)
63 dclerr("attempt to redefine structure member", v->sthead->namep);
64if (v->vdim == 0)
65 v->vdim = a->atdim;
66else if(!eqdim(a->atdim, v->vdim))
67 dclerr("inconsistent dimensions", v->sthead->namep);
68if(v->vprec == 0)
69 v->vprec = a->atprec;
70
71MERGE(attype,vtype);
72
73if(v->vtypep == 0)
74 {
75 if(a->attypep != 0)
76 if(a->attype == TYFIELD)
77 {
78 v->vtypep = ALLOC(fieldspec);
79 cpblock(a->attypep, v->vtypep, sizeof(struct fieldspec));
80 }
81 else if(a->attype == TYCHAR)
82 v->vtypep = cpexpr(a->attypep);
83 else v->vtypep = a->attypep;
84 else if(a->attypep!=0 && a->attypep!=v->vtypep)
85 dclerr("inconsistent attributes", "typep");
86 }
87
88if(v->vprec!=0 && (v->vtype==TYREAL || v->vtype==TYCOMPLEX) )
89 v->vtype += (TYLREAL-TYREAL);
90
91if(a->atcommon)
92 if(v->vclass != 0)
93 dclerr("common variable already in common, argument list, or external",
94 v->sthead->namep);
95 else {
96 if(blklevel != a->atcommon->blklevel)
97 dclerr("inconsistent common block usage", "");
98 for(p = &(a->atcommon->comchain) ; p->nextp!=0 ; p = p->nextp) ;
99 p->nextp = mkchain(v, PNULL);
100 }
101
102if(a->atext!=0 && v->vext==0)
103 {
104 v->vext = 1;
105 extname(v);
106 }
107else if(a->atclass == CLVALUE)
108 if(v->vclass==CLARG || v->vclass==CLVALUE)
109 v->vclass = CLVALUE;
110 else dclerr("cannot value a non-argument variable",v->sthead->namep);
111else MERGE(atclass,vclass);
112if(v->vclass==CLCOMMON || v->vclass==CLVALUE || v->vclass==CLAUTO)
113 setvproc(v, PROCNO);
114}
115
116
117
118
119
120eqdim(a,b)
121register ptr a, b;
122{
123if(a==0 || b==0 || a==b) return(1);
124
125a = a->datap;
126b = b->datap;
127
128while(a!=0 && b!=0)
129 {
130 if(!eqexpr(a->lowerb,b->lowerb) || !eqexpr(a->upperb,b->upperb))
131 return(0);
132
133 a = a->nextp;
134 b = b->nextp;
135 }
136
137return( a == b );
138}
139
140
141eqexpr(a,b)
142register ptr a, b;
143{
144if(a==b) return(1);
145if(a==0 || b==0) return(0);
146if(a->tag!=b->tag || a->subtype!=b->subtype)
147 return(0);
148
149switch(a->tag)
150 {
151case TCONST:
152 return( equals(a->leftp, b->leftp) );
153
154case TNAME:
155 return( a->sthead == b->sthead );
156
157case TLIST:
158 a = a->leftp;
159 b = b->leftp;
160
161 while(a!=0 && b!=0)
162 {
163 if(!eqexpr(a->datap,b->datap))
164 return(0);
165 a = a->nextp;
166 b = b->nextp;
167 }
168 return( a == b );
169
170case TAROP:
171case TASGNOP:
172case TLOGOP:
173case TRELOP:
174case TCALL:
175case TREPOP:
176 return(eqexpr(a->leftp,b->leftp) && eqexpr(a->rightp,b->rightp));
177
178case TNOTOP:
179case TNEGOP:
180 return(eqexpr(a->leftp,b->leftp));
181
182default:
183 badtag("eqexpr", a->tag);
184 }
185/* NOTREACHED */
186}
187
188
189
190setimpl(type, c1, c2)
191int type;
192register int c1, c2;
193{
194register int i;
195
196if(c1<'a' || c2<c1 || c2>'z')
197 dclerr("bad implicit range", CNULL);
198else if(type==TYUNDEFINED || type>TYLCOMPLEX)
199 dclerr("bad type in implicit statement", CNULL);
200else
201 for(i = c1 ; i<=c2 ; ++i)
202 impltype[i-'a'] = type;
203}
204\f
205doinits(p)
206register ptr p;
207{
208register ptr q;
209
210for( ; p ; p = p->nextp)
211 if( (q = p->datap)->vinit)
212 {
213 mkinit(q, q->vinit);
214 q->vinit = 0;
215 }
216}
217
218
219
220
221mkinit(v, e)
222register ptr v;
223register ptr e;
224{
225if(v->vdcldone == 0)
226 dclit(v);
227
228swii(idfile);
229
230if(v->vtype!=TYCHAR && v->vtypep)
231 dclerr("structure initialization", v->sthead->namep);
232else if(v->vdim==NULL || v->vsubs!=NULL)
233 {
234 if(e->tag==TLIST && (v->vtype==TYCOMPLEX || v->vtype==TYLCOMPLEX) )
235 e = compconst(e);
236 valinit(v, e);
237 }
238else
239 arrinit(v,e);
240
241swii(icfile);
242
243frexpr(e);
244}
245
246
247
248
249
250valinit(v, e)
251register ptr v;
252register ptr e;
253{
254static char buf[4] = "1hX";
255int vt;
256
257vt = v->vtype;
258/*check for special case of one-character initialization of
259 non-character datum
260*/
261if(vt==TYCHAR || e->vtype!=TYCHAR || !isconst(e) || strlen(e->leftp)!=1)
262 {
263 e = simple(RVAL, coerce(vt,e) );
264 if(e->tag == TERROR)
265 return;
266 if( ! isconst(e) )
267 {
268 dclerr("nonconstant initializer", v->sthead->namep);
269 return;
270 }
271 }
272if(vt == TYCHAR)
273 {
274 charinit(v, e->leftp);
275 return;
276 }
277prexpr( simple(LVAL,v) );
278putic(ICOP,OPSLASH);
279if(e->vtype != TYCHAR)
280 prexpr(e);
281else if(strlen(e->leftp) == 1)
282 {
283 buf[2] = e->leftp[0];
284 putsii(ICCONST, buf);
285 }
286else dclerr("character initialization of nonchar", v->sthead->namep);
287putic(ICOP,OPSLASH);
288putic(ICMARK,0);
289}
290
291
292
293arrinit(v, e)
294register ptr v;
295register ptr e;
296{
297struct exprblock *listinit(), *firstelt(), *nextelt();
298ptr arrsize();
299
300if(e->tag!=TLIST && e->tag!=TREPOP)
301 e = mknode(TREPOP, 0, arrsize(v), e);
302if( listinit(v, firstelt(v), e) )
303 warn("too few initializers");
304if(v->vsubs)
305 {
306 frexpr(v->vsubs);
307 v->vsubs = NULL;
308 }
309}
310
311
312
313struct exprblock *listinit(v, subs, e)
314register struct varblock *v;
315struct exprblock *subs;
316register ptr e;
317{
318struct varblock *vt;
319register chainp p;
320int n;
321struct varblock *subscript();
322struct exprblock *nextelt();
323
324switch(e->tag)
325 {
326 case TLIST:
327 for(p = e->leftp; p; p = p->nextp)
328 {
329 if(subs == NULL)
330 goto toomany;
331 subs = listinit(v, subs, p->datap);
332 }
333 return(subs);
334
335 case TREPOP:
336 if( ! isicon(e->leftp, &n) )
337 {
338 dclerr("nonconstant repetition factor");
339 return(subs);
340 }
341 while(--n >= 0)
342 {
343 if(subs == NULL)
344 goto toomany;
345 subs = listinit(v, subs, e->rightp);
346 }
347 return(subs);
348
349 default:
350 if(subs == NULL)
351 goto toomany;
352 vt = subscript(cpexpr(v), cpexpr(subs));
353 valinit(vt, e);
354 frexpr(vt);
355 return( nextelt(v,subs) );
356
357 }
358
359toomany:
360 dclerr("too many initializers", NULL);
361 return(NULL);
362}
363
364
365
366
367charinit(v,e)
368ptr v;
369char *e;
370{
371register char *bp;
372char buf[50];
373register int i, j;
374int nwd, nch;
375
376v = cpexpr(v);
377if(v->vsubs == 0)
378 v->vsubs = mknode(TLIST,0, mkchain(mkint(1),CHNULL), PNULL);
379
380nwd = ceil( nch = conval(v->vtypep) , tailor.ftnchwd);
381sprintf(buf,"%dh", tailor.ftnchwd);
382for(bp = buf ; *bp ; ++bp )
383 ;
384
385
386for(i = 0; i<nwd ; ++i)
387 {
388 if(i > 0) v->vsubs->leftp->datap =
389 mknode(TAROP,OPPLUS, v->vsubs->leftp->datap, mkint(1));
390 prexpr( v = simple(LVAL,v) );
391
392 for(j = 0 ; j<tailor.ftnchwd && *e!='\0' && nch-->0 ; )
393 bp[j++] = *e++;
394 while(j < tailor.ftnchwd)
395 {
396 bp[j++] = ' ';
397 nch--;
398 }
399 bp[j] = '\0';
400
401 putic(ICOP,OPSLASH);
402 putsii(ICCONST, buf);
403 putic(ICOP,OPSLASH);
404 putic(ICMARK,0);
405 }
406
407frexpr(v);
408}
409
410
411
412
413
414
415
416struct exprblock *firstelt(v)
417register struct varblock *v;
418{
419register struct dimblock *b;
420register chainp s;
421ptr t;
422int junk;
423
424if(v->vdim==NULL || v->vsubs!=NULL)
425 fatal("firstelt: bad argument");
426s = NULL;
427for(b = v->vdim->datap ; b; b = b->nextp)
428 {
429 t = (b->lowerb ? cpexpr(b->lowerb) : mkint(1) );
430 s = hookup(s, mkchain(t,CHNULL) );
431 if(!isicon(b->upperb,&junk) || (b->lowerb && !isicon(b->lowerb,&junk)) )
432 dclerr("attempt to initialize adjustable array",
433 v->sthead->namep);
434 }
435return( mknode(TLIST, 0, s, PNULL) );
436}
437
438
439
440
441struct exprblock *nextelt(v,subs)
442struct varblock *v;
443struct exprblock *subs;
444{
445register struct dimblock *b;
446register chainp *s;
447int sv;
448
449if(v == NULL)
450 return(NULL);
451
452b = v->vdim->datap;
453s = subs->leftp;
454
455while(b && s)
456 {
457 sv = conval(s->datap);
458 frexpr(s->datap);
459 if( sv < conval(b->upperb) )
460 {
461 s->datap =mkint(sv+1);
462 return(subs);
463 }
464 s->datap = (b->lowerb ? cpexpr(b->lowerb) : mkint(1) );
465
466 b = b->nextp;
467 s = s->nextp;
468 }
469
470if(b || s)
471 fatal("nextelt: bad subscript count");
472return(NULL);
473}