xref: /csrg-svn/usr.bin/f77/pass1.tahoe/data.c (revision 43205)
1*43205Sbostic /*
2*43205Sbostic  * Copyright (c) 1980 Regents of the University of California.
3*43205Sbostic  * All rights reserved.  The Berkeley software License Agreement
4*43205Sbostic  * specifies the terms and conditions for redistribution.
5*43205Sbostic  */
6*43205Sbostic 
7*43205Sbostic #ifndef lint
8*43205Sbostic static char sccsid[] = "@(#)data.c	5.1 (Berkeley) 6/7/85";
9*43205Sbostic #endif not lint
10*43205Sbostic 
11*43205Sbostic /*
12*43205Sbostic  * data.c
13*43205Sbostic  *
14*43205Sbostic  * Routines for handling DATA statements, f77 compiler, 4.2 BSD.
15*43205Sbostic  *
16*43205Sbostic  * University of Utah CS Dept modification history:
17*43205Sbostic  *
18*43205Sbostic  * Revision 3.1  84/10/13  01:09:50  donn
19*43205Sbostic  * Installed Jerry Berkman's version; added UofU comment header.
20*43205Sbostic  *
21*43205Sbostic  */
22*43205Sbostic 
23*43205Sbostic #include "defs.h"
24*43205Sbostic #include "data.h"
25*43205Sbostic 
26*43205Sbostic 
27*43205Sbostic /*  global variables  */
28*43205Sbostic 
29*43205Sbostic flag overlapflag;
30*43205Sbostic 
31*43205Sbostic 
32*43205Sbostic 
33*43205Sbostic /*  local variables  */
34*43205Sbostic 
35*43205Sbostic LOCAL char rstatus;
36*43205Sbostic LOCAL ftnint rvalue;
37*43205Sbostic LOCAL dovars *dvlist;
38*43205Sbostic LOCAL int dataerror;
39*43205Sbostic LOCAL vallist *grvals;
40*43205Sbostic LOCAL int datafile;
41*43205Sbostic LOCAL int chkfile;
42*43205Sbostic LOCAL long base;
43*43205Sbostic 
44*43205Sbostic 
45*43205Sbostic 
46*43205Sbostic /*  Copied from expr.c  */
47*43205Sbostic 
48*43205Sbostic LOCAL letter(c)
49*43205Sbostic register int c;
50*43205Sbostic {
51*43205Sbostic if( isupper(c) )
52*43205Sbostic 	c = tolower(c);
53*43205Sbostic return(c - 'a');
54*43205Sbostic }
55*43205Sbostic 
56*43205Sbostic 
57*43205Sbostic 
58*43205Sbostic vexpr *
59*43205Sbostic cpdvalue(dp)
60*43205Sbostic vexpr *dp;
61*43205Sbostic {
62*43205Sbostic   register dvalue *p;
63*43205Sbostic 
64*43205Sbostic   if (dp->tag != DVALUE)
65*43205Sbostic     badtag("cpdvalue", dp->tag);
66*43205Sbostic 
67*43205Sbostic   p = ALLOC(Dvalue);
68*43205Sbostic   p->tag = DVALUE;
69*43205Sbostic   p->status = dp->dvalue.status;
70*43205Sbostic   p->value = dp->dvalue.value;
71*43205Sbostic 
72*43205Sbostic   return ((vexpr *) p);
73*43205Sbostic }
74*43205Sbostic 
75*43205Sbostic 
76*43205Sbostic 
77*43205Sbostic frvexpr(vp)
78*43205Sbostic register vexpr *vp;
79*43205Sbostic {
80*43205Sbostic   if (vp != NULL)
81*43205Sbostic     {
82*43205Sbostic       if (vp->tag == DNAME)
83*43205Sbostic 	free(vp->dname.repr);
84*43205Sbostic       else if (vp->tag == DEXPR)
85*43205Sbostic 	{
86*43205Sbostic 	  frvexpr(vp->dexpr.left);
87*43205Sbostic 	  frvexpr(vp->dexpr.right);
88*43205Sbostic 	}
89*43205Sbostic 
90*43205Sbostic       free((char *) vp);
91*43205Sbostic     }
92*43205Sbostic 
93*43205Sbostic   return;
94*43205Sbostic }
95*43205Sbostic 
96*43205Sbostic 
97*43205Sbostic 
98*43205Sbostic frvlist(vp)
99*43205Sbostic register vlist *vp;
100*43205Sbostic {
101*43205Sbostic   register vlist *t;
102*43205Sbostic 
103*43205Sbostic   while (vp)
104*43205Sbostic     {
105*43205Sbostic       t = vp->next;
106*43205Sbostic       frvexpr(vp->val);
107*43205Sbostic       free((char *) vp);
108*43205Sbostic       vp = t;
109*43205Sbostic     }
110*43205Sbostic 
111*43205Sbostic   return;
112*43205Sbostic }
113*43205Sbostic 
114*43205Sbostic 
115*43205Sbostic 
116*43205Sbostic frelist(ep)
117*43205Sbostic elist *ep;
118*43205Sbostic {
119*43205Sbostic   register elist *p;
120*43205Sbostic   register elist *t;
121*43205Sbostic   register aelt *ap;
122*43205Sbostic   register dolist *dp;
123*43205Sbostic 
124*43205Sbostic   p = ep;
125*43205Sbostic 
126*43205Sbostic   while (p != NULL)
127*43205Sbostic     {
128*43205Sbostic       if (p->elt->tag == SIMPLE)
129*43205Sbostic 	{
130*43205Sbostic 	  ap = (aelt *) p->elt;
131*43205Sbostic 	  frvlist(ap->subs);
132*43205Sbostic 	  if (ap->range != NULL)
133*43205Sbostic 	    {
134*43205Sbostic 	      frvexpr(ap->range->low);
135*43205Sbostic 	      frvexpr(ap->range->high);
136*43205Sbostic 	      free((char *) ap->range);
137*43205Sbostic 	    }
138*43205Sbostic 	  free((char *) ap);
139*43205Sbostic 	}
140*43205Sbostic       else
141*43205Sbostic 	{
142*43205Sbostic 	  dp = (dolist *) p->elt;
143*43205Sbostic 	  frvexpr(dp->dovar);
144*43205Sbostic 	  frvexpr(dp->init);
145*43205Sbostic 	  frvexpr(dp->limit);
146*43205Sbostic 	  frvexpr(dp->step);
147*43205Sbostic 	  frelist(dp->elts);
148*43205Sbostic 	  free((char *) dp);
149*43205Sbostic 	}
150*43205Sbostic 
151*43205Sbostic       t = p;
152*43205Sbostic       p = p->next;
153*43205Sbostic       free((char *) t);
154*43205Sbostic     }
155*43205Sbostic 
156*43205Sbostic   return;
157*43205Sbostic }
158*43205Sbostic 
159*43205Sbostic 
160*43205Sbostic 
161*43205Sbostic frvallist(vp)
162*43205Sbostic vallist *vp;
163*43205Sbostic {
164*43205Sbostic   register vallist *p;
165*43205Sbostic   register vallist *t;
166*43205Sbostic 
167*43205Sbostic   p = vp;
168*43205Sbostic   while (p != NULL)
169*43205Sbostic     {
170*43205Sbostic       frexpr((tagptr) p->value);
171*43205Sbostic       t = p;
172*43205Sbostic       p = p->next;
173*43205Sbostic       free((char *) t);
174*43205Sbostic     }
175*43205Sbostic 
176*43205Sbostic   return;
177*43205Sbostic }
178*43205Sbostic 
179*43205Sbostic 
180*43205Sbostic 
181*43205Sbostic elist *revelist(ep)
182*43205Sbostic register elist *ep;
183*43205Sbostic {
184*43205Sbostic   register elist *next;
185*43205Sbostic   register elist *t;
186*43205Sbostic 
187*43205Sbostic   if (ep != NULL)
188*43205Sbostic     {
189*43205Sbostic       next = ep->next;
190*43205Sbostic       ep->next = NULL;
191*43205Sbostic 
192*43205Sbostic       while (next)
193*43205Sbostic 	{
194*43205Sbostic 	  t = next->next;
195*43205Sbostic 	  next->next = ep;
196*43205Sbostic 	  ep = next;
197*43205Sbostic 	  next = t;
198*43205Sbostic 	}
199*43205Sbostic     }
200*43205Sbostic 
201*43205Sbostic   return (ep);
202*43205Sbostic }
203*43205Sbostic 
204*43205Sbostic 
205*43205Sbostic 
206*43205Sbostic vlist *revvlist(vp)
207*43205Sbostic vlist *vp;
208*43205Sbostic {
209*43205Sbostic   register vlist *p;
210*43205Sbostic   register vlist *next;
211*43205Sbostic   register vlist *t;
212*43205Sbostic 
213*43205Sbostic   if (vp == NULL)
214*43205Sbostic     p = NULL;
215*43205Sbostic   else
216*43205Sbostic     {
217*43205Sbostic       p = vp;
218*43205Sbostic       next = p->next;
219*43205Sbostic       p->next = NULL;
220*43205Sbostic 
221*43205Sbostic       while (next)
222*43205Sbostic 	{
223*43205Sbostic 	  t = next->next;
224*43205Sbostic 	  next->next = p;
225*43205Sbostic 	  p = next;
226*43205Sbostic 	  next = t;
227*43205Sbostic 	}
228*43205Sbostic     }
229*43205Sbostic 
230*43205Sbostic   return (p);
231*43205Sbostic }
232*43205Sbostic 
233*43205Sbostic 
234*43205Sbostic 
235*43205Sbostic vallist *
236*43205Sbostic revrvals(vp)
237*43205Sbostic vallist *vp;
238*43205Sbostic {
239*43205Sbostic   register vallist *p;
240*43205Sbostic   register vallist *next;
241*43205Sbostic   register vallist *t;
242*43205Sbostic 
243*43205Sbostic   if (vp == NULL)
244*43205Sbostic     p = NULL;
245*43205Sbostic   else
246*43205Sbostic     {
247*43205Sbostic       p = vp;
248*43205Sbostic       next = p->next;
249*43205Sbostic       p->next = NULL;
250*43205Sbostic       while (next)
251*43205Sbostic 	{
252*43205Sbostic 	  t = next->next;
253*43205Sbostic 	  next->next = p;
254*43205Sbostic 	  p = next;
255*43205Sbostic 	  next = t;
256*43205Sbostic 	}
257*43205Sbostic     }
258*43205Sbostic 
259*43205Sbostic   return (p);
260*43205Sbostic }
261*43205Sbostic 
262*43205Sbostic 
263*43205Sbostic 
264*43205Sbostic vlist *prepvexpr(tail, head)
265*43205Sbostic vlist *tail;
266*43205Sbostic vexpr *head;
267*43205Sbostic {
268*43205Sbostic   register vlist *p;
269*43205Sbostic 
270*43205Sbostic   p = ALLOC(Vlist);
271*43205Sbostic   p->next = tail;
272*43205Sbostic   p->val = head;
273*43205Sbostic 
274*43205Sbostic   return (p);
275*43205Sbostic }
276*43205Sbostic 
277*43205Sbostic 
278*43205Sbostic 
279*43205Sbostic elist *preplval(tail, head)
280*43205Sbostic elist *tail;
281*43205Sbostic delt* head;
282*43205Sbostic {
283*43205Sbostic   register elist *p;
284*43205Sbostic   p = ALLOC(Elist);
285*43205Sbostic   p->next = tail;
286*43205Sbostic   p->elt = head;
287*43205Sbostic 
288*43205Sbostic   return (p);
289*43205Sbostic }
290*43205Sbostic 
291*43205Sbostic 
292*43205Sbostic 
293*43205Sbostic delt *mkdlval(name, subs, range)
294*43205Sbostic vexpr *name;
295*43205Sbostic vlist *subs;
296*43205Sbostic rpair *range;
297*43205Sbostic {
298*43205Sbostic   static char *iscomm =" improper initialization for variable in COMMON";
299*43205Sbostic   register aelt *p;
300*43205Sbostic 
301*43205Sbostic   p = ALLOC(Aelt);
302*43205Sbostic   p->tag = SIMPLE;
303*43205Sbostic   p->var = mkname(name->dname.len, name->dname.repr);
304*43205Sbostic   if ((procclass != CLBLOCK) && (p->var->vstg == STGCOMMON))
305*43205Sbostic 	warn(iscomm);
306*43205Sbostic   p->subs = subs;
307*43205Sbostic   p->range = range;
308*43205Sbostic 
309*43205Sbostic   return ((delt *) p);
310*43205Sbostic }
311*43205Sbostic 
312*43205Sbostic 
313*43205Sbostic 
314*43205Sbostic delt *mkdatado(lvals, dovar, params)
315*43205Sbostic elist *lvals;
316*43205Sbostic vexpr *dovar;
317*43205Sbostic vlist *params;
318*43205Sbostic {
319*43205Sbostic   static char *toofew = "missing loop parameters";
320*43205Sbostic   static char *toomany = "too many loop parameters";
321*43205Sbostic 
322*43205Sbostic   register dolist *p;
323*43205Sbostic   register vlist *vp;
324*43205Sbostic   register int pcnt;
325*43205Sbostic   register dvalue *one;
326*43205Sbostic 
327*43205Sbostic   p = ALLOC(DoList);
328*43205Sbostic   p->tag = NESTED;
329*43205Sbostic   p->elts = revelist(lvals);
330*43205Sbostic   p->dovar = dovar;
331*43205Sbostic 
332*43205Sbostic   vp = params;
333*43205Sbostic   pcnt = 0;
334*43205Sbostic   while (vp)
335*43205Sbostic     {
336*43205Sbostic       pcnt++;
337*43205Sbostic       vp = vp->next;
338*43205Sbostic     }
339*43205Sbostic 
340*43205Sbostic   if (pcnt != 2 && pcnt != 3)
341*43205Sbostic     {
342*43205Sbostic       if (pcnt < 2)
343*43205Sbostic 	err(toofew);
344*43205Sbostic       else
345*43205Sbostic 	err(toomany);
346*43205Sbostic 
347*43205Sbostic       p->init = (vexpr *) ALLOC(Derror);
348*43205Sbostic       p->init->tag = DERROR;
349*43205Sbostic 
350*43205Sbostic       p->limit = (vexpr *) ALLOC(Derror);
351*43205Sbostic       p->limit->tag = DERROR;
352*43205Sbostic 
353*43205Sbostic       p->step = (vexpr *) ALLOC(Derror);
354*43205Sbostic       p->step->tag = DERROR;
355*43205Sbostic     }
356*43205Sbostic   else
357*43205Sbostic     {
358*43205Sbostic       vp = params;
359*43205Sbostic 
360*43205Sbostic       if (pcnt == 2)
361*43205Sbostic 	{
362*43205Sbostic 	  one = ALLOC(Dvalue);
363*43205Sbostic 	  one->tag = DVALUE;
364*43205Sbostic 	  one->status = NORMAL;
365*43205Sbostic 	  one->value = 1;
366*43205Sbostic 	  p->step = (vexpr *) one;
367*43205Sbostic 	}
368*43205Sbostic       else
369*43205Sbostic 	{
370*43205Sbostic 	  p->step = vp->val;
371*43205Sbostic 	  vp->val = NULL;
372*43205Sbostic 	  vp = vp->next;
373*43205Sbostic 	}
374*43205Sbostic 
375*43205Sbostic       p->limit = vp->val;
376*43205Sbostic       vp->val = NULL;
377*43205Sbostic       vp = vp->next;
378*43205Sbostic 
379*43205Sbostic       p->init = vp->val;
380*43205Sbostic       vp->val = NULL;
381*43205Sbostic     }
382*43205Sbostic 
383*43205Sbostic   frvlist(params);
384*43205Sbostic   return ((delt *) p);
385*43205Sbostic }
386*43205Sbostic 
387*43205Sbostic 
388*43205Sbostic 
389*43205Sbostic rpair *mkdrange(lb, ub)
390*43205Sbostic vexpr *lb, *ub;
391*43205Sbostic {
392*43205Sbostic   register rpair *p;
393*43205Sbostic 
394*43205Sbostic   p = ALLOC(Rpair);
395*43205Sbostic   p->low = lb;
396*43205Sbostic   p->high = ub;
397*43205Sbostic 
398*43205Sbostic   return (p);
399*43205Sbostic }
400*43205Sbostic 
401*43205Sbostic 
402*43205Sbostic 
403*43205Sbostic vallist *mkdrval(repl, val)
404*43205Sbostic vexpr *repl;
405*43205Sbostic expptr val;
406*43205Sbostic {
407*43205Sbostic   static char *badtag = "bad tag in mkdrval";
408*43205Sbostic   static char *negrepl = "negative replicator";
409*43205Sbostic   static char *zerorepl = "zero replicator";
410*43205Sbostic   static char *toobig = "replicator too large";
411*43205Sbostic   static char *nonconst = "%s is not a constant";
412*43205Sbostic 
413*43205Sbostic   register vexpr *vp;
414*43205Sbostic   register vallist *p;
415*43205Sbostic   register int status;
416*43205Sbostic   register ftnint value;
417*43205Sbostic   register int copied;
418*43205Sbostic 
419*43205Sbostic   copied = 0;
420*43205Sbostic 
421*43205Sbostic   if (repl->tag == DNAME)
422*43205Sbostic     {
423*43205Sbostic       vp = evaldname(repl);
424*43205Sbostic       copied = 1;
425*43205Sbostic     }
426*43205Sbostic   else
427*43205Sbostic     vp = repl;
428*43205Sbostic 
429*43205Sbostic   p = ALLOC(ValList);
430*43205Sbostic   p->next = NULL;
431*43205Sbostic   p->value = (Constp) val;
432*43205Sbostic 
433*43205Sbostic   if (vp->tag == DVALUE)
434*43205Sbostic     {
435*43205Sbostic       status = vp->dvalue.status;
436*43205Sbostic       value = vp->dvalue.value;
437*43205Sbostic 
438*43205Sbostic       if ((status == NORMAL && value < 0) || status == MINLESS1)
439*43205Sbostic 	{
440*43205Sbostic 	  err(negrepl);
441*43205Sbostic 	  p->status = ERRVAL;
442*43205Sbostic 	}
443*43205Sbostic       else if (status == NORMAL)
444*43205Sbostic 	{
445*43205Sbostic 	  if (value == 0)
446*43205Sbostic 	    warn(zerorepl);
447*43205Sbostic 	  p->status = NORMAL;
448*43205Sbostic 	  p->repl = value;
449*43205Sbostic 	}
450*43205Sbostic       else if (status == MAXPLUS1)
451*43205Sbostic 	{
452*43205Sbostic 	  err(toobig);
453*43205Sbostic 	  p->status = ERRVAL;
454*43205Sbostic 	}
455*43205Sbostic       else
456*43205Sbostic 	p->status = ERRVAL;
457*43205Sbostic     }
458*43205Sbostic   else if (vp->tag == DNAME)
459*43205Sbostic     {
460*43205Sbostic       errnm(nonconst, vp->dname.len, vp->dname.repr);
461*43205Sbostic       p->status = ERRVAL;
462*43205Sbostic     }
463*43205Sbostic   else if (vp->tag == DERROR)
464*43205Sbostic     p->status = ERRVAL;
465*43205Sbostic   else
466*43205Sbostic     fatal(badtag);
467*43205Sbostic 
468*43205Sbostic   if (copied) frvexpr(vp);
469*43205Sbostic   return (p);
470*43205Sbostic }
471*43205Sbostic 
472*43205Sbostic 
473*43205Sbostic 
474*43205Sbostic /*  Evicon returns the value of the integer constant  */
475*43205Sbostic /*  pointed to by token.                              */
476*43205Sbostic 
477*43205Sbostic vexpr *evicon(len, token)
478*43205Sbostic register int len;
479*43205Sbostic register char *token;
480*43205Sbostic {
481*43205Sbostic   static char *badconst = "bad integer constant";
482*43205Sbostic   static char *overflow = "integer constant too large";
483*43205Sbostic 
484*43205Sbostic   register int i;
485*43205Sbostic   register ftnint val;
486*43205Sbostic   register int digit;
487*43205Sbostic   register dvalue *p;
488*43205Sbostic 
489*43205Sbostic   if (len <= 0)
490*43205Sbostic     fatal(badconst);
491*43205Sbostic 
492*43205Sbostic   p = ALLOC(Dvalue);
493*43205Sbostic   p->tag = DVALUE;
494*43205Sbostic 
495*43205Sbostic   i = 0;
496*43205Sbostic   val = 0;
497*43205Sbostic   while (i < len)
498*43205Sbostic     {
499*43205Sbostic       if (val > MAXINT/10)
500*43205Sbostic 	{
501*43205Sbostic 	  err(overflow);
502*43205Sbostic 	  p->status = ERRVAL;
503*43205Sbostic 	  goto ret;
504*43205Sbostic 	}
505*43205Sbostic       val = 10*val;
506*43205Sbostic       digit = token[i++];
507*43205Sbostic       if (!isdigit(digit))
508*43205Sbostic 	fatal(badconst);
509*43205Sbostic       digit = digit - '0';
510*43205Sbostic       if (MAXINT - val >= digit)
511*43205Sbostic 	val = val + digit;
512*43205Sbostic       else
513*43205Sbostic 	if (i == len && MAXINT - val + 1 == digit)
514*43205Sbostic 	  {
515*43205Sbostic 	    p->status = MAXPLUS1;
516*43205Sbostic 	    goto ret;
517*43205Sbostic 	  }
518*43205Sbostic 	else
519*43205Sbostic 	  {
520*43205Sbostic 	    err(overflow);
521*43205Sbostic 	    p->status = ERRVAL;
522*43205Sbostic 	    goto ret;
523*43205Sbostic 	  }
524*43205Sbostic     }
525*43205Sbostic 
526*43205Sbostic   p->status = NORMAL;
527*43205Sbostic   p->value = val;
528*43205Sbostic 
529*43205Sbostic ret:
530*43205Sbostic   return ((vexpr *) p);
531*43205Sbostic }
532*43205Sbostic 
533*43205Sbostic 
534*43205Sbostic 
535*43205Sbostic /*  Ivaltoicon converts a dvalue into a constant block.  */
536*43205Sbostic 
537*43205Sbostic expptr ivaltoicon(vp)
538*43205Sbostic register vexpr *vp;
539*43205Sbostic {
540*43205Sbostic   static char *badtag = "bad tag in ivaltoicon";
541*43205Sbostic   static char *overflow = "integer constant too large";
542*43205Sbostic 
543*43205Sbostic   register int vs;
544*43205Sbostic   register expptr p;
545*43205Sbostic 
546*43205Sbostic   if (vp->tag == DERROR)
547*43205Sbostic     return(errnode());
548*43205Sbostic   else if (vp->tag != DVALUE)
549*43205Sbostic     fatal(badtag);
550*43205Sbostic 
551*43205Sbostic   vs = vp->dvalue.status;
552*43205Sbostic   if (vs == NORMAL)
553*43205Sbostic     p = mkintcon(vp->dvalue.value);
554*43205Sbostic   else if ((MAXINT + MININT == -1) && vs == MINLESS1)
555*43205Sbostic     p = mkintcon(MININT);
556*43205Sbostic   else if (vs == MAXPLUS1 || vs == MINLESS1)
557*43205Sbostic     {
558*43205Sbostic       err(overflow);
559*43205Sbostic       p = errnode();
560*43205Sbostic     }
561*43205Sbostic   else
562*43205Sbostic     p = errnode();
563*43205Sbostic 
564*43205Sbostic   return (p);
565*43205Sbostic }
566*43205Sbostic 
567*43205Sbostic 
568*43205Sbostic 
569*43205Sbostic /*  Mkdname stores an identifier as a dname  */
570*43205Sbostic 
571*43205Sbostic vexpr *mkdname(len, str)
572*43205Sbostic int len;
573*43205Sbostic register char *str;
574*43205Sbostic {
575*43205Sbostic   register dname *p;
576*43205Sbostic   register int i;
577*43205Sbostic   register char *s;
578*43205Sbostic 
579*43205Sbostic   s = (char *) ckalloc(len + 1);
580*43205Sbostic   i = len;
581*43205Sbostic   s[i] = '\0';
582*43205Sbostic 
583*43205Sbostic   while (--i >= 0)
584*43205Sbostic     s[i] = str[i];
585*43205Sbostic 
586*43205Sbostic   p = ALLOC(Dname);
587*43205Sbostic   p->tag = DNAME;
588*43205Sbostic   p->len = len;
589*43205Sbostic   p->repr = s;
590*43205Sbostic 
591*43205Sbostic   return ((vexpr *) p);
592*43205Sbostic }
593*43205Sbostic 
594*43205Sbostic 
595*43205Sbostic 
596*43205Sbostic /*  Getname gets the symbol table information associated with  */
597*43205Sbostic /*  a name.  Getname differs from mkname in that it will not   */
598*43205Sbostic /*  add the name to the symbol table if it is not already      */
599*43205Sbostic /*  present.                                                   */
600*43205Sbostic 
601*43205Sbostic Namep getname(l, s)
602*43205Sbostic int l;
603*43205Sbostic register char *s;
604*43205Sbostic {
605*43205Sbostic   struct Hashentry *hp;
606*43205Sbostic   int hash;
607*43205Sbostic   register Namep q;
608*43205Sbostic   register int i;
609*43205Sbostic   char n[VL];
610*43205Sbostic 
611*43205Sbostic   hash = 0;
612*43205Sbostic   for (i = 0; i < l && *s != '\0'; ++i)
613*43205Sbostic     {
614*43205Sbostic       hash += *s;
615*43205Sbostic       n[i] = *s++;
616*43205Sbostic     }
617*43205Sbostic 
618*43205Sbostic   while (i < VL)
619*43205Sbostic     n[i++] = ' ';
620*43205Sbostic 
621*43205Sbostic   hash %= maxhash;
622*43205Sbostic   hp = hashtab + hash;
623*43205Sbostic 
624*43205Sbostic   while (q = hp->varp)
625*43205Sbostic     if (hash == hp->hashval
626*43205Sbostic 	&& eqn(VL, n, q->varname))
627*43205Sbostic       goto ret;
628*43205Sbostic     else if (++hp >= lasthash)
629*43205Sbostic       hp = hashtab;
630*43205Sbostic 
631*43205Sbostic ret:
632*43205Sbostic   return (q);
633*43205Sbostic }
634*43205Sbostic 
635*43205Sbostic 
636*43205Sbostic 
637*43205Sbostic /*  Evparam returns the value of the constant named by name.  */
638*43205Sbostic 
639*43205Sbostic expptr evparam(np)
640*43205Sbostic register vexpr *np;
641*43205Sbostic {
642*43205Sbostic   static char *badtag = "bad tag in evparam";
643*43205Sbostic   static char *undefined = "%s is undefined";
644*43205Sbostic   static char *nonconst = "%s is not constant";
645*43205Sbostic 
646*43205Sbostic   register struct Paramblock *tp;
647*43205Sbostic   register expptr p;
648*43205Sbostic   register int len;
649*43205Sbostic   register char *repr;
650*43205Sbostic 
651*43205Sbostic   if (np->tag != DNAME)
652*43205Sbostic     fatal(badtag);
653*43205Sbostic 
654*43205Sbostic   len = np->dname.len;
655*43205Sbostic   repr = np->dname.repr;
656*43205Sbostic 
657*43205Sbostic   tp = (struct Paramblock *) getname(len, repr);
658*43205Sbostic 
659*43205Sbostic   if (tp == NULL)
660*43205Sbostic     {
661*43205Sbostic       errnm(undefined, len, repr);
662*43205Sbostic       p = errnode();
663*43205Sbostic     }
664*43205Sbostic   else if (tp->vclass != CLPARAM || !ISCONST(tp->paramval))
665*43205Sbostic     {
666*43205Sbostic       if (tp->paramval->tag != TERROR)
667*43205Sbostic         errnm(nonconst, len, repr);
668*43205Sbostic       p = errnode();
669*43205Sbostic     }
670*43205Sbostic   else
671*43205Sbostic     p = (expptr) cpexpr(tp->paramval);
672*43205Sbostic 
673*43205Sbostic   return (p);
674*43205Sbostic }
675*43205Sbostic 
676*43205Sbostic 
677*43205Sbostic 
678*43205Sbostic vexpr *evaldname(dp)
679*43205Sbostic vexpr *dp;
680*43205Sbostic {
681*43205Sbostic   static char *undefined = "%s is undefined";
682*43205Sbostic   static char *nonconst = "%s is not a constant";
683*43205Sbostic   static char *nonint = "%s is not an integer";
684*43205Sbostic 
685*43205Sbostic   register dvalue *p;
686*43205Sbostic   register struct Paramblock *tp;
687*43205Sbostic   register int len;
688*43205Sbostic   register char *repr;
689*43205Sbostic 
690*43205Sbostic   p = ALLOC(Dvalue);
691*43205Sbostic   p->tag = DVALUE;
692*43205Sbostic 
693*43205Sbostic   len = dp->dname.len;
694*43205Sbostic   repr = dp->dname.repr;
695*43205Sbostic 
696*43205Sbostic   tp = (struct Paramblock *) getname(len, repr);
697*43205Sbostic 
698*43205Sbostic   if (tp == NULL)
699*43205Sbostic     {
700*43205Sbostic       errnm(undefined, len, repr);
701*43205Sbostic       p->status = ERRVAL;
702*43205Sbostic     }
703*43205Sbostic   else if (tp->vclass != CLPARAM || !ISCONST(tp->paramval))
704*43205Sbostic     {
705*43205Sbostic       if (tp->paramval->tag != TERROR)
706*43205Sbostic         errnm(nonconst, len, repr);
707*43205Sbostic       p->status = ERRVAL;
708*43205Sbostic     }
709*43205Sbostic   else if (!ISINT(tp->paramval->constblock.vtype))
710*43205Sbostic     {
711*43205Sbostic       errnm(nonint, len, repr);
712*43205Sbostic       p->status = ERRVAL;
713*43205Sbostic     }
714*43205Sbostic   else
715*43205Sbostic     {
716*43205Sbostic       if ((MAXINT + MININT == -1)
717*43205Sbostic 	  && tp->paramval->constblock.const.ci == MININT)
718*43205Sbostic 	p->status = MINLESS1;
719*43205Sbostic       else
720*43205Sbostic 	{
721*43205Sbostic 	  p->status = NORMAL;
722*43205Sbostic           p->value = tp->paramval->constblock.const.ci;
723*43205Sbostic 	}
724*43205Sbostic     }
725*43205Sbostic 
726*43205Sbostic   return ((vexpr *) p);
727*43205Sbostic }
728*43205Sbostic 
729*43205Sbostic 
730*43205Sbostic 
731*43205Sbostic vexpr *mkdexpr(op, l, r)
732*43205Sbostic register int op;
733*43205Sbostic register vexpr *l;
734*43205Sbostic register vexpr *r;
735*43205Sbostic {
736*43205Sbostic   static char *badop = "bad operator in mkdexpr";
737*43205Sbostic 
738*43205Sbostic   register vexpr *p;
739*43205Sbostic 
740*43205Sbostic   switch (op)
741*43205Sbostic     {
742*43205Sbostic     default:
743*43205Sbostic       fatal(badop);
744*43205Sbostic 
745*43205Sbostic     case OPNEG:
746*43205Sbostic     case OPPLUS:
747*43205Sbostic     case OPMINUS:
748*43205Sbostic     case OPSTAR:
749*43205Sbostic     case OPSLASH:
750*43205Sbostic     case OPPOWER:
751*43205Sbostic       break;
752*43205Sbostic     }
753*43205Sbostic 
754*43205Sbostic   if ((l != NULL && l->tag == DERROR) || r->tag == DERROR)
755*43205Sbostic     {
756*43205Sbostic       frvexpr(l);
757*43205Sbostic       frvexpr(r);
758*43205Sbostic       p = (vexpr *) ALLOC(Derror);
759*43205Sbostic       p->tag = DERROR;
760*43205Sbostic     }
761*43205Sbostic   else if (op == OPNEG && r->tag == DVALUE)
762*43205Sbostic     {
763*43205Sbostic       p = negival(r);
764*43205Sbostic       frvexpr(r);
765*43205Sbostic     }
766*43205Sbostic   else if (op != OPNEG && l->tag == DVALUE && r->tag == DVALUE)
767*43205Sbostic     {
768*43205Sbostic       switch (op)
769*43205Sbostic 	{
770*43205Sbostic 	case OPPLUS:
771*43205Sbostic 	  p = addivals(l, r);
772*43205Sbostic 	  break;
773*43205Sbostic 
774*43205Sbostic 	case OPMINUS:
775*43205Sbostic 	  p = subivals(l, r);
776*43205Sbostic 	  break;
777*43205Sbostic 
778*43205Sbostic 	case OPSTAR:
779*43205Sbostic 	  p = mulivals(l, r);
780*43205Sbostic 	  break;
781*43205Sbostic 
782*43205Sbostic 	case OPSLASH:
783*43205Sbostic 	  p = divivals(l, r);
784*43205Sbostic 	  break;
785*43205Sbostic 
786*43205Sbostic 	case OPPOWER:
787*43205Sbostic 	  p = powivals(l, r);
788*43205Sbostic 	  break;
789*43205Sbostic 	}
790*43205Sbostic 
791*43205Sbostic       frvexpr(l);
792*43205Sbostic       frvexpr(r);
793*43205Sbostic     }
794*43205Sbostic   else
795*43205Sbostic     {
796*43205Sbostic       p = (vexpr *) ALLOC(Dexpr);
797*43205Sbostic       p->tag = DEXPR;
798*43205Sbostic       p->dexpr.opcode = op;
799*43205Sbostic       p->dexpr.left = l;
800*43205Sbostic       p->dexpr.right = r;
801*43205Sbostic     }
802*43205Sbostic 
803*43205Sbostic   return (p);
804*43205Sbostic }
805*43205Sbostic 
806*43205Sbostic 
807*43205Sbostic 
808*43205Sbostic vexpr *addivals(l, r)
809*43205Sbostic vexpr *l;
810*43205Sbostic vexpr *r;
811*43205Sbostic {
812*43205Sbostic   static char *badtag = "bad tag in addivals";
813*43205Sbostic   static char *overflow = "integer value too large";
814*43205Sbostic 
815*43205Sbostic   register int ls, rs;
816*43205Sbostic   register ftnint lv, rv;
817*43205Sbostic   register dvalue *p;
818*43205Sbostic   register ftnint k;
819*43205Sbostic 
820*43205Sbostic   if (l->tag != DVALUE || r->tag != DVALUE)
821*43205Sbostic     fatal(badtag);
822*43205Sbostic 
823*43205Sbostic   ls = l->dvalue.status;
824*43205Sbostic   lv = l->dvalue.value;
825*43205Sbostic   rs = r->dvalue.status;
826*43205Sbostic   rv = r->dvalue.value;
827*43205Sbostic 
828*43205Sbostic   p = ALLOC(Dvalue);
829*43205Sbostic   p->tag = DVALUE;
830*43205Sbostic 
831*43205Sbostic   if (ls == ERRVAL || rs == ERRVAL)
832*43205Sbostic     p->status = ERRVAL;
833*43205Sbostic 
834*43205Sbostic   else if (ls == NORMAL && rs == NORMAL)
835*43205Sbostic     {
836*43205Sbostic       addints(lv, rv);
837*43205Sbostic       if (rstatus == ERRVAL)
838*43205Sbostic 	err(overflow);
839*43205Sbostic       p->status = rstatus;
840*43205Sbostic       p->value = rvalue;
841*43205Sbostic     }
842*43205Sbostic 
843*43205Sbostic   else
844*43205Sbostic     {
845*43205Sbostic       if (rs == MAXPLUS1 || rs == MINLESS1)
846*43205Sbostic 	{
847*43205Sbostic 	  rs = ls;
848*43205Sbostic 	  rv = lv;
849*43205Sbostic 	  ls = r->dvalue.status;
850*43205Sbostic 	}
851*43205Sbostic 
852*43205Sbostic       if (rs == NORMAL && rv == 0)
853*43205Sbostic 	p->status = ls;
854*43205Sbostic       else if (ls == MAXPLUS1)
855*43205Sbostic 	{
856*43205Sbostic 	  if (rs == NORMAL && rv < 0)
857*43205Sbostic 	    {
858*43205Sbostic 	      p->status = NORMAL;
859*43205Sbostic 	      k = MAXINT + rv;
860*43205Sbostic 	      p->value = k + 1;
861*43205Sbostic 	    }
862*43205Sbostic 	  else if (rs == MINLESS1)
863*43205Sbostic 	    {
864*43205Sbostic 	      p->status = NORMAL;
865*43205Sbostic 	      p->value = 0;
866*43205Sbostic 	    }
867*43205Sbostic 	  else
868*43205Sbostic 	    {
869*43205Sbostic 	      err(overflow);
870*43205Sbostic 	      p->status = ERRVAL;
871*43205Sbostic 	    }
872*43205Sbostic 	}
873*43205Sbostic       else
874*43205Sbostic 	{
875*43205Sbostic 	  if (rs == NORMAL && rv > 0)
876*43205Sbostic 	    {
877*43205Sbostic 	      p->status = NORMAL;
878*43205Sbostic 	      k = ( -MAXINT ) + rv;
879*43205Sbostic 	      p->value = k - 1;
880*43205Sbostic 	    }
881*43205Sbostic 	  else if (rs == MAXPLUS1)
882*43205Sbostic 	    {
883*43205Sbostic 	      p->status = NORMAL;
884*43205Sbostic 	      p->value = 0;
885*43205Sbostic 	    }
886*43205Sbostic 	  else
887*43205Sbostic 	    {
888*43205Sbostic 	      err(overflow);
889*43205Sbostic 	      p->status = ERRVAL;
890*43205Sbostic 	    }
891*43205Sbostic 	}
892*43205Sbostic     }
893*43205Sbostic 
894*43205Sbostic   return ((vexpr *) p);
895*43205Sbostic }
896*43205Sbostic 
897*43205Sbostic 
898*43205Sbostic 
899*43205Sbostic vexpr *negival(vp)
900*43205Sbostic vexpr *vp;
901*43205Sbostic {
902*43205Sbostic   static char *badtag = "bad tag in negival";
903*43205Sbostic 
904*43205Sbostic   register int vs;
905*43205Sbostic   register dvalue *p;
906*43205Sbostic 
907*43205Sbostic   if (vp->tag != DVALUE)
908*43205Sbostic     fatal(badtag);
909*43205Sbostic 
910*43205Sbostic   vs = vp->dvalue.status;
911*43205Sbostic 
912*43205Sbostic   p = ALLOC(Dvalue);
913*43205Sbostic   p->tag = DVALUE;
914*43205Sbostic 
915*43205Sbostic   if (vs == ERRVAL)
916*43205Sbostic     p->status = ERRVAL;
917*43205Sbostic   else if (vs == NORMAL)
918*43205Sbostic     {
919*43205Sbostic       p->status = NORMAL;
920*43205Sbostic       p->value = -(vp->dvalue.value);
921*43205Sbostic     }
922*43205Sbostic   else if (vs == MAXPLUS1)
923*43205Sbostic     p->status = MINLESS1;
924*43205Sbostic   else
925*43205Sbostic     p->status = MAXPLUS1;
926*43205Sbostic 
927*43205Sbostic   return ((vexpr *) p);
928*43205Sbostic }
929*43205Sbostic 
930*43205Sbostic 
931*43205Sbostic 
932*43205Sbostic vexpr *subivals(l, r)
933*43205Sbostic vexpr *l;
934*43205Sbostic vexpr *r;
935*43205Sbostic {
936*43205Sbostic   static char *badtag = "bad tag in subivals";
937*43205Sbostic 
938*43205Sbostic   register vexpr *p;
939*43205Sbostic   register vexpr *t;
940*43205Sbostic 
941*43205Sbostic   if (l->tag != DVALUE || r->tag != DVALUE)
942*43205Sbostic     fatal(badtag);
943*43205Sbostic 
944*43205Sbostic   t = negival(r);
945*43205Sbostic   p = addivals(l, t);
946*43205Sbostic   frvexpr(t);
947*43205Sbostic 
948*43205Sbostic   return (p);
949*43205Sbostic }
950*43205Sbostic 
951*43205Sbostic 
952*43205Sbostic 
953*43205Sbostic vexpr *mulivals(l, r)
954*43205Sbostic vexpr *l;
955*43205Sbostic vexpr *r;
956*43205Sbostic {
957*43205Sbostic   static char *badtag = "bad tag in mulivals";
958*43205Sbostic   static char *overflow = "integer value too large";
959*43205Sbostic 
960*43205Sbostic   register int ls, rs;
961*43205Sbostic   register ftnint lv, rv;
962*43205Sbostic   register dvalue *p;
963*43205Sbostic 
964*43205Sbostic   if (l->tag != DVALUE || r->tag != DVALUE)
965*43205Sbostic     fatal(badtag);
966*43205Sbostic 
967*43205Sbostic   ls = l->dvalue.status;
968*43205Sbostic   lv = l->dvalue.value;
969*43205Sbostic   rs = r->dvalue.status;
970*43205Sbostic   rv = r->dvalue.value;
971*43205Sbostic 
972*43205Sbostic   p = ALLOC(Dvalue);
973*43205Sbostic   p->tag = DVALUE;
974*43205Sbostic 
975*43205Sbostic   if (ls == ERRVAL || rs == ERRVAL)
976*43205Sbostic     p->status = ERRVAL;
977*43205Sbostic 
978*43205Sbostic   else if (ls == NORMAL && rs == NORMAL)
979*43205Sbostic     {
980*43205Sbostic       mulints(lv, rv);
981*43205Sbostic       if (rstatus == ERRVAL)
982*43205Sbostic 	err(overflow);
983*43205Sbostic       p->status = rstatus;
984*43205Sbostic       p->value = rvalue;
985*43205Sbostic     }
986*43205Sbostic   else
987*43205Sbostic     {
988*43205Sbostic       if (rs == MAXPLUS1 || rs == MINLESS1)
989*43205Sbostic 	{
990*43205Sbostic 	  rs = ls;
991*43205Sbostic 	  rv = lv;
992*43205Sbostic 	  ls = r->dvalue.status;
993*43205Sbostic 	}
994*43205Sbostic 
995*43205Sbostic       if (rs == NORMAL && rv == 0)
996*43205Sbostic 	{
997*43205Sbostic 	  p->status = NORMAL;
998*43205Sbostic 	  p->value = 0;
999*43205Sbostic 	}
1000*43205Sbostic       else if (rs == NORMAL && rv == 1)
1001*43205Sbostic 	p->status = ls;
1002*43205Sbostic       else if (rs == NORMAL && rv == -1)
1003*43205Sbostic 	if (ls == MAXPLUS1)
1004*43205Sbostic 	  p->status = MINLESS1;
1005*43205Sbostic 	else
1006*43205Sbostic 	  p->status = MAXPLUS1;
1007*43205Sbostic       else
1008*43205Sbostic 	{
1009*43205Sbostic 	  err(overflow);
1010*43205Sbostic 	  p->status = ERRVAL;
1011*43205Sbostic 	}
1012*43205Sbostic     }
1013*43205Sbostic 
1014*43205Sbostic   return ((vexpr *) p);
1015*43205Sbostic }
1016*43205Sbostic 
1017*43205Sbostic 
1018*43205Sbostic 
1019*43205Sbostic vexpr *divivals(l, r)
1020*43205Sbostic vexpr *l;
1021*43205Sbostic vexpr *r;
1022*43205Sbostic {
1023*43205Sbostic   static char *badtag = "bad tag in divivals";
1024*43205Sbostic   static char *zerodivide = "division by zero";
1025*43205Sbostic 
1026*43205Sbostic   register int ls, rs;
1027*43205Sbostic   register ftnint lv, rv;
1028*43205Sbostic   register dvalue *p;
1029*43205Sbostic   register ftnint k;
1030*43205Sbostic   register int sign;
1031*43205Sbostic 
1032*43205Sbostic   if (l->tag != DVALUE && r->tag != DVALUE)
1033*43205Sbostic     fatal(badtag);
1034*43205Sbostic 
1035*43205Sbostic   ls = l->dvalue.status;
1036*43205Sbostic   lv = l->dvalue.value;
1037*43205Sbostic   rs = r->dvalue.status;
1038*43205Sbostic   rv = r->dvalue.value;
1039*43205Sbostic 
1040*43205Sbostic   p = ALLOC(Dvalue);
1041*43205Sbostic   p->tag = DVALUE;
1042*43205Sbostic 
1043*43205Sbostic   if (ls == ERRVAL || rs == ERRVAL)
1044*43205Sbostic     p->status = ERRVAL;
1045*43205Sbostic   else if (rs == NORMAL)
1046*43205Sbostic     {
1047*43205Sbostic       if (rv == 0)
1048*43205Sbostic 	{
1049*43205Sbostic 	  err(zerodivide);
1050*43205Sbostic 	  p->status = ERRVAL;
1051*43205Sbostic 	}
1052*43205Sbostic       else if (ls == NORMAL)
1053*43205Sbostic 	{
1054*43205Sbostic 	  p->status = NORMAL;
1055*43205Sbostic 	  p->value = lv / rv;
1056*43205Sbostic 	}
1057*43205Sbostic       else if (rv == 1)
1058*43205Sbostic 	p->status = ls;
1059*43205Sbostic       else if (rv == -1)
1060*43205Sbostic 	if (ls == MAXPLUS1)
1061*43205Sbostic 	  p->status = MINLESS1;
1062*43205Sbostic 	else
1063*43205Sbostic 	  p->status = MAXPLUS1;
1064*43205Sbostic       else
1065*43205Sbostic 	{
1066*43205Sbostic 	  p->status = NORMAL;
1067*43205Sbostic 
1068*43205Sbostic 	  if (ls == MAXPLUS1)
1069*43205Sbostic 	    sign = 1;
1070*43205Sbostic 	  else
1071*43205Sbostic 	    sign = -1;
1072*43205Sbostic 
1073*43205Sbostic 	  if (rv < 0)
1074*43205Sbostic 	    {
1075*43205Sbostic 	      rv = -rv;
1076*43205Sbostic 	      sign = -sign;
1077*43205Sbostic 	    }
1078*43205Sbostic 
1079*43205Sbostic 	  k = MAXINT - rv;
1080*43205Sbostic 	  p->value = sign * ((k + 1)/rv + 1);
1081*43205Sbostic 	}
1082*43205Sbostic     }
1083*43205Sbostic   else
1084*43205Sbostic     {
1085*43205Sbostic       p->status = NORMAL;
1086*43205Sbostic       if (ls == NORMAL)
1087*43205Sbostic 	p->value = 0;
1088*43205Sbostic       else if ((ls == MAXPLUS1 && rs == MAXPLUS1)
1089*43205Sbostic 		|| (ls == MINLESS1 && rs == MINLESS1))
1090*43205Sbostic 	p->value = 1;
1091*43205Sbostic       else
1092*43205Sbostic 	p->value = -1;
1093*43205Sbostic     }
1094*43205Sbostic 
1095*43205Sbostic   return ((vexpr *) p);
1096*43205Sbostic }
1097*43205Sbostic 
1098*43205Sbostic 
1099*43205Sbostic 
1100*43205Sbostic vexpr *powivals(l, r)
1101*43205Sbostic vexpr *l;
1102*43205Sbostic vexpr *r;
1103*43205Sbostic {
1104*43205Sbostic   static char *badtag = "bad tag in powivals";
1105*43205Sbostic   static char *zerozero = "zero raised to the zero-th power";
1106*43205Sbostic   static char *zeroneg = "zero raised to a negative power";
1107*43205Sbostic   static char *overflow = "integer value too large";
1108*43205Sbostic 
1109*43205Sbostic   register int ls, rs;
1110*43205Sbostic   register ftnint lv, rv;
1111*43205Sbostic   register dvalue *p;
1112*43205Sbostic 
1113*43205Sbostic   if (l->tag != DVALUE || r->tag != DVALUE)
1114*43205Sbostic     fatal(badtag);
1115*43205Sbostic 
1116*43205Sbostic   ls = l->dvalue.status;
1117*43205Sbostic   lv = l->dvalue.value;
1118*43205Sbostic   rs = r->dvalue.status;
1119*43205Sbostic   rv = r->dvalue.value;
1120*43205Sbostic 
1121*43205Sbostic   p = ALLOC(Dvalue);
1122*43205Sbostic   p->tag = DVALUE;
1123*43205Sbostic 
1124*43205Sbostic   if (ls == ERRVAL || rs == ERRVAL)
1125*43205Sbostic     p->status = ERRVAL;
1126*43205Sbostic 
1127*43205Sbostic   else if (ls == NORMAL)
1128*43205Sbostic     {
1129*43205Sbostic       if (lv == 1)
1130*43205Sbostic 	{
1131*43205Sbostic 	  p->status = NORMAL;
1132*43205Sbostic 	  p->value = 1;
1133*43205Sbostic 	}
1134*43205Sbostic       else if (lv == 0)
1135*43205Sbostic 	{
1136*43205Sbostic 	  if (rs == MAXPLUS1 || (rs == NORMAL && rv > 0))
1137*43205Sbostic 	    {
1138*43205Sbostic 	      p->status = NORMAL;
1139*43205Sbostic 	      p->value = 0;
1140*43205Sbostic 	    }
1141*43205Sbostic 	  else if (rs == NORMAL && rv == 0)
1142*43205Sbostic 	    {
1143*43205Sbostic 	      warn(zerozero);
1144*43205Sbostic 	      p->status = NORMAL;
1145*43205Sbostic 	      p->value = 1;
1146*43205Sbostic 	    }
1147*43205Sbostic 	  else
1148*43205Sbostic 	    {
1149*43205Sbostic 	      err(zeroneg);
1150*43205Sbostic 	      p->status = ERRVAL;
1151*43205Sbostic 	    }
1152*43205Sbostic 	}
1153*43205Sbostic       else if (lv == -1)
1154*43205Sbostic 	{
1155*43205Sbostic 	  p->status = NORMAL;
1156*43205Sbostic 	  if (rs == NORMAL)
1157*43205Sbostic 	    {
1158*43205Sbostic 	      if (rv < 0) rv = -rv;
1159*43205Sbostic 	      if (rv % 2 == 0)
1160*43205Sbostic 		p->value = 1;
1161*43205Sbostic 	      else
1162*43205Sbostic 		p->value = -1;
1163*43205Sbostic 	    }
1164*43205Sbostic 	  else
1165*43205Sbostic #	    if (MAXINT % 2 == 1)
1166*43205Sbostic 	      p->value = 1;
1167*43205Sbostic #	    else
1168*43205Sbostic 	      p->value = -1;
1169*43205Sbostic #	    endif
1170*43205Sbostic 	}
1171*43205Sbostic       else
1172*43205Sbostic 	{
1173*43205Sbostic 	  if (rs == NORMAL && rv > 0)
1174*43205Sbostic 	    {
1175*43205Sbostic 	      rstatus = NORMAL;
1176*43205Sbostic 	      rvalue = lv;
1177*43205Sbostic 	      while (--rv && rstatus == NORMAL)
1178*43205Sbostic 		mulints(rvalue, lv);
1179*43205Sbostic 	      if (rv == 0 && rstatus != ERRVAL)
1180*43205Sbostic 		{
1181*43205Sbostic 		  p->status = rstatus;
1182*43205Sbostic 		  p->value = rvalue;
1183*43205Sbostic 		}
1184*43205Sbostic 	      else
1185*43205Sbostic 		{
1186*43205Sbostic 		  err(overflow);
1187*43205Sbostic 		  p->status = ERRVAL;
1188*43205Sbostic 		}
1189*43205Sbostic 	    }
1190*43205Sbostic 	  else if (rs == MAXPLUS1)
1191*43205Sbostic 	    {
1192*43205Sbostic 	      err(overflow);
1193*43205Sbostic 	      p->status = ERRVAL;
1194*43205Sbostic 	    }
1195*43205Sbostic 	  else if (rs == NORMAL && rv == 0)
1196*43205Sbostic 	    {
1197*43205Sbostic 	      p->status = NORMAL;
1198*43205Sbostic 	      p->value = 1;
1199*43205Sbostic 	    }
1200*43205Sbostic 	  else
1201*43205Sbostic 	    {
1202*43205Sbostic 	      p->status = NORMAL;
1203*43205Sbostic 	      p->value = 0;
1204*43205Sbostic 	    }
1205*43205Sbostic 	}
1206*43205Sbostic     }
1207*43205Sbostic 
1208*43205Sbostic   else
1209*43205Sbostic     {
1210*43205Sbostic       if (rs == MAXPLUS1 || (rs == NORMAL && rv > 1))
1211*43205Sbostic 	{
1212*43205Sbostic 	  err(overflow);
1213*43205Sbostic 	  p->status = ERRVAL;
1214*43205Sbostic 	}
1215*43205Sbostic       else if (rs == NORMAL && rv == 1)
1216*43205Sbostic 	p->status = ls;
1217*43205Sbostic       else if (rs == NORMAL && rv == 0)
1218*43205Sbostic 	{
1219*43205Sbostic 	  p->status = NORMAL;
1220*43205Sbostic 	  p->value = 1;
1221*43205Sbostic 	}
1222*43205Sbostic       else
1223*43205Sbostic 	{
1224*43205Sbostic 	  p->status = NORMAL;
1225*43205Sbostic 	  p->value = 0;
1226*43205Sbostic 	}
1227*43205Sbostic     }
1228*43205Sbostic 
1229*43205Sbostic   return ((vexpr *) p);
1230*43205Sbostic }
1231*43205Sbostic 
1232*43205Sbostic 
1233*43205Sbostic 
1234*43205Sbostic /*  Addints adds two integer values.  */
1235*43205Sbostic 
1236*43205Sbostic addints(i, j)
1237*43205Sbostic register ftnint i, j;
1238*43205Sbostic {
1239*43205Sbostic   register ftnint margin;
1240*43205Sbostic 
1241*43205Sbostic   if (i == 0)
1242*43205Sbostic     {
1243*43205Sbostic       rstatus = NORMAL;
1244*43205Sbostic       rvalue = j;
1245*43205Sbostic     }
1246*43205Sbostic   else if (i > 0)
1247*43205Sbostic     {
1248*43205Sbostic       margin = MAXINT - i;
1249*43205Sbostic       if (j <= margin)
1250*43205Sbostic 	{
1251*43205Sbostic 	  rstatus = NORMAL;
1252*43205Sbostic 	  rvalue = i + j;
1253*43205Sbostic 	}
1254*43205Sbostic       else if (j == margin + 1)
1255*43205Sbostic 	rstatus = MAXPLUS1;
1256*43205Sbostic       else
1257*43205Sbostic 	rstatus = ERRVAL;
1258*43205Sbostic     }
1259*43205Sbostic   else
1260*43205Sbostic     {
1261*43205Sbostic       margin = ( -MAXINT ) - i;
1262*43205Sbostic       if (j >= margin)
1263*43205Sbostic 	{
1264*43205Sbostic 	  rstatus = NORMAL;
1265*43205Sbostic 	  rvalue = i + j;
1266*43205Sbostic 	}
1267*43205Sbostic       else if (j == margin - 1)
1268*43205Sbostic 	rstatus = MINLESS1;
1269*43205Sbostic       else
1270*43205Sbostic 	rstatus = ERRVAL;
1271*43205Sbostic     }
1272*43205Sbostic 
1273*43205Sbostic    return;
1274*43205Sbostic }
1275*43205Sbostic 
1276*43205Sbostic 
1277*43205Sbostic 
1278*43205Sbostic /*  Mulints multiplies two integer values  */
1279*43205Sbostic 
1280*43205Sbostic mulints(i, j)
1281*43205Sbostic register ftnint i, j;
1282*43205Sbostic {
1283*43205Sbostic   register ftnint sign;
1284*43205Sbostic   register ftnint margin;
1285*43205Sbostic 
1286*43205Sbostic   if (i == 0 || j == 0)
1287*43205Sbostic     {
1288*43205Sbostic       rstatus = NORMAL;
1289*43205Sbostic       rvalue = 0;
1290*43205Sbostic     }
1291*43205Sbostic   else
1292*43205Sbostic     {
1293*43205Sbostic       if ((i > 0 && j > 0) || (i < 0 && j < 0))
1294*43205Sbostic 	sign = 1;
1295*43205Sbostic       else
1296*43205Sbostic 	sign = -1;
1297*43205Sbostic 
1298*43205Sbostic       if (i < 0) i = -i;
1299*43205Sbostic       if (j < 0) j = -j;
1300*43205Sbostic 
1301*43205Sbostic       margin = MAXINT - i;
1302*43205Sbostic       margin = (margin + 1) / i;
1303*43205Sbostic 
1304*43205Sbostic       if (j <= margin)
1305*43205Sbostic 	{
1306*43205Sbostic 	  rstatus = NORMAL;
1307*43205Sbostic 	  rvalue = i * j * sign;
1308*43205Sbostic 	}
1309*43205Sbostic       else if (j - 1 == margin)
1310*43205Sbostic 	{
1311*43205Sbostic 	  margin = i*margin - 1;
1312*43205Sbostic 	  if (margin == MAXINT - i)
1313*43205Sbostic 	    if (sign > 0)
1314*43205Sbostic 	      rstatus = MAXPLUS1;
1315*43205Sbostic 	    else
1316*43205Sbostic 	      rstatus = MINLESS1;
1317*43205Sbostic 	  else
1318*43205Sbostic 	    {
1319*43205Sbostic 	      rstatus = NORMAL;
1320*43205Sbostic 	      rvalue = i * j * sign;
1321*43205Sbostic 	    }
1322*43205Sbostic 	}
1323*43205Sbostic       else
1324*43205Sbostic 	rstatus = ERRVAL;
1325*43205Sbostic     }
1326*43205Sbostic 
1327*43205Sbostic   return;
1328*43205Sbostic }
1329*43205Sbostic 
1330*43205Sbostic 
1331*43205Sbostic 
1332*43205Sbostic vexpr *
1333*43205Sbostic evalvexpr(ep)
1334*43205Sbostic vexpr *ep;
1335*43205Sbostic {
1336*43205Sbostic   register vexpr *p;
1337*43205Sbostic   register vexpr *l, *r;
1338*43205Sbostic 
1339*43205Sbostic   switch (ep->tag)
1340*43205Sbostic     {
1341*43205Sbostic     case DVALUE:
1342*43205Sbostic       p = cpdvalue(ep);
1343*43205Sbostic       break;
1344*43205Sbostic 
1345*43205Sbostic     case DVAR:
1346*43205Sbostic       p = cpdvalue((vexpr *) ep->dvar.valp);
1347*43205Sbostic       break;
1348*43205Sbostic 
1349*43205Sbostic     case DNAME:
1350*43205Sbostic       p = evaldname(ep);
1351*43205Sbostic       break;
1352*43205Sbostic 
1353*43205Sbostic     case DEXPR:
1354*43205Sbostic       if (ep->dexpr.left == NULL)
1355*43205Sbostic 	l = NULL;
1356*43205Sbostic       else
1357*43205Sbostic 	l = evalvexpr(ep->dexpr.left);
1358*43205Sbostic 
1359*43205Sbostic       if (ep->dexpr.right == NULL)
1360*43205Sbostic 	r = NULL;
1361*43205Sbostic       else
1362*43205Sbostic 	r = evalvexpr(ep->dexpr.right);
1363*43205Sbostic 
1364*43205Sbostic       switch (ep->dexpr.opcode)
1365*43205Sbostic 	{
1366*43205Sbostic 	case OPNEG:
1367*43205Sbostic 	  p = negival(r);
1368*43205Sbostic 	  break;
1369*43205Sbostic 
1370*43205Sbostic 	case OPPLUS:
1371*43205Sbostic 	  p = addivals(l, r);
1372*43205Sbostic 	  break;
1373*43205Sbostic 
1374*43205Sbostic 	case OPMINUS:
1375*43205Sbostic 	  p = subivals(l, r);
1376*43205Sbostic 	  break;
1377*43205Sbostic 
1378*43205Sbostic 	case OPSTAR:
1379*43205Sbostic 	  p = mulivals(l, r);
1380*43205Sbostic 	  break;
1381*43205Sbostic 
1382*43205Sbostic 	case OPSLASH:
1383*43205Sbostic 	  p = divivals(l, r);
1384*43205Sbostic 	  break;
1385*43205Sbostic 
1386*43205Sbostic 	case OPPOWER:
1387*43205Sbostic 	  p = powivals(l, r);
1388*43205Sbostic 	  break;
1389*43205Sbostic 	}
1390*43205Sbostic 
1391*43205Sbostic       frvexpr(l);
1392*43205Sbostic       frvexpr(r);
1393*43205Sbostic       break;
1394*43205Sbostic 
1395*43205Sbostic     case DERROR:
1396*43205Sbostic       p = (vexpr *) ALLOC(Dvalue);
1397*43205Sbostic       p->tag = DVALUE;
1398*43205Sbostic       p->dvalue.status = ERRVAL;
1399*43205Sbostic       break;
1400*43205Sbostic     }
1401*43205Sbostic 
1402*43205Sbostic   return (p);
1403*43205Sbostic }
1404*43205Sbostic 
1405*43205Sbostic 
1406*43205Sbostic 
1407*43205Sbostic vexpr *
1408*43205Sbostic refrigdname(vp)
1409*43205Sbostic vexpr *vp;
1410*43205Sbostic {
1411*43205Sbostic   register vexpr *p;
1412*43205Sbostic   register int len;
1413*43205Sbostic   register char *repr;
1414*43205Sbostic   register int found;
1415*43205Sbostic   register dovars *dvp;
1416*43205Sbostic 
1417*43205Sbostic   len = vp->dname.len;
1418*43205Sbostic   repr = vp->dname.repr;
1419*43205Sbostic 
1420*43205Sbostic   found = NO;
1421*43205Sbostic   dvp = dvlist;
1422*43205Sbostic   while (found == NO && dvp != NULL)
1423*43205Sbostic     {
1424*43205Sbostic       if (len == dvp->len && eqn(len, repr, dvp->repr))
1425*43205Sbostic 	found = YES;
1426*43205Sbostic       else
1427*43205Sbostic 	dvp = dvp->next;
1428*43205Sbostic     }
1429*43205Sbostic 
1430*43205Sbostic   if (found == YES)
1431*43205Sbostic     {
1432*43205Sbostic       p = (vexpr *) ALLOC(Dvar);
1433*43205Sbostic       p->tag = DVAR;
1434*43205Sbostic       p->dvar.valp = dvp->valp;
1435*43205Sbostic     }
1436*43205Sbostic   else
1437*43205Sbostic     {
1438*43205Sbostic       p = evaldname(vp);
1439*43205Sbostic       if (p->dvalue.status == ERRVAL)
1440*43205Sbostic 	dataerror = YES;
1441*43205Sbostic     }
1442*43205Sbostic 
1443*43205Sbostic   return (p);
1444*43205Sbostic }
1445*43205Sbostic 
1446*43205Sbostic 
1447*43205Sbostic 
1448*43205Sbostic refrigvexpr(vpp)
1449*43205Sbostic vexpr **vpp;
1450*43205Sbostic {
1451*43205Sbostic   register vexpr *vp;
1452*43205Sbostic 
1453*43205Sbostic   vp = *vpp;
1454*43205Sbostic 
1455*43205Sbostic   switch (vp->tag)
1456*43205Sbostic     {
1457*43205Sbostic     case DVALUE:
1458*43205Sbostic     case DVAR:
1459*43205Sbostic     case DERROR:
1460*43205Sbostic       break;
1461*43205Sbostic 
1462*43205Sbostic     case DEXPR:
1463*43205Sbostic       refrigvexpr( &(vp->dexpr.left) );
1464*43205Sbostic       refrigvexpr( &(vp->dexpr.right) );
1465*43205Sbostic       break;
1466*43205Sbostic 
1467*43205Sbostic     case DNAME:
1468*43205Sbostic       *(vpp) = refrigdname(vp);
1469*43205Sbostic       frvexpr(vp);
1470*43205Sbostic       break;
1471*43205Sbostic     }
1472*43205Sbostic 
1473*43205Sbostic   return;
1474*43205Sbostic }
1475*43205Sbostic 
1476*43205Sbostic 
1477*43205Sbostic 
1478*43205Sbostic int
1479*43205Sbostic chkvar(np, sname)
1480*43205Sbostic Namep np;
1481*43205Sbostic char *sname;
1482*43205Sbostic {
1483*43205Sbostic   static char *nonvar = "%s is not a variable";
1484*43205Sbostic   static char *arginit = "attempt to initialize a dummy argument: %s";
1485*43205Sbostic   static char *autoinit = "attempt to initialize an automatic variable: %s";
1486*43205Sbostic   static char *badclass = "bad class in chkvar";
1487*43205Sbostic 
1488*43205Sbostic   register int status;
1489*43205Sbostic   register struct Dimblock *dp;
1490*43205Sbostic   register int i;
1491*43205Sbostic 
1492*43205Sbostic   status = YES;
1493*43205Sbostic 
1494*43205Sbostic   if (np->vclass == CLUNKNOWN
1495*43205Sbostic       || (np->vclass == CLVAR && !np->vdcldone))
1496*43205Sbostic     vardcl(np);
1497*43205Sbostic 
1498*43205Sbostic   if (np->vstg == STGARG)
1499*43205Sbostic     {
1500*43205Sbostic       errstr(arginit, sname);
1501*43205Sbostic       dataerror = YES;
1502*43205Sbostic       status = NO;
1503*43205Sbostic     }
1504*43205Sbostic   else if (np->vclass != CLVAR)
1505*43205Sbostic     {
1506*43205Sbostic       errstr(nonvar, sname);
1507*43205Sbostic       dataerror = YES;
1508*43205Sbostic       status = NO;
1509*43205Sbostic     }
1510*43205Sbostic   else if (np->vstg == STGAUTO)
1511*43205Sbostic     {
1512*43205Sbostic       errstr(autoinit, sname);
1513*43205Sbostic       dataerror = YES;
1514*43205Sbostic       status = NO;
1515*43205Sbostic     }
1516*43205Sbostic   else if (np->vstg != STGBSS && np->vstg != STGINIT
1517*43205Sbostic 	    && np->vstg != STGCOMMON && np->vstg != STGEQUIV)
1518*43205Sbostic     {
1519*43205Sbostic       fatal(badclass);
1520*43205Sbostic     }
1521*43205Sbostic   else
1522*43205Sbostic     {
1523*43205Sbostic       switch (np->vtype)
1524*43205Sbostic 	{
1525*43205Sbostic 	case TYERROR:
1526*43205Sbostic 	  status = NO;
1527*43205Sbostic 	  dataerror = YES;
1528*43205Sbostic 	  break;
1529*43205Sbostic 
1530*43205Sbostic 	case TYSHORT:
1531*43205Sbostic 	case TYLONG:
1532*43205Sbostic 	case TYREAL:
1533*43205Sbostic 	case TYDREAL:
1534*43205Sbostic 	case TYCOMPLEX:
1535*43205Sbostic 	case TYDCOMPLEX:
1536*43205Sbostic 	case TYLOGICAL:
1537*43205Sbostic 	case TYCHAR:
1538*43205Sbostic 	  dp = np->vdim;
1539*43205Sbostic 	  if (dp != NULL)
1540*43205Sbostic 	    {
1541*43205Sbostic 	      if (dp->nelt == NULL || !ISICON(dp->nelt))
1542*43205Sbostic 	        {
1543*43205Sbostic 	          status = NO;
1544*43205Sbostic 	          dataerror = YES;
1545*43205Sbostic 	        }
1546*43205Sbostic 	    }
1547*43205Sbostic 	  break;
1548*43205Sbostic 
1549*43205Sbostic 	default:
1550*43205Sbostic 	  badtype("chkvar", np->vtype);
1551*43205Sbostic 	}
1552*43205Sbostic     }
1553*43205Sbostic 
1554*43205Sbostic   return (status);
1555*43205Sbostic }
1556*43205Sbostic 
1557*43205Sbostic 
1558*43205Sbostic 
1559*43205Sbostic refrigsubs(ap, sname)
1560*43205Sbostic aelt *ap;
1561*43205Sbostic char *sname;
1562*43205Sbostic {
1563*43205Sbostic   static char *nonarray = "subscripts on a simple variable:  %s";
1564*43205Sbostic   static char *toofew = "not enough subscripts on %s";
1565*43205Sbostic   static char *toomany = "too many subscripts on %s";
1566*43205Sbostic 
1567*43205Sbostic   register vlist *subp;
1568*43205Sbostic   register int nsubs;
1569*43205Sbostic   register Namep np;
1570*43205Sbostic   register struct Dimblock *dp;
1571*43205Sbostic   register int i;
1572*43205Sbostic 
1573*43205Sbostic   np = ap->var;
1574*43205Sbostic   dp = np->vdim;
1575*43205Sbostic 
1576*43205Sbostic   if (ap->subs != NULL)
1577*43205Sbostic     {
1578*43205Sbostic       if (np->vdim == NULL)
1579*43205Sbostic 	{
1580*43205Sbostic 	  errstr(nonarray, sname);
1581*43205Sbostic 	  dataerror = YES;
1582*43205Sbostic 	}
1583*43205Sbostic       else
1584*43205Sbostic 	{
1585*43205Sbostic 	  nsubs = 0;
1586*43205Sbostic 	  subp = ap->subs;
1587*43205Sbostic 	  while (subp != NULL)
1588*43205Sbostic 	    {
1589*43205Sbostic 	      nsubs++;
1590*43205Sbostic 	      refrigvexpr( &(subp->val) );
1591*43205Sbostic 	      subp = subp->next;
1592*43205Sbostic 	    }
1593*43205Sbostic 
1594*43205Sbostic 	  if (dp->ndim != nsubs)
1595*43205Sbostic 	    {
1596*43205Sbostic 	      if (np->vdim->ndim > nsubs)
1597*43205Sbostic 		errstr(toofew, sname);
1598*43205Sbostic 	      else
1599*43205Sbostic 		errstr(toomany, sname);
1600*43205Sbostic 	      dataerror = YES;
1601*43205Sbostic 	    }
1602*43205Sbostic 	  else if (dp->baseoffset == NULL || !ISICON(dp->baseoffset))
1603*43205Sbostic 	    dataerror = YES;
1604*43205Sbostic 	  else
1605*43205Sbostic 	    {
1606*43205Sbostic 	      i = dp->ndim;
1607*43205Sbostic 	      while (i-- > 0)
1608*43205Sbostic 		{
1609*43205Sbostic 		  if (dp->dims[i].dimsize == NULL
1610*43205Sbostic 		      || !ISICON(dp->dims[i].dimsize))
1611*43205Sbostic 		    dataerror = YES;
1612*43205Sbostic 		}
1613*43205Sbostic 	    }
1614*43205Sbostic 	}
1615*43205Sbostic     }
1616*43205Sbostic 
1617*43205Sbostic   return;
1618*43205Sbostic }
1619*43205Sbostic 
1620*43205Sbostic 
1621*43205Sbostic 
1622*43205Sbostic refrigrange(ap, sname)
1623*43205Sbostic aelt *ap;
1624*43205Sbostic char *sname;
1625*43205Sbostic {
1626*43205Sbostic   static char *nonstr = "substring of a noncharacter variable:  %s";
1627*43205Sbostic   static char *array = "substring applied to an array:  %s";
1628*43205Sbostic 
1629*43205Sbostic   register Namep np;
1630*43205Sbostic   register dvalue *t;
1631*43205Sbostic   register rpair *rp;
1632*43205Sbostic 
1633*43205Sbostic   if (ap->range != NULL)
1634*43205Sbostic     {
1635*43205Sbostic       np = ap->var;
1636*43205Sbostic       if (np->vtype != TYCHAR)
1637*43205Sbostic 	{
1638*43205Sbostic 	  errstr(nonstr, sname);
1639*43205Sbostic 	  dataerror = YES;
1640*43205Sbostic 	}
1641*43205Sbostic       else if (ap->subs == NULL && np->vdim != NULL)
1642*43205Sbostic 	{
1643*43205Sbostic 	  errstr(array, sname);
1644*43205Sbostic 	  dataerror = YES;
1645*43205Sbostic 	}
1646*43205Sbostic       else
1647*43205Sbostic 	{
1648*43205Sbostic 	  rp = ap->range;
1649*43205Sbostic 
1650*43205Sbostic 	  if (rp->low != NULL)
1651*43205Sbostic 	    refrigvexpr( &(rp->low) );
1652*43205Sbostic 	  else
1653*43205Sbostic 	    {
1654*43205Sbostic 	      t = ALLOC(Dvalue);
1655*43205Sbostic 	      t->tag = DVALUE;
1656*43205Sbostic 	      t->status = NORMAL;
1657*43205Sbostic 	      t->value = 1;
1658*43205Sbostic 	      rp->low = (vexpr *) t;
1659*43205Sbostic 	    }
1660*43205Sbostic 
1661*43205Sbostic 	  if (rp->high != NULL)
1662*43205Sbostic 	    refrigvexpr( &(rp->high) );
1663*43205Sbostic 	  else
1664*43205Sbostic 	    {
1665*43205Sbostic 	      if (!ISICON(np->vleng))
1666*43205Sbostic 		{
1667*43205Sbostic 		  rp->high = (vexpr *) ALLOC(Derror);
1668*43205Sbostic 		  rp->high->tag = DERROR;
1669*43205Sbostic 		}
1670*43205Sbostic 	      else
1671*43205Sbostic 		{
1672*43205Sbostic 		  t = ALLOC(Dvalue);
1673*43205Sbostic 		  t->tag = DVALUE;
1674*43205Sbostic 		  t->status = NORMAL;
1675*43205Sbostic 		  t->value = np->vleng->constblock.const.ci;
1676*43205Sbostic 		  rp->high = (vexpr *) t;
1677*43205Sbostic 		}
1678*43205Sbostic 	    }
1679*43205Sbostic 	}
1680*43205Sbostic     }
1681*43205Sbostic 
1682*43205Sbostic   return;
1683*43205Sbostic }
1684*43205Sbostic 
1685*43205Sbostic 
1686*43205Sbostic 
1687*43205Sbostic refrigaelt(ap)
1688*43205Sbostic aelt *ap;
1689*43205Sbostic {
1690*43205Sbostic   register Namep np;
1691*43205Sbostic   register char *bp, *sp;
1692*43205Sbostic   register int len;
1693*43205Sbostic   char buff[VL+1];
1694*43205Sbostic 
1695*43205Sbostic   np = ap->var;
1696*43205Sbostic 
1697*43205Sbostic   len = 0;
1698*43205Sbostic   bp = buff;
1699*43205Sbostic   sp = np->varname;
1700*43205Sbostic   while (len < VL && *sp != ' ' && *sp != '\0')
1701*43205Sbostic     {
1702*43205Sbostic       *bp++ = *sp++;
1703*43205Sbostic       len++;
1704*43205Sbostic     }
1705*43205Sbostic   *bp = '\0';
1706*43205Sbostic 
1707*43205Sbostic   if (chkvar(np, buff))
1708*43205Sbostic     {
1709*43205Sbostic       refrigsubs(ap, buff);
1710*43205Sbostic       refrigrange(ap, buff);
1711*43205Sbostic     }
1712*43205Sbostic 
1713*43205Sbostic   return;
1714*43205Sbostic }
1715*43205Sbostic 
1716*43205Sbostic 
1717*43205Sbostic 
1718*43205Sbostic refrigdo(dp)
1719*43205Sbostic dolist *dp;
1720*43205Sbostic {
1721*43205Sbostic   static char *duplicates = "implied DO variable %s redefined";
1722*43205Sbostic   static char *nonvar = "%s is not a variable";
1723*43205Sbostic   static char *nonint = "%s is not integer";
1724*43205Sbostic 
1725*43205Sbostic   register int len;
1726*43205Sbostic   register char *repr;
1727*43205Sbostic   register int found;
1728*43205Sbostic   register dovars *dvp;
1729*43205Sbostic   register Namep np;
1730*43205Sbostic   register dovars *t;
1731*43205Sbostic 
1732*43205Sbostic   refrigvexpr( &(dp->init) );
1733*43205Sbostic   refrigvexpr( &(dp->limit) );
1734*43205Sbostic   refrigvexpr( &(dp->step) );
1735*43205Sbostic 
1736*43205Sbostic   len = dp->dovar->dname.len;
1737*43205Sbostic   repr = dp->dovar->dname.repr;
1738*43205Sbostic 
1739*43205Sbostic   found = NO;
1740*43205Sbostic   dvp = dvlist;
1741*43205Sbostic   while (found == NO && dvp != NULL)
1742*43205Sbostic     if (len == dvp->len && eqn(len, repr, dvp->repr))
1743*43205Sbostic       found = YES;
1744*43205Sbostic     else
1745*43205Sbostic       dvp = dvp->next;
1746*43205Sbostic 
1747*43205Sbostic   if (found == YES)
1748*43205Sbostic     {
1749*43205Sbostic       errnm(duplicates, len, repr);
1750*43205Sbostic       dataerror = YES;
1751*43205Sbostic     }
1752*43205Sbostic   else
1753*43205Sbostic     {
1754*43205Sbostic       np = getname(len, repr);
1755*43205Sbostic       if (np == NULL)
1756*43205Sbostic 	{
1757*43205Sbostic 	  if (!ISINT(impltype[letter(*repr)]))
1758*43205Sbostic 	    warnnm(nonint, len, repr);
1759*43205Sbostic 	}
1760*43205Sbostic       else
1761*43205Sbostic 	{
1762*43205Sbostic 	  if (np->vclass == CLUNKNOWN)
1763*43205Sbostic 	    vardcl(np);
1764*43205Sbostic 	  if (np->vclass != CLVAR)
1765*43205Sbostic 	    warnnm(nonvar, len, repr);
1766*43205Sbostic 	  else if (!ISINT(np->vtype))
1767*43205Sbostic 	    warnnm(nonint, len, repr);
1768*43205Sbostic 	}
1769*43205Sbostic     }
1770*43205Sbostic 
1771*43205Sbostic   t = ALLOC(DoVars);
1772*43205Sbostic   t->next = dvlist;
1773*43205Sbostic   t->len = len;
1774*43205Sbostic   t->repr = repr;
1775*43205Sbostic   t->valp = ALLOC(Dvalue);
1776*43205Sbostic   t->valp->tag = DVALUE;
1777*43205Sbostic   dp->dovar = (vexpr *) t->valp;
1778*43205Sbostic 
1779*43205Sbostic   dvlist = t;
1780*43205Sbostic 
1781*43205Sbostic   refriglvals(dp->elts);
1782*43205Sbostic 
1783*43205Sbostic   dvlist = t->next;
1784*43205Sbostic   free((char *) t);
1785*43205Sbostic 
1786*43205Sbostic   return;
1787*43205Sbostic }
1788*43205Sbostic 
1789*43205Sbostic 
1790*43205Sbostic 
1791*43205Sbostic refriglvals(lvals)
1792*43205Sbostic elist *lvals;
1793*43205Sbostic {
1794*43205Sbostic   register elist *top;
1795*43205Sbostic 
1796*43205Sbostic   top = lvals;
1797*43205Sbostic 
1798*43205Sbostic   while (top != NULL)
1799*43205Sbostic     {
1800*43205Sbostic       if (top->elt->tag == SIMPLE)
1801*43205Sbostic 	refrigaelt((aelt *) top->elt);
1802*43205Sbostic       else
1803*43205Sbostic 	refrigdo((dolist *) top->elt);
1804*43205Sbostic 
1805*43205Sbostic       top = top->next;
1806*43205Sbostic     }
1807*43205Sbostic 
1808*43205Sbostic   return;
1809*43205Sbostic }
1810*43205Sbostic 
1811*43205Sbostic 
1812*43205Sbostic 
1813*43205Sbostic /*  Refrig freezes name/value bindings in the DATA name list  */
1814*43205Sbostic 
1815*43205Sbostic 
1816*43205Sbostic refrig(lvals)
1817*43205Sbostic elist *lvals;
1818*43205Sbostic {
1819*43205Sbostic   dvlist = NULL;
1820*43205Sbostic   refriglvals(lvals);
1821*43205Sbostic   return;
1822*43205Sbostic }
1823*43205Sbostic 
1824*43205Sbostic 
1825*43205Sbostic 
1826*43205Sbostic ftnint
1827*43205Sbostic indexer(ap)
1828*43205Sbostic aelt *ap;
1829*43205Sbostic {
1830*43205Sbostic   static char *badvar = "bad variable in indexer";
1831*43205Sbostic   static char *boundserror = "subscript out of bounds";
1832*43205Sbostic 
1833*43205Sbostic   register ftnint index;
1834*43205Sbostic   register vlist *sp;
1835*43205Sbostic   register Namep np;
1836*43205Sbostic   register struct Dimblock *dp;
1837*43205Sbostic   register int i;
1838*43205Sbostic   register dvalue *vp;
1839*43205Sbostic   register ftnint size;
1840*43205Sbostic   ftnint sub[MAXDIM];
1841*43205Sbostic 
1842*43205Sbostic   sp = ap->subs;
1843*43205Sbostic   if (sp == NULL) return (0);
1844*43205Sbostic 
1845*43205Sbostic   np = ap->var;
1846*43205Sbostic   dp = np->vdim;
1847*43205Sbostic 
1848*43205Sbostic   if (dp == NULL)
1849*43205Sbostic     fatal(badvar);
1850*43205Sbostic 
1851*43205Sbostic   i = 0;
1852*43205Sbostic   while (sp != NULL)
1853*43205Sbostic     {
1854*43205Sbostic       vp = (dvalue *) evalvexpr(sp->val);
1855*43205Sbostic 
1856*43205Sbostic       if (vp->status == NORMAL)
1857*43205Sbostic 	sub[i++] = vp->value;
1858*43205Sbostic       else if ((MININT + MAXINT == -1) && vp->status == MINLESS1)
1859*43205Sbostic 	sub[i++] = MININT;
1860*43205Sbostic       else
1861*43205Sbostic 	{
1862*43205Sbostic 	  frvexpr((vexpr *) vp);
1863*43205Sbostic 	  return (-1);
1864*43205Sbostic 	}
1865*43205Sbostic 
1866*43205Sbostic       frvexpr((vexpr *) vp);
1867*43205Sbostic       sp = sp->next;
1868*43205Sbostic     }
1869*43205Sbostic 
1870*43205Sbostic   index = sub[--i];
1871*43205Sbostic   while (i-- > 0)
1872*43205Sbostic     {
1873*43205Sbostic       size = dp->dims[i].dimsize->constblock.const.ci;
1874*43205Sbostic       index = sub[i] + index * size;
1875*43205Sbostic     }
1876*43205Sbostic 
1877*43205Sbostic   index -= dp->baseoffset->constblock.const.ci;
1878*43205Sbostic 
1879*43205Sbostic   if (index < 0 || index >= dp->nelt->constblock.const.ci)
1880*43205Sbostic     {
1881*43205Sbostic       err(boundserror);
1882*43205Sbostic       return (-1);
1883*43205Sbostic     }
1884*43205Sbostic 
1885*43205Sbostic   return (index);
1886*43205Sbostic }
1887*43205Sbostic 
1888*43205Sbostic 
1889*43205Sbostic 
1890*43205Sbostic savedata(lvals, rvals)
1891*43205Sbostic elist *lvals;
1892*43205Sbostic vallist *rvals;
1893*43205Sbostic {
1894*43205Sbostic   static char *toomany = "more data values than data items";
1895*43205Sbostic 
1896*43205Sbostic   register elist *top;
1897*43205Sbostic 
1898*43205Sbostic   dataerror = NO;
1899*43205Sbostic   badvalue = NO;
1900*43205Sbostic 
1901*43205Sbostic   lvals = revelist(lvals);
1902*43205Sbostic   grvals = revrvals(rvals);
1903*43205Sbostic 
1904*43205Sbostic   refrig(lvals);
1905*43205Sbostic 
1906*43205Sbostic   if (!dataerror)
1907*43205Sbostic     outdata(lvals);
1908*43205Sbostic 
1909*43205Sbostic   frelist(lvals);
1910*43205Sbostic 
1911*43205Sbostic   while (grvals != NULL && dataerror == NO)
1912*43205Sbostic     {
1913*43205Sbostic       if (grvals->status != NORMAL)
1914*43205Sbostic 	dataerror = YES;
1915*43205Sbostic       else if (grvals->repl <= 0)
1916*43205Sbostic         grvals = grvals->next;
1917*43205Sbostic       else
1918*43205Sbostic 	{
1919*43205Sbostic 	  err(toomany);
1920*43205Sbostic 	  dataerror = YES;
1921*43205Sbostic 	}
1922*43205Sbostic     }
1923*43205Sbostic 
1924*43205Sbostic   frvallist(grvals);
1925*43205Sbostic 
1926*43205Sbostic   return;
1927*43205Sbostic }
1928*43205Sbostic 
1929*43205Sbostic 
1930*43205Sbostic 
1931*43205Sbostic setdfiles(np)
1932*43205Sbostic register Namep np;
1933*43205Sbostic {
1934*43205Sbostic   register struct Extsym *cp;
1935*43205Sbostic   register struct Equivblock *ep;
1936*43205Sbostic   register int stg;
1937*43205Sbostic   register int type;
1938*43205Sbostic   register ftnint typelen;
1939*43205Sbostic   register ftnint nelt;
1940*43205Sbostic   register ftnint varsize;
1941*43205Sbostic 
1942*43205Sbostic   stg = np->vstg;
1943*43205Sbostic 
1944*43205Sbostic   if (stg == STGBSS || stg == STGINIT)
1945*43205Sbostic     {
1946*43205Sbostic       datafile = vdatafile;
1947*43205Sbostic       chkfile = vchkfile;
1948*43205Sbostic       if (np->init == YES)
1949*43205Sbostic 	base = np->initoffset;
1950*43205Sbostic       else
1951*43205Sbostic 	{
1952*43205Sbostic 	  np->init = YES;
1953*43205Sbostic 	  np->initoffset = base = vdatahwm;
1954*43205Sbostic 	  if (np->vdim != NULL)
1955*43205Sbostic 	    nelt = np->vdim->nelt->constblock.const.ci;
1956*43205Sbostic 	  else
1957*43205Sbostic 	    nelt = 1;
1958*43205Sbostic 	  type = np->vtype;
1959*43205Sbostic 	  if (type == TYCHAR)
1960*43205Sbostic 	    typelen = np->vleng->constblock.const.ci;
1961*43205Sbostic 	  else if (type == TYLOGICAL)
1962*43205Sbostic 	    typelen = typesize[tylogical];
1963*43205Sbostic 	  else
1964*43205Sbostic 	    typelen = typesize[type];
1965*43205Sbostic 	  varsize = nelt * typelen;
1966*43205Sbostic 	  vdatahwm += varsize;
1967*43205Sbostic 	}
1968*43205Sbostic     }
1969*43205Sbostic   else if (stg == STGEQUIV)
1970*43205Sbostic     {
1971*43205Sbostic       datafile = vdatafile;
1972*43205Sbostic       chkfile = vchkfile;
1973*43205Sbostic       ep = &eqvclass[np->vardesc.varno];
1974*43205Sbostic       if (ep->init == YES)
1975*43205Sbostic 	base = ep->initoffset;
1976*43205Sbostic       else
1977*43205Sbostic 	{
1978*43205Sbostic 	  ep->init = YES;
1979*43205Sbostic 	  ep->initoffset = base = vdatahwm;
1980*43205Sbostic 	  vdatahwm += ep->eqvleng;
1981*43205Sbostic 	}
1982*43205Sbostic       base += np->voffset;
1983*43205Sbostic     }
1984*43205Sbostic   else if (stg == STGCOMMON)
1985*43205Sbostic     {
1986*43205Sbostic       datafile = cdatafile;
1987*43205Sbostic       chkfile = cchkfile;
1988*43205Sbostic       cp = &extsymtab[np->vardesc.varno];
1989*43205Sbostic       if (cp->init == YES)
1990*43205Sbostic 	base = cp->initoffset;
1991*43205Sbostic       else
1992*43205Sbostic 	{
1993*43205Sbostic 	  cp->init = YES;
1994*43205Sbostic 	  cp->initoffset = base = cdatahwm;
1995*43205Sbostic 	  cdatahwm += cp->maxleng;
1996*43205Sbostic 	}
1997*43205Sbostic       base += np->voffset;
1998*43205Sbostic     }
1999*43205Sbostic 
2000*43205Sbostic   return;
2001*43205Sbostic }
2002*43205Sbostic 
2003*43205Sbostic 
2004*43205Sbostic 
2005*43205Sbostic wrtdata(offset, repl, len, const)
2006*43205Sbostic long offset;
2007*43205Sbostic ftnint repl;
2008*43205Sbostic ftnint len;
2009*43205Sbostic char *const;
2010*43205Sbostic {
2011*43205Sbostic   static char *badoffset = "bad offset in wrtdata";
2012*43205Sbostic   static char *toomuch = "too much data";
2013*43205Sbostic   static char *readerror = "read error on tmp file";
2014*43205Sbostic   static char *writeerror = "write error on tmp file";
2015*43205Sbostic   static char *seekerror = "seek error on tmp file";
2016*43205Sbostic 
2017*43205Sbostic   register ftnint k;
2018*43205Sbostic   long lastbyte;
2019*43205Sbostic   int bitpos;
2020*43205Sbostic   long chkoff;
2021*43205Sbostic   long lastoff;
2022*43205Sbostic   long chklen;
2023*43205Sbostic   long pos;
2024*43205Sbostic   int n;
2025*43205Sbostic   ftnint nbytes;
2026*43205Sbostic   int mask;
2027*43205Sbostic   register int i;
2028*43205Sbostic   char overlap;
2029*43205Sbostic   char allzero;
2030*43205Sbostic   char buff[BUFSIZ];
2031*43205Sbostic 
2032*43205Sbostic   if (offset < 0)
2033*43205Sbostic     fatal(badoffset);
2034*43205Sbostic 
2035*43205Sbostic   overlap = NO;
2036*43205Sbostic 
2037*43205Sbostic   k = repl * len;
2038*43205Sbostic   lastbyte = offset + k - 1;
2039*43205Sbostic   if (lastbyte < 0)
2040*43205Sbostic     {
2041*43205Sbostic       err(toomuch);
2042*43205Sbostic       dataerror = YES;
2043*43205Sbostic       return;
2044*43205Sbostic     }
2045*43205Sbostic 
2046*43205Sbostic   bitpos = offset % BYTESIZE;
2047*43205Sbostic   chkoff = offset/BYTESIZE;
2048*43205Sbostic   lastoff = lastbyte/BYTESIZE;
2049*43205Sbostic   chklen = lastoff - chkoff + 1;
2050*43205Sbostic 
2051*43205Sbostic   pos = lseek(chkfile, chkoff, 0);
2052*43205Sbostic   if (pos == -1)
2053*43205Sbostic     {
2054*43205Sbostic       err(seekerror);
2055*43205Sbostic       done(1);
2056*43205Sbostic     }
2057*43205Sbostic 
2058*43205Sbostic   while (k > 0)
2059*43205Sbostic     {
2060*43205Sbostic       if (chklen <= BUFSIZ)
2061*43205Sbostic 	n = chklen;
2062*43205Sbostic       else
2063*43205Sbostic 	{
2064*43205Sbostic 	  n = BUFSIZ;
2065*43205Sbostic 	  chklen -= BUFSIZ;
2066*43205Sbostic 	}
2067*43205Sbostic 
2068*43205Sbostic       nbytes = read(chkfile, buff, n);
2069*43205Sbostic       if (nbytes < 0)
2070*43205Sbostic 	{
2071*43205Sbostic 	  err(readerror);
2072*43205Sbostic 	  done(1);
2073*43205Sbostic 	}
2074*43205Sbostic 
2075*43205Sbostic       if (nbytes == 0)
2076*43205Sbostic 	buff[0] = '\0';
2077*43205Sbostic 
2078*43205Sbostic       if (nbytes < n)
2079*43205Sbostic 	buff[ n-1 ] = '\0';
2080*43205Sbostic 
2081*43205Sbostic       i = 0;
2082*43205Sbostic 
2083*43205Sbostic       if (bitpos > 0)
2084*43205Sbostic 	{
2085*43205Sbostic 	  while (k > 0 && bitpos < BYTESIZE)
2086*43205Sbostic 	    {
2087*43205Sbostic 	      mask = 1 << bitpos;
2088*43205Sbostic 
2089*43205Sbostic 	      if (mask & buff[0])
2090*43205Sbostic 		overlap = YES;
2091*43205Sbostic 	      else
2092*43205Sbostic 		buff[0] |= mask;
2093*43205Sbostic 
2094*43205Sbostic 	      k--;
2095*43205Sbostic 	      bitpos++;
2096*43205Sbostic 	    }
2097*43205Sbostic 
2098*43205Sbostic 	  if (bitpos == BYTESIZE)
2099*43205Sbostic 	    {
2100*43205Sbostic 	      bitpos = 0;
2101*43205Sbostic 	      i++;
2102*43205Sbostic 	    }
2103*43205Sbostic 	}
2104*43205Sbostic 
2105*43205Sbostic       while (i < nbytes && overlap == NO)
2106*43205Sbostic 	{
2107*43205Sbostic 	  if (buff[i] == 0 && k >= BYTESIZE)
2108*43205Sbostic 	    {
2109*43205Sbostic 	      buff[i++] = MAXBYTE;
2110*43205Sbostic 	      k -= BYTESIZE;
2111*43205Sbostic 	    }
2112*43205Sbostic 	  else if (k < BYTESIZE)
2113*43205Sbostic 	    {
2114*43205Sbostic 	      while (k-- > 0)
2115*43205Sbostic 		{
2116*43205Sbostic 		  mask = 1 << k;
2117*43205Sbostic 		  if (mask & buff[i])
2118*43205Sbostic 		    overlap = YES;
2119*43205Sbostic 		  else
2120*43205Sbostic 		    buff[i] |= mask;
2121*43205Sbostic 		}
2122*43205Sbostic 	      i++;
2123*43205Sbostic 	    }
2124*43205Sbostic 	  else
2125*43205Sbostic 	    {
2126*43205Sbostic 	      overlap = YES;
2127*43205Sbostic 	      buff[i++] = MAXBYTE;
2128*43205Sbostic 	      k -= BYTESIZE;
2129*43205Sbostic 	    }
2130*43205Sbostic 	}
2131*43205Sbostic 
2132*43205Sbostic       while (i < n)
2133*43205Sbostic 	{
2134*43205Sbostic 	  if (k >= BYTESIZE)
2135*43205Sbostic 	    {
2136*43205Sbostic 	      buff[i++] = MAXBYTE;
2137*43205Sbostic 	      k -= BYTESIZE;
2138*43205Sbostic 	    }
2139*43205Sbostic 	  else
2140*43205Sbostic 	    {
2141*43205Sbostic 	      while (k-- > 0)
2142*43205Sbostic 		{
2143*43205Sbostic 		  mask = 1 << k;
2144*43205Sbostic 		  buff[i] |= mask;
2145*43205Sbostic 		}
2146*43205Sbostic 	      i++;
2147*43205Sbostic 	    }
2148*43205Sbostic 	}
2149*43205Sbostic 
2150*43205Sbostic       pos = lseek(chkfile, -nbytes, 1);
2151*43205Sbostic       if (pos == -1)
2152*43205Sbostic 	{
2153*43205Sbostic 	  err(seekerror);
2154*43205Sbostic 	  done(1);
2155*43205Sbostic 	}
2156*43205Sbostic 
2157*43205Sbostic       nbytes = write(chkfile, buff, n);
2158*43205Sbostic       if (nbytes != n)
2159*43205Sbostic 	{
2160*43205Sbostic 	  err(writeerror);
2161*43205Sbostic 	  done(1);
2162*43205Sbostic 	}
2163*43205Sbostic     }
2164*43205Sbostic 
2165*43205Sbostic   if (overlap == NO)
2166*43205Sbostic     {
2167*43205Sbostic       allzero = YES;
2168*43205Sbostic       k = len;
2169*43205Sbostic 
2170*43205Sbostic       while (k > 0 && allzero != NO)
2171*43205Sbostic 	if (const[--k] != 0) allzero = NO;
2172*43205Sbostic 
2173*43205Sbostic       if (allzero == YES)
2174*43205Sbostic 	return;
2175*43205Sbostic     }
2176*43205Sbostic 
2177*43205Sbostic   pos = lseek(datafile, offset, 0);
2178*43205Sbostic   if (pos == -1)
2179*43205Sbostic     {
2180*43205Sbostic       err(seekerror);
2181*43205Sbostic       done(1);
2182*43205Sbostic     }
2183*43205Sbostic 
2184*43205Sbostic   k = repl;
2185*43205Sbostic   while (k-- > 0)
2186*43205Sbostic     {
2187*43205Sbostic       nbytes = write(datafile, const, len);
2188*43205Sbostic       if (nbytes != len)
2189*43205Sbostic 	{
2190*43205Sbostic 	  err(writeerror);
2191*43205Sbostic 	  done(1);
2192*43205Sbostic 	}
2193*43205Sbostic     }
2194*43205Sbostic 
2195*43205Sbostic   if (overlap) overlapflag = YES;
2196*43205Sbostic 
2197*43205Sbostic   return;
2198*43205Sbostic }
2199*43205Sbostic 
2200*43205Sbostic 
2201*43205Sbostic 
2202*43205Sbostic Constp
2203*43205Sbostic getdatum()
2204*43205Sbostic {
2205*43205Sbostic   static char *toofew = "more data items than data values";
2206*43205Sbostic 
2207*43205Sbostic   register vallist *t;
2208*43205Sbostic 
2209*43205Sbostic   while (grvals != NULL)
2210*43205Sbostic     {
2211*43205Sbostic       if (grvals->status != NORMAL)
2212*43205Sbostic 	{
2213*43205Sbostic 	  dataerror = YES;
2214*43205Sbostic 	  return (NULL);
2215*43205Sbostic 	}
2216*43205Sbostic       else if (grvals->repl > 0)
2217*43205Sbostic 	{
2218*43205Sbostic 	  grvals->repl--;
2219*43205Sbostic 	  return (grvals->value);
2220*43205Sbostic 	}
2221*43205Sbostic       else
2222*43205Sbostic 	{
2223*43205Sbostic 	  badvalue = 0;
2224*43205Sbostic 	  frexpr ((tagptr) grvals->value);
2225*43205Sbostic 	  t = grvals;
2226*43205Sbostic 	  grvals = t->next;
2227*43205Sbostic 	  free((char *) t);
2228*43205Sbostic 	}
2229*43205Sbostic     }
2230*43205Sbostic 
2231*43205Sbostic   err(toofew);
2232*43205Sbostic   dataerror = YES;
2233*43205Sbostic   return (NULL);
2234*43205Sbostic }
2235*43205Sbostic 
2236*43205Sbostic 
2237*43205Sbostic 
2238*43205Sbostic outdata(lvals)
2239*43205Sbostic elist *lvals;
2240*43205Sbostic {
2241*43205Sbostic   register elist *top;
2242*43205Sbostic 
2243*43205Sbostic   top = lvals;
2244*43205Sbostic 
2245*43205Sbostic   while (top != NULL && dataerror == NO)
2246*43205Sbostic     {
2247*43205Sbostic       if (top->elt->tag == SIMPLE)
2248*43205Sbostic 	outaelt((aelt *) top->elt);
2249*43205Sbostic       else
2250*43205Sbostic 	outdolist((dolist *) top->elt);
2251*43205Sbostic 
2252*43205Sbostic       top = top->next;
2253*43205Sbostic     }
2254*43205Sbostic 
2255*43205Sbostic   return;
2256*43205Sbostic }
2257*43205Sbostic 
2258*43205Sbostic 
2259*43205Sbostic 
2260*43205Sbostic outaelt(ap)
2261*43205Sbostic aelt *ap;
2262*43205Sbostic {
2263*43205Sbostic   static char *toofew = "more data items than data values";
2264*43205Sbostic   static char *boundserror = "substring expression out of bounds";
2265*43205Sbostic   static char *order = "substring expressions out of order";
2266*43205Sbostic 
2267*43205Sbostic   register Namep np;
2268*43205Sbostic   register long soffset;
2269*43205Sbostic   register dvalue *lwb;
2270*43205Sbostic   register dvalue *upb;
2271*43205Sbostic   register Constp const;
2272*43205Sbostic   register int k;
2273*43205Sbostic   register vallist *t;
2274*43205Sbostic   register int type;
2275*43205Sbostic   register ftnint typelen;
2276*43205Sbostic   register ftnint repl;
2277*43205Sbostic 
2278*43205Sbostic   extern char *packbytes();
2279*43205Sbostic 
2280*43205Sbostic   np = ap->var;
2281*43205Sbostic   setdfiles(np);
2282*43205Sbostic 
2283*43205Sbostic   type = np->vtype;
2284*43205Sbostic 
2285*43205Sbostic   if (type == TYCHAR)
2286*43205Sbostic     typelen = np->vleng->constblock.const.ci;
2287*43205Sbostic   else if (type == TYLOGICAL)
2288*43205Sbostic     typelen = typesize[tylogical];
2289*43205Sbostic   else
2290*43205Sbostic     typelen = typesize[type];
2291*43205Sbostic 
2292*43205Sbostic   if (ap->subs != NULL || np->vdim == NULL)
2293*43205Sbostic     {
2294*43205Sbostic       soffset = indexer(ap);
2295*43205Sbostic       if (soffset == -1)
2296*43205Sbostic 	{
2297*43205Sbostic 	  dataerror = YES;
2298*43205Sbostic 	  return;
2299*43205Sbostic 	}
2300*43205Sbostic 
2301*43205Sbostic       soffset = soffset * typelen;
2302*43205Sbostic 
2303*43205Sbostic       if (ap->range != NULL)
2304*43205Sbostic 	{
2305*43205Sbostic 	  lwb = (dvalue *) evalvexpr(ap->range->low);
2306*43205Sbostic 	  upb = (dvalue *) evalvexpr(ap->range->high);
2307*43205Sbostic 	  if (lwb->status == ERRVAL || upb->status == ERRVAL)
2308*43205Sbostic 	    {
2309*43205Sbostic 	      frvexpr((vexpr *) lwb);
2310*43205Sbostic 	      frvexpr((vexpr *) upb);
2311*43205Sbostic 	      dataerror = YES;
2312*43205Sbostic 	      return;
2313*43205Sbostic 	    }
2314*43205Sbostic 
2315*43205Sbostic 	  if (lwb->status != NORMAL ||
2316*43205Sbostic 	      lwb->value < 1 ||
2317*43205Sbostic 	      lwb->value > typelen ||
2318*43205Sbostic 	      upb->status != NORMAL ||
2319*43205Sbostic 	      upb->value < 1 ||
2320*43205Sbostic 	      upb->value > typelen)
2321*43205Sbostic 	    {
2322*43205Sbostic 	      err(boundserror);
2323*43205Sbostic 	      frvexpr((vexpr *) lwb);
2324*43205Sbostic 	      frvexpr((vexpr *) upb);
2325*43205Sbostic 	      dataerror = YES;
2326*43205Sbostic 	      return;
2327*43205Sbostic 	    }
2328*43205Sbostic 
2329*43205Sbostic 	  if (lwb->value > upb->value)
2330*43205Sbostic 	    {
2331*43205Sbostic 	      err(order);
2332*43205Sbostic 	      frvexpr((vexpr *) lwb);
2333*43205Sbostic 	      frvexpr((vexpr *) upb);
2334*43205Sbostic 	      dataerror = YES;
2335*43205Sbostic 	      return;
2336*43205Sbostic 	    }
2337*43205Sbostic 
2338*43205Sbostic 	  soffset = soffset + lwb->value - 1;
2339*43205Sbostic 	  typelen = upb->value - lwb->value + 1;
2340*43205Sbostic 	  frvexpr((vexpr *) lwb);
2341*43205Sbostic 	  frvexpr((vexpr *) upb);
2342*43205Sbostic 	}
2343*43205Sbostic 
2344*43205Sbostic       const = getdatum();
2345*43205Sbostic       if (const == NULL || !ISCONST(const))
2346*43205Sbostic 	return;
2347*43205Sbostic 
2348*43205Sbostic       const = (Constp) convconst(type, typelen, const);
2349*43205Sbostic       if (const == NULL || !ISCONST(const))
2350*43205Sbostic 	{
2351*43205Sbostic 	  frexpr((tagptr) const);
2352*43205Sbostic 	  return;
2353*43205Sbostic 	}
2354*43205Sbostic 
2355*43205Sbostic       if (type == TYCHAR)
2356*43205Sbostic 	wrtdata(base + soffset, 1, typelen, const->const.ccp);
2357*43205Sbostic       else
2358*43205Sbostic 	wrtdata(base + soffset, 1, typelen, packbytes(const));
2359*43205Sbostic 
2360*43205Sbostic       frexpr((tagptr) const);
2361*43205Sbostic     }
2362*43205Sbostic   else
2363*43205Sbostic     {
2364*43205Sbostic       soffset = 0;
2365*43205Sbostic       k = np->vdim->nelt->constblock.const.ci;
2366*43205Sbostic       while (k > 0 && dataerror == NO)
2367*43205Sbostic 	{
2368*43205Sbostic 	  if (grvals == NULL)
2369*43205Sbostic 	    {
2370*43205Sbostic 	      err(toofew);
2371*43205Sbostic 	      dataerror = YES;
2372*43205Sbostic 	    }
2373*43205Sbostic 	  else if (grvals->status != NORMAL)
2374*43205Sbostic 	    dataerror = YES;
2375*43205Sbostic 	  else if (grvals-> repl <= 0)
2376*43205Sbostic 	    {
2377*43205Sbostic 	      badvalue = 0;
2378*43205Sbostic 	      frexpr((tagptr) grvals->value);
2379*43205Sbostic 	      t = grvals;
2380*43205Sbostic 	      grvals = t->next;
2381*43205Sbostic 	      free((char *) t);
2382*43205Sbostic 	    }
2383*43205Sbostic 	  else
2384*43205Sbostic 	    {
2385*43205Sbostic 	      const = grvals->value;
2386*43205Sbostic 	      if (const == NULL || !ISCONST(const))
2387*43205Sbostic 		{
2388*43205Sbostic 		  dataerror = YES;
2389*43205Sbostic 		}
2390*43205Sbostic 	      else
2391*43205Sbostic 		{
2392*43205Sbostic 		  const = (Constp) convconst(type, typelen, const);
2393*43205Sbostic 		  if (const == NULL || !ISCONST(const))
2394*43205Sbostic 		    {
2395*43205Sbostic 		      dataerror = YES;
2396*43205Sbostic 		      frexpr((tagptr) const);
2397*43205Sbostic 		    }
2398*43205Sbostic 		  else
2399*43205Sbostic 		    {
2400*43205Sbostic 		      if (k > grvals->repl)
2401*43205Sbostic 			repl = grvals->repl;
2402*43205Sbostic 		      else
2403*43205Sbostic 			repl = k;
2404*43205Sbostic 
2405*43205Sbostic 		      grvals->repl -= repl;
2406*43205Sbostic 		      k -= repl;
2407*43205Sbostic 
2408*43205Sbostic 		      if (type == TYCHAR)
2409*43205Sbostic 			wrtdata(base+soffset, repl, typelen, const->const.ccp);
2410*43205Sbostic 		      else
2411*43205Sbostic 			wrtdata(base+soffset, repl, typelen, packbytes(const));
2412*43205Sbostic 
2413*43205Sbostic 		      soffset = soffset + repl * typelen;
2414*43205Sbostic 
2415*43205Sbostic 		      frexpr((tagptr) const);
2416*43205Sbostic 		    }
2417*43205Sbostic 		}
2418*43205Sbostic 	    }
2419*43205Sbostic 	}
2420*43205Sbostic     }
2421*43205Sbostic 
2422*43205Sbostic   return;
2423*43205Sbostic }
2424*43205Sbostic 
2425*43205Sbostic 
2426*43205Sbostic 
2427*43205Sbostic outdolist(dp)
2428*43205Sbostic dolist *dp;
2429*43205Sbostic {
2430*43205Sbostic   static char *zerostep = "zero step in implied-DO";
2431*43205Sbostic   static char *order = "zero iteration count in implied-DO";
2432*43205Sbostic 
2433*43205Sbostic   register dvalue *e1, *e2, *e3;
2434*43205Sbostic   register int direction;
2435*43205Sbostic   register dvalue *dv;
2436*43205Sbostic   register int done;
2437*43205Sbostic   register int addin;
2438*43205Sbostic   register int ts;
2439*43205Sbostic   register ftnint tv;
2440*43205Sbostic 
2441*43205Sbostic   e1 = (dvalue *) evalvexpr(dp->init);
2442*43205Sbostic   e2 = (dvalue *) evalvexpr(dp->limit);
2443*43205Sbostic   e3 = (dvalue *) evalvexpr(dp->step);
2444*43205Sbostic 
2445*43205Sbostic   if (e1->status == ERRVAL ||
2446*43205Sbostic       e2->status == ERRVAL ||
2447*43205Sbostic       e3->status == ERRVAL)
2448*43205Sbostic     {
2449*43205Sbostic       dataerror = YES;
2450*43205Sbostic       goto ret;
2451*43205Sbostic     }
2452*43205Sbostic 
2453*43205Sbostic   if (e1->status == NORMAL)
2454*43205Sbostic     {
2455*43205Sbostic       if (e2->status == NORMAL)
2456*43205Sbostic 	{
2457*43205Sbostic 	  if (e1->value < e2->value)
2458*43205Sbostic 	    direction = 1;
2459*43205Sbostic 	  else if (e1->value > e2->value)
2460*43205Sbostic 	    direction = -1;
2461*43205Sbostic 	  else
2462*43205Sbostic 	    direction = 0;
2463*43205Sbostic 	}
2464*43205Sbostic       else if (e2->status == MAXPLUS1)
2465*43205Sbostic 	direction = 1;
2466*43205Sbostic       else
2467*43205Sbostic 	direction = -1;
2468*43205Sbostic     }
2469*43205Sbostic   else if (e1->status == MAXPLUS1)
2470*43205Sbostic     {
2471*43205Sbostic       if (e2->status == MAXPLUS1)
2472*43205Sbostic 	direction = 0;
2473*43205Sbostic       else
2474*43205Sbostic 	direction = -1;
2475*43205Sbostic     }
2476*43205Sbostic   else
2477*43205Sbostic     {
2478*43205Sbostic       if (e2->status == MINLESS1)
2479*43205Sbostic 	direction = 0;
2480*43205Sbostic       else
2481*43205Sbostic 	direction = 1;
2482*43205Sbostic     }
2483*43205Sbostic 
2484*43205Sbostic   if (e3->status == NORMAL && e3->value == 0)
2485*43205Sbostic     {
2486*43205Sbostic       err(zerostep);
2487*43205Sbostic       dataerror = YES;
2488*43205Sbostic       goto ret;
2489*43205Sbostic     }
2490*43205Sbostic   else if (e3->status == MAXPLUS1 ||
2491*43205Sbostic 	   (e3->status == NORMAL && e3->value > 0))
2492*43205Sbostic     {
2493*43205Sbostic       if (direction == -1)
2494*43205Sbostic 	{
2495*43205Sbostic 	  warn(order);
2496*43205Sbostic 	  goto ret;
2497*43205Sbostic 	}
2498*43205Sbostic     }
2499*43205Sbostic   else
2500*43205Sbostic     {
2501*43205Sbostic       if (direction == 1)
2502*43205Sbostic 	{
2503*43205Sbostic 	  warn(order);
2504*43205Sbostic 	  goto ret;
2505*43205Sbostic 	}
2506*43205Sbostic     }
2507*43205Sbostic 
2508*43205Sbostic   dv = (dvalue *) dp->dovar;
2509*43205Sbostic   dv->status = e1->status;
2510*43205Sbostic   dv->value = e1->value;
2511*43205Sbostic 
2512*43205Sbostic   done = NO;
2513*43205Sbostic   while (done == NO && dataerror == NO)
2514*43205Sbostic     {
2515*43205Sbostic       outdata(dp->elts);
2516*43205Sbostic 
2517*43205Sbostic       if (e3->status == NORMAL && dv->status == NORMAL)
2518*43205Sbostic 	{
2519*43205Sbostic 	  addints(e3->value, dv->value);
2520*43205Sbostic 	  dv->status = rstatus;
2521*43205Sbostic 	  dv->value = rvalue;
2522*43205Sbostic 	}
2523*43205Sbostic       else
2524*43205Sbostic 	{
2525*43205Sbostic 	  if (e3->status != NORMAL)
2526*43205Sbostic 	    {
2527*43205Sbostic 	      if (e3->status == MAXPLUS1)
2528*43205Sbostic 		addin = MAXPLUS1;
2529*43205Sbostic 	      else
2530*43205Sbostic 		addin = MINLESS1;
2531*43205Sbostic 	      ts = dv->status;
2532*43205Sbostic 	      tv = dv->value;
2533*43205Sbostic 	    }
2534*43205Sbostic 	  else
2535*43205Sbostic 	    {
2536*43205Sbostic 	      if (dv->status == MAXPLUS1)
2537*43205Sbostic 		addin = MAXPLUS1;
2538*43205Sbostic 	      else
2539*43205Sbostic 		addin = MINLESS1;
2540*43205Sbostic 	      ts = e3->status;
2541*43205Sbostic 	      tv = e3->value;
2542*43205Sbostic 	    }
2543*43205Sbostic 
2544*43205Sbostic 	  if (addin == MAXPLUS1)
2545*43205Sbostic 	    {
2546*43205Sbostic 	      if (ts == MAXPLUS1 || (ts == NORMAL && tv > 0))
2547*43205Sbostic 		dv->status = ERRVAL;
2548*43205Sbostic 	      else if (ts == NORMAL && tv == 0)
2549*43205Sbostic 		dv->status = MAXPLUS1;
2550*43205Sbostic 	      else if (ts == NORMAL)
2551*43205Sbostic 		{
2552*43205Sbostic 		  dv->status = NORMAL;
2553*43205Sbostic 		  dv->value = tv + MAXINT;
2554*43205Sbostic 		  dv->value++;
2555*43205Sbostic 		}
2556*43205Sbostic 	      else
2557*43205Sbostic 		{
2558*43205Sbostic 		  dv->status = NORMAL;
2559*43205Sbostic 		  dv->value = 0;
2560*43205Sbostic 		}
2561*43205Sbostic 	    }
2562*43205Sbostic 	  else
2563*43205Sbostic 	    {
2564*43205Sbostic 	      if (ts == MINLESS1 || (ts == NORMAL && tv < 0))
2565*43205Sbostic 		dv->status = ERRVAL;
2566*43205Sbostic 	      else if (ts == NORMAL && tv == 0)
2567*43205Sbostic 		dv->status = MINLESS1;
2568*43205Sbostic 	      else if (ts == NORMAL)
2569*43205Sbostic 		{
2570*43205Sbostic 		  dv->status = NORMAL;
2571*43205Sbostic 		  dv->value = tv - MAXINT;
2572*43205Sbostic 		  dv->value--;
2573*43205Sbostic 		}
2574*43205Sbostic 	      else
2575*43205Sbostic 		{
2576*43205Sbostic 		  dv->status = NORMAL;
2577*43205Sbostic 		  dv->value = 0;
2578*43205Sbostic 		}
2579*43205Sbostic 	    }
2580*43205Sbostic 	}
2581*43205Sbostic 
2582*43205Sbostic       if (dv->status == ERRVAL)
2583*43205Sbostic 	done = YES;
2584*43205Sbostic       else if (direction > 0)
2585*43205Sbostic 	{
2586*43205Sbostic 	  if (e2->status == NORMAL)
2587*43205Sbostic 	    {
2588*43205Sbostic 	      if (dv->status == MAXPLUS1 ||
2589*43205Sbostic 		  (dv->status == NORMAL && dv->value > e2->value))
2590*43205Sbostic 		done = YES;
2591*43205Sbostic 	    }
2592*43205Sbostic 	}
2593*43205Sbostic       else if (direction < 0)
2594*43205Sbostic 	{
2595*43205Sbostic 	  if (e2->status == NORMAL)
2596*43205Sbostic 	    {
2597*43205Sbostic 	      if (dv->status == MINLESS1 ||
2598*43205Sbostic 		  (dv->status == NORMAL && dv->value < e2->value))
2599*43205Sbostic 		done = YES;
2600*43205Sbostic 	    }
2601*43205Sbostic 	}
2602*43205Sbostic       else
2603*43205Sbostic 	done = YES;
2604*43205Sbostic     }
2605*43205Sbostic 
2606*43205Sbostic ret:
2607*43205Sbostic   frvexpr((vexpr *) e1);
2608*43205Sbostic   frvexpr((vexpr *) e2);
2609*43205Sbostic   frvexpr((vexpr *) e3);
2610*43205Sbostic   return;
2611*43205Sbostic }
2612