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