xref: /csrg-svn/usr.bin/f77/pass1.vax/data.c (revision 47955)
1*47955Sbostic /*-
2*47955Sbostic  * Copyright (c) 1980 The Regents of the University of California.
3*47955Sbostic  * All rights reserved.
4*47955Sbostic  *
5*47955Sbostic  * %sccs.include.proprietary.c%
622803Smckusick  */
722803Smckusick 
822803Smckusick #ifndef lint
9*47955Sbostic static char sccsid[] = "@(#)data.c	5.3 (Berkeley) 04/12/91";
10*47955Sbostic #endif /* not lint */
1122803Smckusick 
1222803Smckusick /*
1322803Smckusick  * data.c
1422803Smckusick  *
1522803Smckusick  * Routines for handling DATA statements, f77 compiler, 4.2 BSD.
1622803Smckusick  *
1722803Smckusick  * University of Utah CS Dept modification history:
1822803Smckusick  *
1922803Smckusick  * Revision 3.1  84/10/13  01:09:50  donn
2022803Smckusick  * Installed Jerry Berkman's version; added UofU comment header.
2122803Smckusick  *
2222803Smckusick  */
2322803Smckusick 
2422803Smckusick #include "defs.h"
2522803Smckusick #include "data.h"
2622803Smckusick 
2722803Smckusick 
2822803Smckusick /*  global variables  */
2922803Smckusick 
3022803Smckusick flag overlapflag;
3122803Smckusick 
3222803Smckusick 
3322803Smckusick 
3422803Smckusick /*  local variables  */
3522803Smckusick 
3622803Smckusick LOCAL char rstatus;
3722803Smckusick LOCAL ftnint rvalue;
3822803Smckusick LOCAL dovars *dvlist;
3922803Smckusick LOCAL int dataerror;
4022803Smckusick LOCAL vallist *grvals;
4122803Smckusick LOCAL int datafile;
4222803Smckusick LOCAL int chkfile;
4322803Smckusick LOCAL long base;
4422803Smckusick 
4522803Smckusick 
4622803Smckusick 
4722803Smckusick /*  Copied from expr.c  */
4822803Smckusick 
letter(c)4922803Smckusick LOCAL letter(c)
5022803Smckusick register int c;
5122803Smckusick {
5222803Smckusick if( isupper(c) )
5322803Smckusick 	c = tolower(c);
5422803Smckusick return(c - 'a');
5522803Smckusick }
5622803Smckusick 
5722803Smckusick 
5822803Smckusick 
5922803Smckusick vexpr *
cpdvalue(dp)6022803Smckusick cpdvalue(dp)
6122803Smckusick vexpr *dp;
6222803Smckusick {
6322803Smckusick   register dvalue *p;
6422803Smckusick 
6522803Smckusick   if (dp->tag != DVALUE)
6622803Smckusick     badtag("cpdvalue", dp->tag);
6722803Smckusick 
6822803Smckusick   p = ALLOC(Dvalue);
6922803Smckusick   p->tag = DVALUE;
7022803Smckusick   p->status = dp->dvalue.status;
7122803Smckusick   p->value = dp->dvalue.value;
7222803Smckusick 
7322803Smckusick   return ((vexpr *) p);
7422803Smckusick }
7522803Smckusick 
7622803Smckusick 
7722803Smckusick 
frvexpr(vp)7822803Smckusick frvexpr(vp)
7922803Smckusick register vexpr *vp;
8022803Smckusick {
8122803Smckusick   if (vp != NULL)
8222803Smckusick     {
8322803Smckusick       if (vp->tag == DNAME)
8422803Smckusick 	free(vp->dname.repr);
8522803Smckusick       else if (vp->tag == DEXPR)
8622803Smckusick 	{
8722803Smckusick 	  frvexpr(vp->dexpr.left);
8822803Smckusick 	  frvexpr(vp->dexpr.right);
8922803Smckusick 	}
9022803Smckusick 
9122803Smckusick       free((char *) vp);
9222803Smckusick     }
9322803Smckusick 
9422803Smckusick   return;
9522803Smckusick }
9622803Smckusick 
9722803Smckusick 
9822803Smckusick 
frvlist(vp)9922803Smckusick frvlist(vp)
10022803Smckusick register vlist *vp;
10122803Smckusick {
10222803Smckusick   register vlist *t;
10322803Smckusick 
10422803Smckusick   while (vp)
10522803Smckusick     {
10622803Smckusick       t = vp->next;
10722803Smckusick       frvexpr(vp->val);
10822803Smckusick       free((char *) vp);
10922803Smckusick       vp = t;
11022803Smckusick     }
11122803Smckusick 
11222803Smckusick   return;
11322803Smckusick }
11422803Smckusick 
11522803Smckusick 
11622803Smckusick 
frelist(ep)11722803Smckusick frelist(ep)
11822803Smckusick elist *ep;
11922803Smckusick {
12022803Smckusick   register elist *p;
12122803Smckusick   register elist *t;
12222803Smckusick   register aelt *ap;
12322803Smckusick   register dolist *dp;
12422803Smckusick 
12522803Smckusick   p = ep;
12622803Smckusick 
12722803Smckusick   while (p != NULL)
12822803Smckusick     {
12922803Smckusick       if (p->elt->tag == SIMPLE)
13022803Smckusick 	{
13122803Smckusick 	  ap = (aelt *) p->elt;
13222803Smckusick 	  frvlist(ap->subs);
13322803Smckusick 	  if (ap->range != NULL)
13422803Smckusick 	    {
13522803Smckusick 	      frvexpr(ap->range->low);
13622803Smckusick 	      frvexpr(ap->range->high);
13722803Smckusick 	      free((char *) ap->range);
13822803Smckusick 	    }
13922803Smckusick 	  free((char *) ap);
14022803Smckusick 	}
14122803Smckusick       else
14222803Smckusick 	{
14322803Smckusick 	  dp = (dolist *) p->elt;
14422803Smckusick 	  frvexpr(dp->dovar);
14522803Smckusick 	  frvexpr(dp->init);
14622803Smckusick 	  frvexpr(dp->limit);
14722803Smckusick 	  frvexpr(dp->step);
14822803Smckusick 	  frelist(dp->elts);
14922803Smckusick 	  free((char *) dp);
15022803Smckusick 	}
15122803Smckusick 
15222803Smckusick       t = p;
15322803Smckusick       p = p->next;
15422803Smckusick       free((char *) t);
15522803Smckusick     }
15622803Smckusick 
15722803Smckusick   return;
15822803Smckusick }
15922803Smckusick 
16022803Smckusick 
16122803Smckusick 
frvallist(vp)16222803Smckusick frvallist(vp)
16322803Smckusick vallist *vp;
16422803Smckusick {
16522803Smckusick   register vallist *p;
16622803Smckusick   register vallist *t;
16722803Smckusick 
16822803Smckusick   p = vp;
16922803Smckusick   while (p != NULL)
17022803Smckusick     {
17122803Smckusick       frexpr((tagptr) p->value);
17222803Smckusick       t = p;
17322803Smckusick       p = p->next;
17422803Smckusick       free((char *) t);
17522803Smckusick     }
17622803Smckusick 
17722803Smckusick   return;
17822803Smckusick }
17922803Smckusick 
18022803Smckusick 
18122803Smckusick 
revelist(ep)18222803Smckusick elist *revelist(ep)
18322803Smckusick register elist *ep;
18422803Smckusick {
18522803Smckusick   register elist *next;
18622803Smckusick   register elist *t;
18722803Smckusick 
18822803Smckusick   if (ep != NULL)
18922803Smckusick     {
19022803Smckusick       next = ep->next;
19122803Smckusick       ep->next = NULL;
19222803Smckusick 
19322803Smckusick       while (next)
19422803Smckusick 	{
19522803Smckusick 	  t = next->next;
19622803Smckusick 	  next->next = ep;
19722803Smckusick 	  ep = next;
19822803Smckusick 	  next = t;
19922803Smckusick 	}
20022803Smckusick     }
20122803Smckusick 
20222803Smckusick   return (ep);
20322803Smckusick }
20422803Smckusick 
20522803Smckusick 
20622803Smckusick 
revvlist(vp)20722803Smckusick vlist *revvlist(vp)
20822803Smckusick vlist *vp;
20922803Smckusick {
21022803Smckusick   register vlist *p;
21122803Smckusick   register vlist *next;
21222803Smckusick   register vlist *t;
21322803Smckusick 
21422803Smckusick   if (vp == NULL)
21522803Smckusick     p = NULL;
21622803Smckusick   else
21722803Smckusick     {
21822803Smckusick       p = vp;
21922803Smckusick       next = p->next;
22022803Smckusick       p->next = NULL;
22122803Smckusick 
22222803Smckusick       while (next)
22322803Smckusick 	{
22422803Smckusick 	  t = next->next;
22522803Smckusick 	  next->next = p;
22622803Smckusick 	  p = next;
22722803Smckusick 	  next = t;
22822803Smckusick 	}
22922803Smckusick     }
23022803Smckusick 
23122803Smckusick   return (p);
23222803Smckusick }
23322803Smckusick 
23422803Smckusick 
23522803Smckusick 
23622803Smckusick vallist *
revrvals(vp)23722803Smckusick revrvals(vp)
23822803Smckusick vallist *vp;
23922803Smckusick {
24022803Smckusick   register vallist *p;
24122803Smckusick   register vallist *next;
24222803Smckusick   register vallist *t;
24322803Smckusick 
24422803Smckusick   if (vp == NULL)
24522803Smckusick     p = NULL;
24622803Smckusick   else
24722803Smckusick     {
24822803Smckusick       p = vp;
24922803Smckusick       next = p->next;
25022803Smckusick       p->next = NULL;
25122803Smckusick       while (next)
25222803Smckusick 	{
25322803Smckusick 	  t = next->next;
25422803Smckusick 	  next->next = p;
25522803Smckusick 	  p = next;
25622803Smckusick 	  next = t;
25722803Smckusick 	}
25822803Smckusick     }
25922803Smckusick 
26022803Smckusick   return (p);
26122803Smckusick }
26222803Smckusick 
26322803Smckusick 
26422803Smckusick 
prepvexpr(tail,head)26522803Smckusick vlist *prepvexpr(tail, head)
26622803Smckusick vlist *tail;
26722803Smckusick vexpr *head;
26822803Smckusick {
26922803Smckusick   register vlist *p;
27022803Smckusick 
27122803Smckusick   p = ALLOC(Vlist);
27222803Smckusick   p->next = tail;
27322803Smckusick   p->val = head;
27422803Smckusick 
27522803Smckusick   return (p);
27622803Smckusick }
27722803Smckusick 
27822803Smckusick 
27922803Smckusick 
preplval(tail,head)28022803Smckusick elist *preplval(tail, head)
28122803Smckusick elist *tail;
28222803Smckusick delt* head;
28322803Smckusick {
28422803Smckusick   register elist *p;
28522803Smckusick   p = ALLOC(Elist);
28622803Smckusick   p->next = tail;
28722803Smckusick   p->elt = head;
28822803Smckusick 
28922803Smckusick   return (p);
29022803Smckusick }
29122803Smckusick 
29222803Smckusick 
29322803Smckusick 
mkdlval(name,subs,range)29422803Smckusick delt *mkdlval(name, subs, range)
29522803Smckusick vexpr *name;
29622803Smckusick vlist *subs;
29722803Smckusick rpair *range;
29822803Smckusick {
29922803Smckusick   register aelt *p;
30022803Smckusick 
30122803Smckusick   p = ALLOC(Aelt);
30222803Smckusick   p->tag = SIMPLE;
30322803Smckusick   p->var = mkname(name->dname.len, name->dname.repr);
30422803Smckusick   p->subs = subs;
30522803Smckusick   p->range = range;
30622803Smckusick 
30722803Smckusick   return ((delt *) p);
30822803Smckusick }
30922803Smckusick 
31022803Smckusick 
31122803Smckusick 
mkdatado(lvals,dovar,params)31222803Smckusick delt *mkdatado(lvals, dovar, params)
31322803Smckusick elist *lvals;
31422803Smckusick vexpr *dovar;
31522803Smckusick vlist *params;
31622803Smckusick {
31722803Smckusick   static char *toofew = "missing loop parameters";
31822803Smckusick   static char *toomany = "too many loop parameters";
31922803Smckusick 
32022803Smckusick   register dolist *p;
32122803Smckusick   register vlist *vp;
32222803Smckusick   register int pcnt;
32322803Smckusick   register dvalue *one;
32422803Smckusick 
32522803Smckusick   p = ALLOC(DoList);
32622803Smckusick   p->tag = NESTED;
32722803Smckusick   p->elts = revelist(lvals);
32822803Smckusick   p->dovar = dovar;
32922803Smckusick 
33022803Smckusick   vp = params;
33122803Smckusick   pcnt = 0;
33222803Smckusick   while (vp)
33322803Smckusick     {
33422803Smckusick       pcnt++;
33522803Smckusick       vp = vp->next;
33622803Smckusick     }
33722803Smckusick 
33822803Smckusick   if (pcnt != 2 && pcnt != 3)
33922803Smckusick     {
34022803Smckusick       if (pcnt < 2)
34122803Smckusick 	err(toofew);
34222803Smckusick       else
34322803Smckusick 	err(toomany);
34422803Smckusick 
34522803Smckusick       p->init = (vexpr *) ALLOC(Derror);
34622803Smckusick       p->init->tag = DERROR;
34722803Smckusick 
34822803Smckusick       p->limit = (vexpr *) ALLOC(Derror);
34922803Smckusick       p->limit->tag = DERROR;
35022803Smckusick 
35122803Smckusick       p->step = (vexpr *) ALLOC(Derror);
35222803Smckusick       p->step->tag = DERROR;
35322803Smckusick     }
35422803Smckusick   else
35522803Smckusick     {
35622803Smckusick       vp = params;
35722803Smckusick 
35822803Smckusick       if (pcnt == 2)
35922803Smckusick 	{
36022803Smckusick 	  one = ALLOC(Dvalue);
36122803Smckusick 	  one->tag = DVALUE;
36222803Smckusick 	  one->status = NORMAL;
36322803Smckusick 	  one->value = 1;
36422803Smckusick 	  p->step = (vexpr *) one;
36522803Smckusick 	}
36622803Smckusick       else
36722803Smckusick 	{
36822803Smckusick 	  p->step = vp->val;
36922803Smckusick 	  vp->val = NULL;
37022803Smckusick 	  vp = vp->next;
37122803Smckusick 	}
37222803Smckusick 
37322803Smckusick       p->limit = vp->val;
37422803Smckusick       vp->val = NULL;
37522803Smckusick       vp = vp->next;
37622803Smckusick 
37722803Smckusick       p->init = vp->val;
37822803Smckusick       vp->val = NULL;
37922803Smckusick     }
38022803Smckusick 
38122803Smckusick   frvlist(params);
38222803Smckusick   return ((delt *) p);
38322803Smckusick }
38422803Smckusick 
38522803Smckusick 
38622803Smckusick 
mkdrange(lb,ub)38722803Smckusick rpair *mkdrange(lb, ub)
38822803Smckusick vexpr *lb, *ub;
38922803Smckusick {
39022803Smckusick   register rpair *p;
39122803Smckusick 
39222803Smckusick   p = ALLOC(Rpair);
39322803Smckusick   p->low = lb;
39422803Smckusick   p->high = ub;
39522803Smckusick 
39622803Smckusick   return (p);
39722803Smckusick }
39822803Smckusick 
39922803Smckusick 
40022803Smckusick 
mkdrval(repl,val)40122803Smckusick vallist *mkdrval(repl, val)
40222803Smckusick vexpr *repl;
40322803Smckusick expptr val;
40422803Smckusick {
40522803Smckusick   static char *badtag = "bad tag in mkdrval";
40622803Smckusick   static char *negrepl = "negative replicator";
40722803Smckusick   static char *zerorepl = "zero replicator";
40822803Smckusick   static char *toobig = "replicator too large";
40922803Smckusick   static char *nonconst = "%s is not a constant";
41022803Smckusick 
41122803Smckusick   register vexpr *vp;
41222803Smckusick   register vallist *p;
41322803Smckusick   register int status;
41422803Smckusick   register ftnint value;
41522803Smckusick   register int copied;
41622803Smckusick 
41722803Smckusick   copied = 0;
41822803Smckusick 
41922803Smckusick   if (repl->tag == DNAME)
42022803Smckusick     {
42122803Smckusick       vp = evaldname(repl);
42222803Smckusick       copied = 1;
42322803Smckusick     }
42422803Smckusick   else
42522803Smckusick     vp = repl;
42622803Smckusick 
42722803Smckusick   p = ALLOC(ValList);
42822803Smckusick   p->next = NULL;
42922803Smckusick   p->value = (Constp) val;
43022803Smckusick 
43122803Smckusick   if (vp->tag == DVALUE)
43222803Smckusick     {
43322803Smckusick       status = vp->dvalue.status;
43422803Smckusick       value = vp->dvalue.value;
43522803Smckusick 
43622803Smckusick       if ((status == NORMAL && value < 0) || status == MINLESS1)
43722803Smckusick 	{
43822803Smckusick 	  err(negrepl);
43922803Smckusick 	  p->status = ERRVAL;
44022803Smckusick 	}
44122803Smckusick       else if (status == NORMAL)
44222803Smckusick 	{
44322803Smckusick 	  if (value == 0)
44422803Smckusick 	    warn(zerorepl);
44522803Smckusick 	  p->status = NORMAL;
44622803Smckusick 	  p->repl = value;
44722803Smckusick 	}
44822803Smckusick       else if (status == MAXPLUS1)
44922803Smckusick 	{
45022803Smckusick 	  err(toobig);
45122803Smckusick 	  p->status = ERRVAL;
45222803Smckusick 	}
45322803Smckusick       else
45422803Smckusick 	p->status = ERRVAL;
45522803Smckusick     }
45622803Smckusick   else if (vp->tag == DNAME)
45722803Smckusick     {
45822803Smckusick       errnm(nonconst, vp->dname.len, vp->dname.repr);
45922803Smckusick       p->status = ERRVAL;
46022803Smckusick     }
46122803Smckusick   else if (vp->tag == DERROR)
46222803Smckusick     p->status = ERRVAL;
46322803Smckusick   else
46422803Smckusick     fatal(badtag);
46522803Smckusick 
46622803Smckusick   if (copied) frvexpr(vp);
46722803Smckusick   return (p);
46822803Smckusick }
46922803Smckusick 
47022803Smckusick 
47122803Smckusick 
47222803Smckusick /*  Evicon returns the value of the integer constant  */
47322803Smckusick /*  pointed to by token.                              */
47422803Smckusick 
evicon(len,token)47522803Smckusick vexpr *evicon(len, token)
47622803Smckusick register int len;
47722803Smckusick register char *token;
47822803Smckusick {
47922803Smckusick   static char *badconst = "bad integer constant";
48022803Smckusick   static char *overflow = "integer constant too large";
48122803Smckusick 
48222803Smckusick   register int i;
48322803Smckusick   register ftnint val;
48422803Smckusick   register int digit;
48522803Smckusick   register dvalue *p;
48622803Smckusick 
48722803Smckusick   if (len <= 0)
48822803Smckusick     fatal(badconst);
48922803Smckusick 
49022803Smckusick   p = ALLOC(Dvalue);
49122803Smckusick   p->tag = DVALUE;
49222803Smckusick 
49322803Smckusick   i = 0;
49422803Smckusick   val = 0;
49522803Smckusick   while (i < len)
49622803Smckusick     {
49722803Smckusick       if (val > MAXINT/10)
49822803Smckusick 	{
49922803Smckusick 	  err(overflow);
50022803Smckusick 	  p->status = ERRVAL;
50122803Smckusick 	  goto ret;
50222803Smckusick 	}
50322803Smckusick       val = 10*val;
50422803Smckusick       digit = token[i++];
50522803Smckusick       if (!isdigit(digit))
50622803Smckusick 	fatal(badconst);
50722803Smckusick       digit = digit - '0';
50822803Smckusick       if (MAXINT - val >= digit)
50922803Smckusick 	val = val + digit;
51022803Smckusick       else
51122803Smckusick 	if (i == len && MAXINT - val + 1 == digit)
51222803Smckusick 	  {
51322803Smckusick 	    p->status = MAXPLUS1;
51422803Smckusick 	    goto ret;
51522803Smckusick 	  }
51622803Smckusick 	else
51722803Smckusick 	  {
51822803Smckusick 	    err(overflow);
51922803Smckusick 	    p->status = ERRVAL;
52022803Smckusick 	    goto ret;
52122803Smckusick 	  }
52222803Smckusick     }
52322803Smckusick 
52422803Smckusick   p->status = NORMAL;
52522803Smckusick   p->value = val;
52622803Smckusick 
52722803Smckusick ret:
52822803Smckusick   return ((vexpr *) p);
52922803Smckusick }
53022803Smckusick 
53122803Smckusick 
53222803Smckusick 
53322803Smckusick /*  Ivaltoicon converts a dvalue into a constant block.  */
53422803Smckusick 
ivaltoicon(vp)53522803Smckusick expptr ivaltoicon(vp)
53622803Smckusick register vexpr *vp;
53722803Smckusick {
53822803Smckusick   static char *badtag = "bad tag in ivaltoicon";
53922803Smckusick   static char *overflow = "integer constant too large";
54022803Smckusick 
54122803Smckusick   register int vs;
54222803Smckusick   register expptr p;
54322803Smckusick 
54422803Smckusick   if (vp->tag == DERROR)
54522803Smckusick     return(errnode());
54622803Smckusick   else if (vp->tag != DVALUE)
54722803Smckusick     fatal(badtag);
54822803Smckusick 
54922803Smckusick   vs = vp->dvalue.status;
55022803Smckusick   if (vs == NORMAL)
55122803Smckusick     p = mkintcon(vp->dvalue.value);
55222803Smckusick   else if ((MAXINT + MININT == -1) && vs == MINLESS1)
55322803Smckusick     p = mkintcon(MININT);
55422803Smckusick   else if (vs == MAXPLUS1 || vs == MINLESS1)
55522803Smckusick     {
55622803Smckusick       err(overflow);
55722803Smckusick       p = errnode();
55822803Smckusick     }
55922803Smckusick   else
56022803Smckusick     p = errnode();
56122803Smckusick 
56222803Smckusick   return (p);
56322803Smckusick }
56422803Smckusick 
56522803Smckusick 
56622803Smckusick 
56722803Smckusick /*  Mkdname stores an identifier as a dname  */
56822803Smckusick 
mkdname(len,str)56922803Smckusick vexpr *mkdname(len, str)
57022803Smckusick int len;
57122803Smckusick register char *str;
57222803Smckusick {
57322803Smckusick   register dname *p;
57422803Smckusick   register int i;
57522803Smckusick   register char *s;
57622803Smckusick 
57722803Smckusick   s = (char *) ckalloc(len + 1);
57822803Smckusick   i = len;
57922803Smckusick   s[i] = '\0';
58022803Smckusick 
58122803Smckusick   while (--i >= 0)
58222803Smckusick     s[i] = str[i];
58322803Smckusick 
58422803Smckusick   p = ALLOC(Dname);
58522803Smckusick   p->tag = DNAME;
58622803Smckusick   p->len = len;
58722803Smckusick   p->repr = s;
58822803Smckusick 
58922803Smckusick   return ((vexpr *) p);
59022803Smckusick }
59122803Smckusick 
59222803Smckusick 
59322803Smckusick 
59422803Smckusick /*  Getname gets the symbol table information associated with  */
59522803Smckusick /*  a name.  Getname differs from mkname in that it will not   */
59622803Smckusick /*  add the name to the symbol table if it is not already      */
59722803Smckusick /*  present.                                                   */
59822803Smckusick 
getname(l,s)59922803Smckusick Namep getname(l, s)
60022803Smckusick int l;
60122803Smckusick register char *s;
60222803Smckusick {
60322803Smckusick   struct Hashentry *hp;
60422803Smckusick   int hash;
60522803Smckusick   register Namep q;
60622803Smckusick   register int i;
60722803Smckusick   char n[VL];
60822803Smckusick 
60922803Smckusick   hash = 0;
61022803Smckusick   for (i = 0; i < l && *s != '\0'; ++i)
61122803Smckusick     {
61222803Smckusick       hash += *s;
61322803Smckusick       n[i] = *s++;
61422803Smckusick     }
61522803Smckusick 
61622803Smckusick   while (i < VL)
61722803Smckusick     n[i++] = ' ';
61822803Smckusick 
61922803Smckusick   hash %= maxhash;
62022803Smckusick   hp = hashtab + hash;
62122803Smckusick 
62222803Smckusick   while (q = hp->varp)
62322803Smckusick     if (hash == hp->hashval
62422803Smckusick 	&& eqn(VL, n, q->varname))
62522803Smckusick       goto ret;
62622803Smckusick     else if (++hp >= lasthash)
62722803Smckusick       hp = hashtab;
62822803Smckusick 
62922803Smckusick ret:
63022803Smckusick   return (q);
63122803Smckusick }
63222803Smckusick 
63322803Smckusick 
63422803Smckusick 
63522803Smckusick /*  Evparam returns the value of the constant named by name.  */
63622803Smckusick 
evparam(np)63722803Smckusick expptr evparam(np)
63822803Smckusick register vexpr *np;
63922803Smckusick {
64022803Smckusick   static char *badtag = "bad tag in evparam";
64122803Smckusick   static char *undefined = "%s is undefined";
64222803Smckusick   static char *nonconst = "%s is not constant";
64322803Smckusick 
64422803Smckusick   register struct Paramblock *tp;
64522803Smckusick   register expptr p;
64622803Smckusick   register int len;
64722803Smckusick   register char *repr;
64822803Smckusick 
64922803Smckusick   if (np->tag != DNAME)
65022803Smckusick     fatal(badtag);
65122803Smckusick 
65222803Smckusick   len = np->dname.len;
65322803Smckusick   repr = np->dname.repr;
65422803Smckusick 
65522803Smckusick   tp = (struct Paramblock *) getname(len, repr);
65622803Smckusick 
65722803Smckusick   if (tp == NULL)
65822803Smckusick     {
65922803Smckusick       errnm(undefined, len, repr);
66022803Smckusick       p = errnode();
66122803Smckusick     }
66222803Smckusick   else if (tp->vclass != CLPARAM || !ISCONST(tp->paramval))
66322803Smckusick     {
66422803Smckusick       if (tp->paramval->tag != TERROR)
66522803Smckusick         errnm(nonconst, len, repr);
66622803Smckusick       p = errnode();
66722803Smckusick     }
66822803Smckusick   else
66922803Smckusick     p = (expptr) cpexpr(tp->paramval);
67022803Smckusick 
67122803Smckusick   return (p);
67222803Smckusick }
67322803Smckusick 
67422803Smckusick 
67522803Smckusick 
evaldname(dp)67622803Smckusick vexpr *evaldname(dp)
67722803Smckusick vexpr *dp;
67822803Smckusick {
67922803Smckusick   static char *undefined = "%s is undefined";
68022803Smckusick   static char *nonconst = "%s is not a constant";
68122803Smckusick   static char *nonint = "%s is not an integer";
68222803Smckusick 
68322803Smckusick   register dvalue *p;
68422803Smckusick   register struct Paramblock *tp;
68522803Smckusick   register int len;
68622803Smckusick   register char *repr;
68722803Smckusick 
68822803Smckusick   p = ALLOC(Dvalue);
68922803Smckusick   p->tag = DVALUE;
69022803Smckusick 
69122803Smckusick   len = dp->dname.len;
69222803Smckusick   repr = dp->dname.repr;
69322803Smckusick 
69422803Smckusick   tp = (struct Paramblock *) getname(len, repr);
69522803Smckusick 
69622803Smckusick   if (tp == NULL)
69722803Smckusick     {
69822803Smckusick       errnm(undefined, len, repr);
69922803Smckusick       p->status = ERRVAL;
70022803Smckusick     }
70122803Smckusick   else if (tp->vclass != CLPARAM || !ISCONST(tp->paramval))
70222803Smckusick     {
70322803Smckusick       if (tp->paramval->tag != TERROR)
70422803Smckusick         errnm(nonconst, len, repr);
70522803Smckusick       p->status = ERRVAL;
70622803Smckusick     }
70722803Smckusick   else if (!ISINT(tp->paramval->constblock.vtype))
70822803Smckusick     {
70922803Smckusick       errnm(nonint, len, repr);
71022803Smckusick       p->status = ERRVAL;
71122803Smckusick     }
71222803Smckusick   else
71322803Smckusick     {
71422803Smckusick       if ((MAXINT + MININT == -1)
71533256Sbostic 	  && tp->paramval->constblock.constant.ci == MININT)
71622803Smckusick 	p->status = MINLESS1;
71722803Smckusick       else
71822803Smckusick 	{
71922803Smckusick 	  p->status = NORMAL;
72033256Sbostic           p->value = tp->paramval->constblock.constant.ci;
72122803Smckusick 	}
72222803Smckusick     }
72322803Smckusick 
72422803Smckusick   return ((vexpr *) p);
72522803Smckusick }
72622803Smckusick 
72722803Smckusick 
72822803Smckusick 
mkdexpr(op,l,r)72922803Smckusick vexpr *mkdexpr(op, l, r)
73022803Smckusick register int op;
73122803Smckusick register vexpr *l;
73222803Smckusick register vexpr *r;
73322803Smckusick {
73422803Smckusick   static char *badop = "bad operator in mkdexpr";
73522803Smckusick 
73622803Smckusick   register vexpr *p;
73722803Smckusick 
73822803Smckusick   switch (op)
73922803Smckusick     {
74022803Smckusick     default:
74122803Smckusick       fatal(badop);
74222803Smckusick 
74322803Smckusick     case OPNEG:
74422803Smckusick     case OPPLUS:
74522803Smckusick     case OPMINUS:
74622803Smckusick     case OPSTAR:
74722803Smckusick     case OPSLASH:
74822803Smckusick     case OPPOWER:
74922803Smckusick       break;
75022803Smckusick     }
75122803Smckusick 
75222803Smckusick   if ((l != NULL && l->tag == DERROR) || r->tag == DERROR)
75322803Smckusick     {
75422803Smckusick       frvexpr(l);
75522803Smckusick       frvexpr(r);
75622803Smckusick       p = (vexpr *) ALLOC(Derror);
75722803Smckusick       p->tag = DERROR;
75822803Smckusick     }
75922803Smckusick   else if (op == OPNEG && r->tag == DVALUE)
76022803Smckusick     {
76122803Smckusick       p = negival(r);
76222803Smckusick       frvexpr(r);
76322803Smckusick     }
76422803Smckusick   else if (op != OPNEG && l->tag == DVALUE && r->tag == DVALUE)
76522803Smckusick     {
76622803Smckusick       switch (op)
76722803Smckusick 	{
76822803Smckusick 	case OPPLUS:
76922803Smckusick 	  p = addivals(l, r);
77022803Smckusick 	  break;
77122803Smckusick 
77222803Smckusick 	case OPMINUS:
77322803Smckusick 	  p = subivals(l, r);
77422803Smckusick 	  break;
77522803Smckusick 
77622803Smckusick 	case OPSTAR:
77722803Smckusick 	  p = mulivals(l, r);
77822803Smckusick 	  break;
77922803Smckusick 
78022803Smckusick 	case OPSLASH:
78122803Smckusick 	  p = divivals(l, r);
78222803Smckusick 	  break;
78322803Smckusick 
78422803Smckusick 	case OPPOWER:
78522803Smckusick 	  p = powivals(l, r);
78622803Smckusick 	  break;
78722803Smckusick 	}
78822803Smckusick 
78922803Smckusick       frvexpr(l);
79022803Smckusick       frvexpr(r);
79122803Smckusick     }
79222803Smckusick   else
79322803Smckusick     {
79422803Smckusick       p = (vexpr *) ALLOC(Dexpr);
79522803Smckusick       p->tag = DEXPR;
79622803Smckusick       p->dexpr.opcode = op;
79722803Smckusick       p->dexpr.left = l;
79822803Smckusick       p->dexpr.right = r;
79922803Smckusick     }
80022803Smckusick 
80122803Smckusick   return (p);
80222803Smckusick }
80322803Smckusick 
80422803Smckusick 
80522803Smckusick 
addivals(l,r)80622803Smckusick vexpr *addivals(l, r)
80722803Smckusick vexpr *l;
80822803Smckusick vexpr *r;
80922803Smckusick {
81022803Smckusick   static char *badtag = "bad tag in addivals";
81122803Smckusick   static char *overflow = "integer value too large";
81222803Smckusick 
81322803Smckusick   register int ls, rs;
81422803Smckusick   register ftnint lv, rv;
81522803Smckusick   register dvalue *p;
81622803Smckusick   register ftnint k;
81722803Smckusick 
81822803Smckusick   if (l->tag != DVALUE || r->tag != DVALUE)
81922803Smckusick     fatal(badtag);
82022803Smckusick 
82122803Smckusick   ls = l->dvalue.status;
82222803Smckusick   lv = l->dvalue.value;
82322803Smckusick   rs = r->dvalue.status;
82422803Smckusick   rv = r->dvalue.value;
82522803Smckusick 
82622803Smckusick   p = ALLOC(Dvalue);
82722803Smckusick   p->tag = DVALUE;
82822803Smckusick 
82922803Smckusick   if (ls == ERRVAL || rs == ERRVAL)
83022803Smckusick     p->status = ERRVAL;
83122803Smckusick 
83222803Smckusick   else if (ls == NORMAL && rs == NORMAL)
83322803Smckusick     {
83422803Smckusick       addints(lv, rv);
83522803Smckusick       if (rstatus == ERRVAL)
83622803Smckusick 	err(overflow);
83722803Smckusick       p->status = rstatus;
83822803Smckusick       p->value = rvalue;
83922803Smckusick     }
84022803Smckusick 
84122803Smckusick   else
84222803Smckusick     {
84322803Smckusick       if (rs == MAXPLUS1 || rs == MINLESS1)
84422803Smckusick 	{
84522803Smckusick 	  rs = ls;
84622803Smckusick 	  rv = lv;
84722803Smckusick 	  ls = r->dvalue.status;
84822803Smckusick 	}
84922803Smckusick 
85022803Smckusick       if (rs == NORMAL && rv == 0)
85122803Smckusick 	p->status = ls;
85222803Smckusick       else if (ls == MAXPLUS1)
85322803Smckusick 	{
85422803Smckusick 	  if (rs == NORMAL && rv < 0)
85522803Smckusick 	    {
85622803Smckusick 	      p->status = NORMAL;
85722803Smckusick 	      k = MAXINT + rv;
85822803Smckusick 	      p->value = k + 1;
85922803Smckusick 	    }
86022803Smckusick 	  else if (rs == MINLESS1)
86122803Smckusick 	    {
86222803Smckusick 	      p->status = NORMAL;
86322803Smckusick 	      p->value = 0;
86422803Smckusick 	    }
86522803Smckusick 	  else
86622803Smckusick 	    {
86722803Smckusick 	      err(overflow);
86822803Smckusick 	      p->status = ERRVAL;
86922803Smckusick 	    }
87022803Smckusick 	}
87122803Smckusick       else
87222803Smckusick 	{
87322803Smckusick 	  if (rs == NORMAL && rv > 0)
87422803Smckusick 	    {
87522803Smckusick 	      p->status = NORMAL;
87622803Smckusick 	      k = ( -MAXINT ) + rv;
87722803Smckusick 	      p->value = k - 1;
87822803Smckusick 	    }
87922803Smckusick 	  else if (rs == MAXPLUS1)
88022803Smckusick 	    {
88122803Smckusick 	      p->status = NORMAL;
88222803Smckusick 	      p->value = 0;
88322803Smckusick 	    }
88422803Smckusick 	  else
88522803Smckusick 	    {
88622803Smckusick 	      err(overflow);
88722803Smckusick 	      p->status = ERRVAL;
88822803Smckusick 	    }
88922803Smckusick 	}
89022803Smckusick     }
89122803Smckusick 
89222803Smckusick   return ((vexpr *) p);
89322803Smckusick }
89422803Smckusick 
89522803Smckusick 
89622803Smckusick 
negival(vp)89722803Smckusick vexpr *negival(vp)
89822803Smckusick vexpr *vp;
89922803Smckusick {
90022803Smckusick   static char *badtag = "bad tag in negival";
90122803Smckusick 
90222803Smckusick   register int vs;
90322803Smckusick   register dvalue *p;
90422803Smckusick 
90522803Smckusick   if (vp->tag != DVALUE)
90622803Smckusick     fatal(badtag);
90722803Smckusick 
90822803Smckusick   vs = vp->dvalue.status;
90922803Smckusick 
91022803Smckusick   p = ALLOC(Dvalue);
91122803Smckusick   p->tag = DVALUE;
91222803Smckusick 
91322803Smckusick   if (vs == ERRVAL)
91422803Smckusick     p->status = ERRVAL;
91522803Smckusick   else if (vs == NORMAL)
91622803Smckusick     {
91722803Smckusick       p->status = NORMAL;
91822803Smckusick       p->value = -(vp->dvalue.value);
91922803Smckusick     }
92022803Smckusick   else if (vs == MAXPLUS1)
92122803Smckusick     p->status = MINLESS1;
92222803Smckusick   else
92322803Smckusick     p->status = MAXPLUS1;
92422803Smckusick 
92522803Smckusick   return ((vexpr *) p);
92622803Smckusick }
92722803Smckusick 
92822803Smckusick 
92922803Smckusick 
subivals(l,r)93022803Smckusick vexpr *subivals(l, r)
93122803Smckusick vexpr *l;
93222803Smckusick vexpr *r;
93322803Smckusick {
93422803Smckusick   static char *badtag = "bad tag in subivals";
93522803Smckusick 
93622803Smckusick   register vexpr *p;
93722803Smckusick   register vexpr *t;
93822803Smckusick 
93922803Smckusick   if (l->tag != DVALUE || r->tag != DVALUE)
94022803Smckusick     fatal(badtag);
94122803Smckusick 
94222803Smckusick   t = negival(r);
94322803Smckusick   p = addivals(l, t);
94422803Smckusick   frvexpr(t);
94522803Smckusick 
94622803Smckusick   return (p);
94722803Smckusick }
94822803Smckusick 
94922803Smckusick 
95022803Smckusick 
mulivals(l,r)95122803Smckusick vexpr *mulivals(l, r)
95222803Smckusick vexpr *l;
95322803Smckusick vexpr *r;
95422803Smckusick {
95522803Smckusick   static char *badtag = "bad tag in mulivals";
95622803Smckusick   static char *overflow = "integer value too large";
95722803Smckusick 
95822803Smckusick   register int ls, rs;
95922803Smckusick   register ftnint lv, rv;
96022803Smckusick   register dvalue *p;
96122803Smckusick 
96222803Smckusick   if (l->tag != DVALUE || r->tag != DVALUE)
96322803Smckusick     fatal(badtag);
96422803Smckusick 
96522803Smckusick   ls = l->dvalue.status;
96622803Smckusick   lv = l->dvalue.value;
96722803Smckusick   rs = r->dvalue.status;
96822803Smckusick   rv = r->dvalue.value;
96922803Smckusick 
97022803Smckusick   p = ALLOC(Dvalue);
97122803Smckusick   p->tag = DVALUE;
97222803Smckusick 
97322803Smckusick   if (ls == ERRVAL || rs == ERRVAL)
97422803Smckusick     p->status = ERRVAL;
97522803Smckusick 
97622803Smckusick   else if (ls == NORMAL && rs == NORMAL)
97722803Smckusick     {
97822803Smckusick       mulints(lv, rv);
97922803Smckusick       if (rstatus == ERRVAL)
98022803Smckusick 	err(overflow);
98122803Smckusick       p->status = rstatus;
98222803Smckusick       p->value = rvalue;
98322803Smckusick     }
98422803Smckusick   else
98522803Smckusick     {
98622803Smckusick       if (rs == MAXPLUS1 || rs == MINLESS1)
98722803Smckusick 	{
98822803Smckusick 	  rs = ls;
98922803Smckusick 	  rv = lv;
99022803Smckusick 	  ls = r->dvalue.status;
99122803Smckusick 	}
99222803Smckusick 
99322803Smckusick       if (rs == NORMAL && rv == 0)
99422803Smckusick 	{
99522803Smckusick 	  p->status = NORMAL;
99622803Smckusick 	  p->value = 0;
99722803Smckusick 	}
99822803Smckusick       else if (rs == NORMAL && rv == 1)
99922803Smckusick 	p->status = ls;
100022803Smckusick       else if (rs == NORMAL && rv == -1)
100122803Smckusick 	if (ls == MAXPLUS1)
100222803Smckusick 	  p->status = MINLESS1;
100322803Smckusick 	else
100422803Smckusick 	  p->status = MAXPLUS1;
100522803Smckusick       else
100622803Smckusick 	{
100722803Smckusick 	  err(overflow);
100822803Smckusick 	  p->status = ERRVAL;
100922803Smckusick 	}
101022803Smckusick     }
101122803Smckusick 
101222803Smckusick   return ((vexpr *) p);
101322803Smckusick }
101422803Smckusick 
101522803Smckusick 
101622803Smckusick 
divivals(l,r)101722803Smckusick vexpr *divivals(l, r)
101822803Smckusick vexpr *l;
101922803Smckusick vexpr *r;
102022803Smckusick {
102122803Smckusick   static char *badtag = "bad tag in divivals";
102222803Smckusick   static char *zerodivide = "division by zero";
102322803Smckusick 
102422803Smckusick   register int ls, rs;
102522803Smckusick   register ftnint lv, rv;
102622803Smckusick   register dvalue *p;
102722803Smckusick   register ftnint k;
102822803Smckusick   register int sign;
102922803Smckusick 
103022803Smckusick   if (l->tag != DVALUE && r->tag != DVALUE)
103122803Smckusick     fatal(badtag);
103222803Smckusick 
103322803Smckusick   ls = l->dvalue.status;
103422803Smckusick   lv = l->dvalue.value;
103522803Smckusick   rs = r->dvalue.status;
103622803Smckusick   rv = r->dvalue.value;
103722803Smckusick 
103822803Smckusick   p = ALLOC(Dvalue);
103922803Smckusick   p->tag = DVALUE;
104022803Smckusick 
104122803Smckusick   if (ls == ERRVAL || rs == ERRVAL)
104222803Smckusick     p->status = ERRVAL;
104322803Smckusick   else if (rs == NORMAL)
104422803Smckusick     {
104522803Smckusick       if (rv == 0)
104622803Smckusick 	{
104722803Smckusick 	  err(zerodivide);
104822803Smckusick 	  p->status = ERRVAL;
104922803Smckusick 	}
105022803Smckusick       else if (ls == NORMAL)
105122803Smckusick 	{
105222803Smckusick 	  p->status = NORMAL;
105322803Smckusick 	  p->value = lv / rv;
105422803Smckusick 	}
105522803Smckusick       else if (rv == 1)
105622803Smckusick 	p->status = ls;
105722803Smckusick       else if (rv == -1)
105822803Smckusick 	if (ls == MAXPLUS1)
105922803Smckusick 	  p->status = MINLESS1;
106022803Smckusick 	else
106122803Smckusick 	  p->status = MAXPLUS1;
106222803Smckusick       else
106322803Smckusick 	{
106422803Smckusick 	  p->status = NORMAL;
106522803Smckusick 
106622803Smckusick 	  if (ls == MAXPLUS1)
106722803Smckusick 	    sign = 1;
106822803Smckusick 	  else
106922803Smckusick 	    sign = -1;
107022803Smckusick 
107122803Smckusick 	  if (rv < 0)
107222803Smckusick 	    {
107322803Smckusick 	      rv = -rv;
107422803Smckusick 	      sign = -sign;
107522803Smckusick 	    }
107622803Smckusick 
107722803Smckusick 	  k = MAXINT - rv;
107822803Smckusick 	  p->value = sign * ((k + 1)/rv + 1);
107922803Smckusick 	}
108022803Smckusick     }
108122803Smckusick   else
108222803Smckusick     {
108322803Smckusick       p->status = NORMAL;
108422803Smckusick       if (ls == NORMAL)
108522803Smckusick 	p->value = 0;
108622803Smckusick       else if ((ls == MAXPLUS1 && rs == MAXPLUS1)
108722803Smckusick 		|| (ls == MINLESS1 && rs == MINLESS1))
108822803Smckusick 	p->value = 1;
108922803Smckusick       else
109022803Smckusick 	p->value = -1;
109122803Smckusick     }
109222803Smckusick 
109322803Smckusick   return ((vexpr *) p);
109422803Smckusick }
109522803Smckusick 
109622803Smckusick 
109722803Smckusick 
powivals(l,r)109822803Smckusick vexpr *powivals(l, r)
109922803Smckusick vexpr *l;
110022803Smckusick vexpr *r;
110122803Smckusick {
110222803Smckusick   static char *badtag = "bad tag in powivals";
110322803Smckusick   static char *zerozero = "zero raised to the zero-th power";
110422803Smckusick   static char *zeroneg = "zero raised to a negative power";
110522803Smckusick   static char *overflow = "integer value too large";
110622803Smckusick 
110722803Smckusick   register int ls, rs;
110822803Smckusick   register ftnint lv, rv;
110922803Smckusick   register dvalue *p;
111022803Smckusick 
111122803Smckusick   if (l->tag != DVALUE || r->tag != DVALUE)
111222803Smckusick     fatal(badtag);
111322803Smckusick 
111422803Smckusick   ls = l->dvalue.status;
111522803Smckusick   lv = l->dvalue.value;
111622803Smckusick   rs = r->dvalue.status;
111722803Smckusick   rv = r->dvalue.value;
111822803Smckusick 
111922803Smckusick   p = ALLOC(Dvalue);
112022803Smckusick   p->tag = DVALUE;
112122803Smckusick 
112222803Smckusick   if (ls == ERRVAL || rs == ERRVAL)
112322803Smckusick     p->status = ERRVAL;
112422803Smckusick 
112522803Smckusick   else if (ls == NORMAL)
112622803Smckusick     {
112722803Smckusick       if (lv == 1)
112822803Smckusick 	{
112922803Smckusick 	  p->status = NORMAL;
113022803Smckusick 	  p->value = 1;
113122803Smckusick 	}
113222803Smckusick       else if (lv == 0)
113322803Smckusick 	{
113422803Smckusick 	  if (rs == MAXPLUS1 || (rs == NORMAL && rv > 0))
113522803Smckusick 	    {
113622803Smckusick 	      p->status = NORMAL;
113722803Smckusick 	      p->value = 0;
113822803Smckusick 	    }
113922803Smckusick 	  else if (rs == NORMAL && rv == 0)
114022803Smckusick 	    {
114122803Smckusick 	      warn(zerozero);
114222803Smckusick 	      p->status = NORMAL;
114322803Smckusick 	      p->value = 1;
114422803Smckusick 	    }
114522803Smckusick 	  else
114622803Smckusick 	    {
114722803Smckusick 	      err(zeroneg);
114822803Smckusick 	      p->status = ERRVAL;
114922803Smckusick 	    }
115022803Smckusick 	}
115122803Smckusick       else if (lv == -1)
115222803Smckusick 	{
115322803Smckusick 	  p->status = NORMAL;
115422803Smckusick 	  if (rs == NORMAL)
115522803Smckusick 	    {
115622803Smckusick 	      if (rv < 0) rv = -rv;
115722803Smckusick 	      if (rv % 2 == 0)
115822803Smckusick 		p->value = 1;
115922803Smckusick 	      else
116022803Smckusick 		p->value = -1;
116122803Smckusick 	    }
116222803Smckusick 	  else
116322803Smckusick #	    if (MAXINT % 2 == 1)
116422803Smckusick 	      p->value = 1;
116522803Smckusick #	    else
116622803Smckusick 	      p->value = -1;
116722803Smckusick #	    endif
116822803Smckusick 	}
116922803Smckusick       else
117022803Smckusick 	{
117122803Smckusick 	  if (rs == NORMAL && rv > 0)
117222803Smckusick 	    {
117322803Smckusick 	      rstatus = NORMAL;
117422803Smckusick 	      rvalue = lv;
117522803Smckusick 	      while (--rv && rstatus == NORMAL)
117622803Smckusick 		mulints(rvalue, lv);
117722803Smckusick 	      if (rv == 0 && rstatus != ERRVAL)
117822803Smckusick 		{
117922803Smckusick 		  p->status = rstatus;
118022803Smckusick 		  p->value = rvalue;
118122803Smckusick 		}
118222803Smckusick 	      else
118322803Smckusick 		{
118422803Smckusick 		  err(overflow);
118522803Smckusick 		  p->status = ERRVAL;
118622803Smckusick 		}
118722803Smckusick 	    }
118822803Smckusick 	  else if (rs == MAXPLUS1)
118922803Smckusick 	    {
119022803Smckusick 	      err(overflow);
119122803Smckusick 	      p->status = ERRVAL;
119222803Smckusick 	    }
119322803Smckusick 	  else if (rs == NORMAL && rv == 0)
119422803Smckusick 	    {
119522803Smckusick 	      p->status = NORMAL;
119622803Smckusick 	      p->value = 1;
119722803Smckusick 	    }
119822803Smckusick 	  else
119922803Smckusick 	    {
120022803Smckusick 	      p->status = NORMAL;
120122803Smckusick 	      p->value = 0;
120222803Smckusick 	    }
120322803Smckusick 	}
120422803Smckusick     }
120522803Smckusick 
120622803Smckusick   else
120722803Smckusick     {
120822803Smckusick       if (rs == MAXPLUS1 || (rs == NORMAL && rv > 1))
120922803Smckusick 	{
121022803Smckusick 	  err(overflow);
121122803Smckusick 	  p->status = ERRVAL;
121222803Smckusick 	}
121322803Smckusick       else if (rs == NORMAL && rv == 1)
121422803Smckusick 	p->status = ls;
121522803Smckusick       else if (rs == NORMAL && rv == 0)
121622803Smckusick 	{
121722803Smckusick 	  p->status = NORMAL;
121822803Smckusick 	  p->value = 1;
121922803Smckusick 	}
122022803Smckusick       else
122122803Smckusick 	{
122222803Smckusick 	  p->status = NORMAL;
122322803Smckusick 	  p->value = 0;
122422803Smckusick 	}
122522803Smckusick     }
122622803Smckusick 
122722803Smckusick   return ((vexpr *) p);
122822803Smckusick }
122922803Smckusick 
123022803Smckusick 
123122803Smckusick 
123222803Smckusick /*  Addints adds two integer values.  */
123322803Smckusick 
addints(i,j)123422803Smckusick addints(i, j)
123522803Smckusick register ftnint i, j;
123622803Smckusick {
123722803Smckusick   register ftnint margin;
123822803Smckusick 
123922803Smckusick   if (i == 0)
124022803Smckusick     {
124122803Smckusick       rstatus = NORMAL;
124222803Smckusick       rvalue = j;
124322803Smckusick     }
124422803Smckusick   else if (i > 0)
124522803Smckusick     {
124622803Smckusick       margin = MAXINT - i;
124722803Smckusick       if (j <= margin)
124822803Smckusick 	{
124922803Smckusick 	  rstatus = NORMAL;
125022803Smckusick 	  rvalue = i + j;
125122803Smckusick 	}
125222803Smckusick       else if (j == margin + 1)
125322803Smckusick 	rstatus = MAXPLUS1;
125422803Smckusick       else
125522803Smckusick 	rstatus = ERRVAL;
125622803Smckusick     }
125722803Smckusick   else
125822803Smckusick     {
125922803Smckusick       margin = ( -MAXINT ) - i;
126022803Smckusick       if (j >= margin)
126122803Smckusick 	{
126222803Smckusick 	  rstatus = NORMAL;
126322803Smckusick 	  rvalue = i + j;
126422803Smckusick 	}
126522803Smckusick       else if (j == margin - 1)
126622803Smckusick 	rstatus = MINLESS1;
126722803Smckusick       else
126822803Smckusick 	rstatus = ERRVAL;
126922803Smckusick     }
127022803Smckusick 
127122803Smckusick    return;
127222803Smckusick }
127322803Smckusick 
127422803Smckusick 
127522803Smckusick 
127622803Smckusick /*  Mulints multiplies two integer values  */
127722803Smckusick 
mulints(i,j)127822803Smckusick mulints(i, j)
127922803Smckusick register ftnint i, j;
128022803Smckusick {
128122803Smckusick   register ftnint sign;
128222803Smckusick   register ftnint margin;
128322803Smckusick 
128422803Smckusick   if (i == 0 || j == 0)
128522803Smckusick     {
128622803Smckusick       rstatus = NORMAL;
128722803Smckusick       rvalue = 0;
128822803Smckusick     }
128922803Smckusick   else
129022803Smckusick     {
129122803Smckusick       if ((i > 0 && j > 0) || (i < 0 && j < 0))
129222803Smckusick 	sign = 1;
129322803Smckusick       else
129422803Smckusick 	sign = -1;
129522803Smckusick 
129622803Smckusick       if (i < 0) i = -i;
129722803Smckusick       if (j < 0) j = -j;
129822803Smckusick 
129922803Smckusick       margin = MAXINT - i;
130022803Smckusick       margin = (margin + 1) / i;
130122803Smckusick 
130222803Smckusick       if (j <= margin)
130322803Smckusick 	{
130422803Smckusick 	  rstatus = NORMAL;
130522803Smckusick 	  rvalue = i * j * sign;
130622803Smckusick 	}
130722803Smckusick       else if (j - 1 == margin)
130822803Smckusick 	{
130922803Smckusick 	  margin = i*margin - 1;
131022803Smckusick 	  if (margin == MAXINT - i)
131122803Smckusick 	    if (sign > 0)
131222803Smckusick 	      rstatus = MAXPLUS1;
131322803Smckusick 	    else
131422803Smckusick 	      rstatus = MINLESS1;
131522803Smckusick 	  else
131622803Smckusick 	    {
131722803Smckusick 	      rstatus = NORMAL;
131822803Smckusick 	      rvalue = i * j * sign;
131922803Smckusick 	    }
132022803Smckusick 	}
132122803Smckusick       else
132222803Smckusick 	rstatus = ERRVAL;
132322803Smckusick     }
132422803Smckusick 
132522803Smckusick   return;
132622803Smckusick }
132722803Smckusick 
132822803Smckusick 
132922803Smckusick 
133022803Smckusick vexpr *
evalvexpr(ep)133122803Smckusick evalvexpr(ep)
133222803Smckusick vexpr *ep;
133322803Smckusick {
133422803Smckusick   register vexpr *p;
133522803Smckusick   register vexpr *l, *r;
133622803Smckusick 
133722803Smckusick   switch (ep->tag)
133822803Smckusick     {
133922803Smckusick     case DVALUE:
134022803Smckusick       p = cpdvalue(ep);
134122803Smckusick       break;
134222803Smckusick 
134322803Smckusick     case DVAR:
134422803Smckusick       p = cpdvalue((vexpr *) ep->dvar.valp);
134522803Smckusick       break;
134622803Smckusick 
134722803Smckusick     case DNAME:
134822803Smckusick       p = evaldname(ep);
134922803Smckusick       break;
135022803Smckusick 
135122803Smckusick     case DEXPR:
135222803Smckusick       if (ep->dexpr.left == NULL)
135322803Smckusick 	l = NULL;
135422803Smckusick       else
135522803Smckusick 	l = evalvexpr(ep->dexpr.left);
135622803Smckusick 
135722803Smckusick       if (ep->dexpr.right == NULL)
135822803Smckusick 	r = NULL;
135922803Smckusick       else
136022803Smckusick 	r = evalvexpr(ep->dexpr.right);
136122803Smckusick 
136222803Smckusick       switch (ep->dexpr.opcode)
136322803Smckusick 	{
136422803Smckusick 	case OPNEG:
136522803Smckusick 	  p = negival(r);
136622803Smckusick 	  break;
136722803Smckusick 
136822803Smckusick 	case OPPLUS:
136922803Smckusick 	  p = addivals(l, r);
137022803Smckusick 	  break;
137122803Smckusick 
137222803Smckusick 	case OPMINUS:
137322803Smckusick 	  p = subivals(l, r);
137422803Smckusick 	  break;
137522803Smckusick 
137622803Smckusick 	case OPSTAR:
137722803Smckusick 	  p = mulivals(l, r);
137822803Smckusick 	  break;
137922803Smckusick 
138022803Smckusick 	case OPSLASH:
138122803Smckusick 	  p = divivals(l, r);
138222803Smckusick 	  break;
138322803Smckusick 
138422803Smckusick 	case OPPOWER:
138522803Smckusick 	  p = powivals(l, r);
138622803Smckusick 	  break;
138722803Smckusick 	}
138822803Smckusick 
138922803Smckusick       frvexpr(l);
139022803Smckusick       frvexpr(r);
139122803Smckusick       break;
139222803Smckusick 
139322803Smckusick     case DERROR:
139422803Smckusick       p = (vexpr *) ALLOC(Dvalue);
139522803Smckusick       p->tag = DVALUE;
139622803Smckusick       p->dvalue.status = ERRVAL;
139722803Smckusick       break;
139822803Smckusick     }
139922803Smckusick 
140022803Smckusick   return (p);
140122803Smckusick }
140222803Smckusick 
140322803Smckusick 
140422803Smckusick 
140522803Smckusick vexpr *
refrigdname(vp)140622803Smckusick refrigdname(vp)
140722803Smckusick vexpr *vp;
140822803Smckusick {
140922803Smckusick   register vexpr *p;
141022803Smckusick   register int len;
141122803Smckusick   register char *repr;
141222803Smckusick   register int found;
141322803Smckusick   register dovars *dvp;
141422803Smckusick 
141522803Smckusick   len = vp->dname.len;
141622803Smckusick   repr = vp->dname.repr;
141722803Smckusick 
141822803Smckusick   found = NO;
141922803Smckusick   dvp = dvlist;
142022803Smckusick   while (found == NO && dvp != NULL)
142122803Smckusick     {
142222803Smckusick       if (len == dvp->len && eqn(len, repr, dvp->repr))
142322803Smckusick 	found = YES;
142422803Smckusick       else
142522803Smckusick 	dvp = dvp->next;
142622803Smckusick     }
142722803Smckusick 
142822803Smckusick   if (found == YES)
142922803Smckusick     {
143022803Smckusick       p = (vexpr *) ALLOC(Dvar);
143122803Smckusick       p->tag = DVAR;
143222803Smckusick       p->dvar.valp = dvp->valp;
143322803Smckusick     }
143422803Smckusick   else
143522803Smckusick     {
143622803Smckusick       p = evaldname(vp);
143722803Smckusick       if (p->dvalue.status == ERRVAL)
143822803Smckusick 	dataerror = YES;
143922803Smckusick     }
144022803Smckusick 
144122803Smckusick   return (p);
144222803Smckusick }
144322803Smckusick 
144422803Smckusick 
144522803Smckusick 
refrigvexpr(vpp)144622803Smckusick refrigvexpr(vpp)
144722803Smckusick vexpr **vpp;
144822803Smckusick {
144922803Smckusick   register vexpr *vp;
145022803Smckusick 
145122803Smckusick   vp = *vpp;
145222803Smckusick 
145322803Smckusick   switch (vp->tag)
145422803Smckusick     {
145522803Smckusick     case DVALUE:
145622803Smckusick     case DVAR:
145722803Smckusick     case DERROR:
145822803Smckusick       break;
145922803Smckusick 
146022803Smckusick     case DEXPR:
146122803Smckusick       refrigvexpr( &(vp->dexpr.left) );
146222803Smckusick       refrigvexpr( &(vp->dexpr.right) );
146322803Smckusick       break;
146422803Smckusick 
146522803Smckusick     case DNAME:
146622803Smckusick       *(vpp) = refrigdname(vp);
146722803Smckusick       frvexpr(vp);
146822803Smckusick       break;
146922803Smckusick     }
147022803Smckusick 
147122803Smckusick   return;
147222803Smckusick }
147322803Smckusick 
147422803Smckusick 
147522803Smckusick 
147622803Smckusick int
chkvar(np,sname)147722803Smckusick chkvar(np, sname)
147822803Smckusick Namep np;
147922803Smckusick char *sname;
148022803Smckusick {
148122803Smckusick   static char *nonvar = "%s is not a variable";
148222803Smckusick   static char *arginit = "attempt to initialize a dummy argument: %s";
148322803Smckusick   static char *autoinit = "attempt to initialize an automatic variable: %s";
148422803Smckusick   static char *badclass = "bad class in chkvar";
148522803Smckusick 
148622803Smckusick   register int status;
148722803Smckusick   register struct Dimblock *dp;
148822803Smckusick   register int i;
148922803Smckusick 
149022803Smckusick   status = YES;
149122803Smckusick 
149222803Smckusick   if (np->vclass == CLUNKNOWN
149322803Smckusick       || (np->vclass == CLVAR && !np->vdcldone))
149422803Smckusick     vardcl(np);
149522803Smckusick 
149622803Smckusick   if (np->vstg == STGARG)
149722803Smckusick     {
149822803Smckusick       errstr(arginit, sname);
149922803Smckusick       dataerror = YES;
150022803Smckusick       status = NO;
150122803Smckusick     }
150222803Smckusick   else if (np->vclass != CLVAR)
150322803Smckusick     {
150422803Smckusick       errstr(nonvar, sname);
150522803Smckusick       dataerror = YES;
150622803Smckusick       status = NO;
150722803Smckusick     }
150822803Smckusick   else if (np->vstg == STGAUTO)
150922803Smckusick     {
151022803Smckusick       errstr(autoinit, sname);
151122803Smckusick       dataerror = YES;
151222803Smckusick       status = NO;
151322803Smckusick     }
151422803Smckusick   else if (np->vstg != STGBSS && np->vstg != STGINIT
151522803Smckusick 	    && np->vstg != STGCOMMON && np->vstg != STGEQUIV)
151622803Smckusick     {
151722803Smckusick       fatal(badclass);
151822803Smckusick     }
151922803Smckusick   else
152022803Smckusick     {
152122803Smckusick       switch (np->vtype)
152222803Smckusick 	{
152322803Smckusick 	case TYERROR:
152422803Smckusick 	  status = NO;
152522803Smckusick 	  dataerror = YES;
152622803Smckusick 	  break;
152722803Smckusick 
152822803Smckusick 	case TYSHORT:
152922803Smckusick 	case TYLONG:
153022803Smckusick 	case TYREAL:
153122803Smckusick 	case TYDREAL:
153222803Smckusick 	case TYCOMPLEX:
153322803Smckusick 	case TYDCOMPLEX:
153422803Smckusick 	case TYLOGICAL:
153522803Smckusick 	case TYCHAR:
153622803Smckusick 	  dp = np->vdim;
153722803Smckusick 	  if (dp != NULL)
153822803Smckusick 	    {
153922803Smckusick 	      if (dp->nelt == NULL || !ISICON(dp->nelt))
154022803Smckusick 	        {
154122803Smckusick 	          status = NO;
154222803Smckusick 	          dataerror = YES;
154322803Smckusick 	        }
154422803Smckusick 	    }
154522803Smckusick 	  break;
154622803Smckusick 
154722803Smckusick 	default:
154822803Smckusick 	  badtype("chkvar", np->vtype);
154922803Smckusick 	}
155022803Smckusick     }
155122803Smckusick 
155222803Smckusick   return (status);
155322803Smckusick }
155422803Smckusick 
155522803Smckusick 
155622803Smckusick 
refrigsubs(ap,sname)155722803Smckusick refrigsubs(ap, sname)
155822803Smckusick aelt *ap;
155922803Smckusick char *sname;
156022803Smckusick {
156122803Smckusick   static char *nonarray = "subscripts on a simple variable:  %s";
156222803Smckusick   static char *toofew = "not enough subscripts on %s";
156322803Smckusick   static char *toomany = "too many subscripts on %s";
156422803Smckusick 
156522803Smckusick   register vlist *subp;
156622803Smckusick   register int nsubs;
156722803Smckusick   register Namep np;
156822803Smckusick   register struct Dimblock *dp;
156922803Smckusick   register int i;
157022803Smckusick 
157122803Smckusick   np = ap->var;
157222803Smckusick   dp = np->vdim;
157322803Smckusick 
157422803Smckusick   if (ap->subs != NULL)
157522803Smckusick     {
157622803Smckusick       if (np->vdim == NULL)
157722803Smckusick 	{
157822803Smckusick 	  errstr(nonarray, sname);
157922803Smckusick 	  dataerror = YES;
158022803Smckusick 	}
158122803Smckusick       else
158222803Smckusick 	{
158322803Smckusick 	  nsubs = 0;
158422803Smckusick 	  subp = ap->subs;
158522803Smckusick 	  while (subp != NULL)
158622803Smckusick 	    {
158722803Smckusick 	      nsubs++;
158822803Smckusick 	      refrigvexpr( &(subp->val) );
158922803Smckusick 	      subp = subp->next;
159022803Smckusick 	    }
159122803Smckusick 
159222803Smckusick 	  if (dp->ndim != nsubs)
159322803Smckusick 	    {
159422803Smckusick 	      if (np->vdim->ndim > nsubs)
159522803Smckusick 		errstr(toofew, sname);
159622803Smckusick 	      else
159722803Smckusick 		errstr(toomany, sname);
159822803Smckusick 	      dataerror = YES;
159922803Smckusick 	    }
160022803Smckusick 	  else if (dp->baseoffset == NULL || !ISICON(dp->baseoffset))
160122803Smckusick 	    dataerror = YES;
160222803Smckusick 	  else
160322803Smckusick 	    {
160422803Smckusick 	      i = dp->ndim;
160522803Smckusick 	      while (i-- > 0)
160622803Smckusick 		{
160722803Smckusick 		  if (dp->dims[i].dimsize == NULL
160822803Smckusick 		      || !ISICON(dp->dims[i].dimsize))
160922803Smckusick 		    dataerror = YES;
161022803Smckusick 		}
161122803Smckusick 	    }
161222803Smckusick 	}
161322803Smckusick     }
161422803Smckusick 
161522803Smckusick   return;
161622803Smckusick }
161722803Smckusick 
161822803Smckusick 
161922803Smckusick 
refrigrange(ap,sname)162022803Smckusick refrigrange(ap, sname)
162122803Smckusick aelt *ap;
162222803Smckusick char *sname;
162322803Smckusick {
162422803Smckusick   static char *nonstr = "substring of a noncharacter variable:  %s";
162522803Smckusick   static char *array = "substring applied to an array:  %s";
162622803Smckusick 
162722803Smckusick   register Namep np;
162822803Smckusick   register dvalue *t;
162922803Smckusick   register rpair *rp;
163022803Smckusick 
163122803Smckusick   if (ap->range != NULL)
163222803Smckusick     {
163322803Smckusick       np = ap->var;
163422803Smckusick       if (np->vtype != TYCHAR)
163522803Smckusick 	{
163622803Smckusick 	  errstr(nonstr, sname);
163722803Smckusick 	  dataerror = YES;
163822803Smckusick 	}
163922803Smckusick       else if (ap->subs == NULL && np->vdim != NULL)
164022803Smckusick 	{
164122803Smckusick 	  errstr(array, sname);
164222803Smckusick 	  dataerror = YES;
164322803Smckusick 	}
164422803Smckusick       else
164522803Smckusick 	{
164622803Smckusick 	  rp = ap->range;
164722803Smckusick 
164822803Smckusick 	  if (rp->low != NULL)
164922803Smckusick 	    refrigvexpr( &(rp->low) );
165022803Smckusick 	  else
165122803Smckusick 	    {
165222803Smckusick 	      t = ALLOC(Dvalue);
165322803Smckusick 	      t->tag = DVALUE;
165422803Smckusick 	      t->status = NORMAL;
165522803Smckusick 	      t->value = 1;
165622803Smckusick 	      rp->low = (vexpr *) t;
165722803Smckusick 	    }
165822803Smckusick 
165922803Smckusick 	  if (rp->high != NULL)
166022803Smckusick 	    refrigvexpr( &(rp->high) );
166122803Smckusick 	  else
166222803Smckusick 	    {
166322803Smckusick 	      if (!ISICON(np->vleng))
166422803Smckusick 		{
166522803Smckusick 		  rp->high = (vexpr *) ALLOC(Derror);
166622803Smckusick 		  rp->high->tag = DERROR;
166722803Smckusick 		}
166822803Smckusick 	      else
166922803Smckusick 		{
167022803Smckusick 		  t = ALLOC(Dvalue);
167122803Smckusick 		  t->tag = DVALUE;
167222803Smckusick 		  t->status = NORMAL;
167333256Sbostic 		  t->value = np->vleng->constblock.constant.ci;
167422803Smckusick 		  rp->high = (vexpr *) t;
167522803Smckusick 		}
167622803Smckusick 	    }
167722803Smckusick 	}
167822803Smckusick     }
167922803Smckusick 
168022803Smckusick   return;
168122803Smckusick }
168222803Smckusick 
168322803Smckusick 
168422803Smckusick 
refrigaelt(ap)168522803Smckusick refrigaelt(ap)
168622803Smckusick aelt *ap;
168722803Smckusick {
168822803Smckusick   register Namep np;
168922803Smckusick   register char *bp, *sp;
169022803Smckusick   register int len;
169122803Smckusick   char buff[VL+1];
169222803Smckusick 
169322803Smckusick   np = ap->var;
169422803Smckusick 
169522803Smckusick   len = 0;
169622803Smckusick   bp = buff;
169722803Smckusick   sp = np->varname;
169822803Smckusick   while (len < VL && *sp != ' ' && *sp != '\0')
169922803Smckusick     {
170022803Smckusick       *bp++ = *sp++;
170122803Smckusick       len++;
170222803Smckusick     }
170322803Smckusick   *bp = '\0';
170422803Smckusick 
170522803Smckusick   if (chkvar(np, buff))
170622803Smckusick     {
170722803Smckusick       refrigsubs(ap, buff);
170822803Smckusick       refrigrange(ap, buff);
170922803Smckusick     }
171022803Smckusick 
171122803Smckusick   return;
171222803Smckusick }
171322803Smckusick 
171422803Smckusick 
171522803Smckusick 
refrigdo(dp)171622803Smckusick refrigdo(dp)
171722803Smckusick dolist *dp;
171822803Smckusick {
171922803Smckusick   static char *duplicates = "implied DO variable %s redefined";
172022803Smckusick   static char *nonvar = "%s is not a variable";
172122803Smckusick   static char *nonint = "%s is not integer";
172222803Smckusick 
172322803Smckusick   register int len;
172422803Smckusick   register char *repr;
172522803Smckusick   register int found;
172622803Smckusick   register dovars *dvp;
172722803Smckusick   register Namep np;
172822803Smckusick   register dovars *t;
172922803Smckusick 
173022803Smckusick   refrigvexpr( &(dp->init) );
173122803Smckusick   refrigvexpr( &(dp->limit) );
173222803Smckusick   refrigvexpr( &(dp->step) );
173322803Smckusick 
173422803Smckusick   len = dp->dovar->dname.len;
173522803Smckusick   repr = dp->dovar->dname.repr;
173622803Smckusick 
173722803Smckusick   found = NO;
173822803Smckusick   dvp = dvlist;
173922803Smckusick   while (found == NO && dvp != NULL)
174022803Smckusick     if (len == dvp->len && eqn(len, repr, dvp->repr))
174122803Smckusick       found = YES;
174222803Smckusick     else
174322803Smckusick       dvp = dvp->next;
174422803Smckusick 
174522803Smckusick   if (found == YES)
174622803Smckusick     {
174722803Smckusick       errnm(duplicates, len, repr);
174822803Smckusick       dataerror = YES;
174922803Smckusick     }
175022803Smckusick   else
175122803Smckusick     {
175222803Smckusick       np = getname(len, repr);
175322803Smckusick       if (np == NULL)
175422803Smckusick 	{
175522803Smckusick 	  if (!ISINT(impltype[letter(*repr)]))
175622803Smckusick 	    warnnm(nonint, len, repr);
175722803Smckusick 	}
175822803Smckusick       else
175922803Smckusick 	{
176022803Smckusick 	  if (np->vclass == CLUNKNOWN)
176122803Smckusick 	    vardcl(np);
176222803Smckusick 	  if (np->vclass != CLVAR)
176322803Smckusick 	    warnnm(nonvar, len, repr);
176422803Smckusick 	  else if (!ISINT(np->vtype))
176522803Smckusick 	    warnnm(nonint, len, repr);
176622803Smckusick 	}
176722803Smckusick     }
176822803Smckusick 
176922803Smckusick   t = ALLOC(DoVars);
177022803Smckusick   t->next = dvlist;
177122803Smckusick   t->len = len;
177222803Smckusick   t->repr = repr;
177322803Smckusick   t->valp = ALLOC(Dvalue);
177422803Smckusick   t->valp->tag = DVALUE;
177522803Smckusick   dp->dovar = (vexpr *) t->valp;
177622803Smckusick 
177722803Smckusick   dvlist = t;
177822803Smckusick 
177922803Smckusick   refriglvals(dp->elts);
178022803Smckusick 
178122803Smckusick   dvlist = t->next;
178222803Smckusick   free((char *) t);
178322803Smckusick 
178422803Smckusick   return;
178522803Smckusick }
178622803Smckusick 
178722803Smckusick 
178822803Smckusick 
refriglvals(lvals)178922803Smckusick refriglvals(lvals)
179022803Smckusick elist *lvals;
179122803Smckusick {
179222803Smckusick   register elist *top;
179322803Smckusick 
179422803Smckusick   top = lvals;
179522803Smckusick 
179622803Smckusick   while (top != NULL)
179722803Smckusick     {
179822803Smckusick       if (top->elt->tag == SIMPLE)
179922803Smckusick 	refrigaelt((aelt *) top->elt);
180022803Smckusick       else
180122803Smckusick 	refrigdo((dolist *) top->elt);
180222803Smckusick 
180322803Smckusick       top = top->next;
180422803Smckusick     }
180522803Smckusick 
180622803Smckusick   return;
180722803Smckusick }
180822803Smckusick 
180922803Smckusick 
181022803Smckusick 
181122803Smckusick /*  Refrig freezes name/value bindings in the DATA name list  */
181222803Smckusick 
181322803Smckusick 
refrig(lvals)181422803Smckusick refrig(lvals)
181522803Smckusick elist *lvals;
181622803Smckusick {
181722803Smckusick   dvlist = NULL;
181822803Smckusick   refriglvals(lvals);
181922803Smckusick   return;
182022803Smckusick }
182122803Smckusick 
182222803Smckusick 
182322803Smckusick 
182422803Smckusick ftnint
indexer(ap)182522803Smckusick indexer(ap)
182622803Smckusick aelt *ap;
182722803Smckusick {
182822803Smckusick   static char *badvar = "bad variable in indexer";
182922803Smckusick   static char *boundserror = "subscript out of bounds";
183022803Smckusick 
183122803Smckusick   register ftnint index;
183222803Smckusick   register vlist *sp;
183322803Smckusick   register Namep np;
183422803Smckusick   register struct Dimblock *dp;
183522803Smckusick   register int i;
183622803Smckusick   register dvalue *vp;
183722803Smckusick   register ftnint size;
183822803Smckusick   ftnint sub[MAXDIM];
183922803Smckusick 
184022803Smckusick   sp = ap->subs;
184122803Smckusick   if (sp == NULL) return (0);
184222803Smckusick 
184322803Smckusick   np = ap->var;
184422803Smckusick   dp = np->vdim;
184522803Smckusick 
184622803Smckusick   if (dp == NULL)
184722803Smckusick     fatal(badvar);
184822803Smckusick 
184922803Smckusick   i = 0;
185022803Smckusick   while (sp != NULL)
185122803Smckusick     {
185222803Smckusick       vp = (dvalue *) evalvexpr(sp->val);
185322803Smckusick 
185422803Smckusick       if (vp->status == NORMAL)
185522803Smckusick 	sub[i++] = vp->value;
185622803Smckusick       else if ((MININT + MAXINT == -1) && vp->status == MINLESS1)
185722803Smckusick 	sub[i++] = MININT;
185822803Smckusick       else
185922803Smckusick 	{
186022803Smckusick 	  frvexpr((vexpr *) vp);
186122803Smckusick 	  return (-1);
186222803Smckusick 	}
186322803Smckusick 
186422803Smckusick       frvexpr((vexpr *) vp);
186522803Smckusick       sp = sp->next;
186622803Smckusick     }
186722803Smckusick 
186822803Smckusick   index = sub[--i];
186922803Smckusick   while (i-- > 0)
187022803Smckusick     {
187133256Sbostic       size = dp->dims[i].dimsize->constblock.constant.ci;
187222803Smckusick       index = sub[i] + index * size;
187322803Smckusick     }
187422803Smckusick 
187533256Sbostic   index -= dp->baseoffset->constblock.constant.ci;
187622803Smckusick 
187733256Sbostic   if (index < 0 || index >= dp->nelt->constblock.constant.ci)
187822803Smckusick     {
187922803Smckusick       err(boundserror);
188022803Smckusick       return (-1);
188122803Smckusick     }
188222803Smckusick 
188322803Smckusick   return (index);
188422803Smckusick }
188522803Smckusick 
188622803Smckusick 
188722803Smckusick 
savedata(lvals,rvals)188822803Smckusick savedata(lvals, rvals)
188922803Smckusick elist *lvals;
189022803Smckusick vallist *rvals;
189122803Smckusick {
189222803Smckusick   static char *toomany = "more data values than data items";
189322803Smckusick 
189422803Smckusick   register elist *top;
189522803Smckusick 
189622803Smckusick   dataerror = NO;
189722803Smckusick   badvalue = NO;
189822803Smckusick 
189922803Smckusick   lvals = revelist(lvals);
190022803Smckusick   grvals = revrvals(rvals);
190122803Smckusick 
190222803Smckusick   refrig(lvals);
190322803Smckusick 
190422803Smckusick   if (!dataerror)
190522803Smckusick     outdata(lvals);
190622803Smckusick 
190722803Smckusick   frelist(lvals);
190822803Smckusick 
190922803Smckusick   while (grvals != NULL && dataerror == NO)
191022803Smckusick     {
191122803Smckusick       if (grvals->status != NORMAL)
191222803Smckusick 	dataerror = YES;
191322803Smckusick       else if (grvals->repl <= 0)
191422803Smckusick         grvals = grvals->next;
191522803Smckusick       else
191622803Smckusick 	{
191722803Smckusick 	  err(toomany);
191822803Smckusick 	  dataerror = YES;
191922803Smckusick 	}
192022803Smckusick     }
192122803Smckusick 
192222803Smckusick   frvallist(grvals);
192322803Smckusick 
192422803Smckusick   return;
192522803Smckusick }
192622803Smckusick 
192722803Smckusick 
192822803Smckusick 
setdfiles(np)192922803Smckusick setdfiles(np)
193022803Smckusick register Namep np;
193122803Smckusick {
193222803Smckusick   register struct Extsym *cp;
193322803Smckusick   register struct Equivblock *ep;
193422803Smckusick   register int stg;
193522803Smckusick   register int type;
193622803Smckusick   register ftnint typelen;
193722803Smckusick   register ftnint nelt;
193822803Smckusick   register ftnint varsize;
193922803Smckusick 
194022803Smckusick   stg = np->vstg;
194122803Smckusick 
194222803Smckusick   if (stg == STGBSS || stg == STGINIT)
194322803Smckusick     {
194422803Smckusick       datafile = vdatafile;
194522803Smckusick       chkfile = vchkfile;
194622803Smckusick       if (np->init == YES)
194722803Smckusick 	base = np->initoffset;
194822803Smckusick       else
194922803Smckusick 	{
195022803Smckusick 	  np->init = YES;
195122803Smckusick 	  np->initoffset = base = vdatahwm;
195222803Smckusick 	  if (np->vdim != NULL)
195333256Sbostic 	    nelt = np->vdim->nelt->constblock.constant.ci;
195422803Smckusick 	  else
195522803Smckusick 	    nelt = 1;
195622803Smckusick 	  type = np->vtype;
195722803Smckusick 	  if (type == TYCHAR)
195833256Sbostic 	    typelen = np->vleng->constblock.constant.ci;
195922803Smckusick 	  else if (type == TYLOGICAL)
196022803Smckusick 	    typelen = typesize[tylogical];
196122803Smckusick 	  else
196222803Smckusick 	    typelen = typesize[type];
196322803Smckusick 	  varsize = nelt * typelen;
196422803Smckusick 	  vdatahwm += varsize;
196522803Smckusick 	}
196622803Smckusick     }
196722803Smckusick   else if (stg == STGEQUIV)
196822803Smckusick     {
196922803Smckusick       datafile = vdatafile;
197022803Smckusick       chkfile = vchkfile;
197122803Smckusick       ep = &eqvclass[np->vardesc.varno];
197222803Smckusick       if (ep->init == YES)
197322803Smckusick 	base = ep->initoffset;
197422803Smckusick       else
197522803Smckusick 	{
197622803Smckusick 	  ep->init = YES;
197722803Smckusick 	  ep->initoffset = base = vdatahwm;
197822803Smckusick 	  vdatahwm += ep->eqvleng;
197922803Smckusick 	}
198022803Smckusick       base += np->voffset;
198122803Smckusick     }
198222803Smckusick   else if (stg == STGCOMMON)
198322803Smckusick     {
198422803Smckusick       datafile = cdatafile;
198522803Smckusick       chkfile = cchkfile;
198622803Smckusick       cp = &extsymtab[np->vardesc.varno];
198722803Smckusick       if (cp->init == YES)
198822803Smckusick 	base = cp->initoffset;
198922803Smckusick       else
199022803Smckusick 	{
199122803Smckusick 	  cp->init = YES;
199222803Smckusick 	  cp->initoffset = base = cdatahwm;
199322803Smckusick 	  cdatahwm += cp->maxleng;
199422803Smckusick 	}
199522803Smckusick       base += np->voffset;
199622803Smckusick     }
199722803Smckusick 
199822803Smckusick   return;
199922803Smckusick }
200022803Smckusick 
200122803Smckusick 
200222803Smckusick 
wrtdata(offset,repl,len,constant)200333256Sbostic wrtdata(offset, repl, len, constant)
200422803Smckusick long offset;
200522803Smckusick ftnint repl;
200622803Smckusick ftnint len;
200733256Sbostic char *constant;
200822803Smckusick {
200922803Smckusick   static char *badoffset = "bad offset in wrtdata";
201022803Smckusick   static char *toomuch = "too much data";
201122803Smckusick   static char *readerror = "read error on tmp file";
201222803Smckusick   static char *writeerror = "write error on tmp file";
201322803Smckusick   static char *seekerror = "seek error on tmp file";
201422803Smckusick 
201522803Smckusick   register ftnint k;
201622803Smckusick   long lastbyte;
201722803Smckusick   int bitpos;
201822803Smckusick   long chkoff;
201922803Smckusick   long lastoff;
202022803Smckusick   long chklen;
202122803Smckusick   long pos;
202222803Smckusick   int n;
202322803Smckusick   ftnint nbytes;
202422803Smckusick   int mask;
202522803Smckusick   register int i;
202622803Smckusick   char overlap;
202722803Smckusick   char allzero;
202822803Smckusick   char buff[BUFSIZ];
202922803Smckusick 
203022803Smckusick   if (offset < 0)
203122803Smckusick     fatal(badoffset);
203222803Smckusick 
203322803Smckusick   overlap = NO;
203422803Smckusick 
203522803Smckusick   k = repl * len;
203622803Smckusick   lastbyte = offset + k - 1;
203722803Smckusick   if (lastbyte < 0)
203822803Smckusick     {
203922803Smckusick       err(toomuch);
204022803Smckusick       dataerror = YES;
204122803Smckusick       return;
204222803Smckusick     }
204322803Smckusick 
204422803Smckusick   bitpos = offset % BYTESIZE;
204522803Smckusick   chkoff = offset/BYTESIZE;
204622803Smckusick   lastoff = lastbyte/BYTESIZE;
204722803Smckusick   chklen = lastoff - chkoff + 1;
204822803Smckusick 
204922803Smckusick   pos = lseek(chkfile, chkoff, 0);
205022803Smckusick   if (pos == -1)
205122803Smckusick     {
205222803Smckusick       err(seekerror);
205322803Smckusick       done(1);
205422803Smckusick     }
205522803Smckusick 
205622803Smckusick   while (k > 0)
205722803Smckusick     {
205822803Smckusick       if (chklen <= BUFSIZ)
205922803Smckusick 	n = chklen;
206022803Smckusick       else
206122803Smckusick 	{
206222803Smckusick 	  n = BUFSIZ;
206322803Smckusick 	  chklen -= BUFSIZ;
206422803Smckusick 	}
206522803Smckusick 
206622803Smckusick       nbytes = read(chkfile, buff, n);
206722803Smckusick       if (nbytes < 0)
206822803Smckusick 	{
206922803Smckusick 	  err(readerror);
207022803Smckusick 	  done(1);
207122803Smckusick 	}
207222803Smckusick 
207322803Smckusick       if (nbytes == 0)
207422803Smckusick 	buff[0] = '\0';
207522803Smckusick 
207622803Smckusick       if (nbytes < n)
207722803Smckusick 	buff[ n-1 ] = '\0';
207822803Smckusick 
207922803Smckusick       i = 0;
208022803Smckusick 
208122803Smckusick       if (bitpos > 0)
208222803Smckusick 	{
208322803Smckusick 	  while (k > 0 && bitpos < BYTESIZE)
208422803Smckusick 	    {
208522803Smckusick 	      mask = 1 << bitpos;
208622803Smckusick 
208722803Smckusick 	      if (mask & buff[0])
208822803Smckusick 		overlap = YES;
208922803Smckusick 	      else
209022803Smckusick 		buff[0] |= mask;
209122803Smckusick 
209222803Smckusick 	      k--;
209322803Smckusick 	      bitpos++;
209422803Smckusick 	    }
209522803Smckusick 
209622803Smckusick 	  if (bitpos == BYTESIZE)
209722803Smckusick 	    {
209822803Smckusick 	      bitpos = 0;
209922803Smckusick 	      i++;
210022803Smckusick 	    }
210122803Smckusick 	}
210222803Smckusick 
210322803Smckusick       while (i < nbytes && overlap == NO)
210422803Smckusick 	{
210522803Smckusick 	  if (buff[i] == 0 && k >= BYTESIZE)
210622803Smckusick 	    {
210722803Smckusick 	      buff[i++] = MAXBYTE;
210822803Smckusick 	      k -= BYTESIZE;
210922803Smckusick 	    }
211022803Smckusick 	  else if (k < BYTESIZE)
211122803Smckusick 	    {
211222803Smckusick 	      while (k-- > 0)
211322803Smckusick 		{
211422803Smckusick 		  mask = 1 << k;
211522803Smckusick 		  if (mask & buff[i])
211622803Smckusick 		    overlap = YES;
211722803Smckusick 		  else
211822803Smckusick 		    buff[i] |= mask;
211922803Smckusick 		}
212022803Smckusick 	      i++;
212122803Smckusick 	    }
212222803Smckusick 	  else
212322803Smckusick 	    {
212422803Smckusick 	      overlap = YES;
212522803Smckusick 	      buff[i++] = MAXBYTE;
212622803Smckusick 	      k -= BYTESIZE;
212722803Smckusick 	    }
212822803Smckusick 	}
212922803Smckusick 
213022803Smckusick       while (i < n)
213122803Smckusick 	{
213222803Smckusick 	  if (k >= BYTESIZE)
213322803Smckusick 	    {
213422803Smckusick 	      buff[i++] = MAXBYTE;
213522803Smckusick 	      k -= BYTESIZE;
213622803Smckusick 	    }
213722803Smckusick 	  else
213822803Smckusick 	    {
213922803Smckusick 	      while (k-- > 0)
214022803Smckusick 		{
214122803Smckusick 		  mask = 1 << k;
214222803Smckusick 		  buff[i] |= mask;
214322803Smckusick 		}
214422803Smckusick 	      i++;
214522803Smckusick 	    }
214622803Smckusick 	}
214722803Smckusick 
214822803Smckusick       pos = lseek(chkfile, -nbytes, 1);
214922803Smckusick       if (pos == -1)
215022803Smckusick 	{
215122803Smckusick 	  err(seekerror);
215222803Smckusick 	  done(1);
215322803Smckusick 	}
215422803Smckusick 
215522803Smckusick       nbytes = write(chkfile, buff, n);
215622803Smckusick       if (nbytes != n)
215722803Smckusick 	{
215822803Smckusick 	  err(writeerror);
215922803Smckusick 	  done(1);
216022803Smckusick 	}
216122803Smckusick     }
216222803Smckusick 
216322803Smckusick   if (overlap == NO)
216422803Smckusick     {
216522803Smckusick       allzero = YES;
216622803Smckusick       k = len;
216722803Smckusick 
216822803Smckusick       while (k > 0 && allzero != NO)
216933256Sbostic 	if (constant[--k] != 0) allzero = NO;
217022803Smckusick 
217122803Smckusick       if (allzero == YES)
217222803Smckusick 	return;
217322803Smckusick     }
217422803Smckusick 
217522803Smckusick   pos = lseek(datafile, offset, 0);
217622803Smckusick   if (pos == -1)
217722803Smckusick     {
217822803Smckusick       err(seekerror);
217922803Smckusick       done(1);
218022803Smckusick     }
218122803Smckusick 
218222803Smckusick   k = repl;
218322803Smckusick   while (k-- > 0)
218422803Smckusick     {
218533256Sbostic       nbytes = write(datafile, constant, len);
218622803Smckusick       if (nbytes != len)
218722803Smckusick 	{
218822803Smckusick 	  err(writeerror);
218922803Smckusick 	  done(1);
219022803Smckusick 	}
219122803Smckusick     }
219222803Smckusick 
219322803Smckusick   if (overlap) overlapflag = YES;
219422803Smckusick 
219522803Smckusick   return;
219622803Smckusick }
219722803Smckusick 
219822803Smckusick 
219922803Smckusick 
220022803Smckusick Constp
getdatum()220122803Smckusick getdatum()
220222803Smckusick {
220322803Smckusick   static char *toofew = "more data items than data values";
220422803Smckusick 
220522803Smckusick   register vallist *t;
220622803Smckusick 
220722803Smckusick   while (grvals != NULL)
220822803Smckusick     {
220922803Smckusick       if (grvals->status != NORMAL)
221022803Smckusick 	{
221122803Smckusick 	  dataerror = YES;
221222803Smckusick 	  return (NULL);
221322803Smckusick 	}
221422803Smckusick       else if (grvals->repl > 0)
221522803Smckusick 	{
221622803Smckusick 	  grvals->repl--;
221722803Smckusick 	  return (grvals->value);
221822803Smckusick 	}
221922803Smckusick       else
222022803Smckusick 	{
222122803Smckusick 	  badvalue = 0;
222222803Smckusick 	  frexpr ((tagptr) grvals->value);
222322803Smckusick 	  t = grvals;
222422803Smckusick 	  grvals = t->next;
222522803Smckusick 	  free((char *) t);
222622803Smckusick 	}
222722803Smckusick     }
222822803Smckusick 
222922803Smckusick   err(toofew);
223022803Smckusick   dataerror = YES;
223122803Smckusick   return (NULL);
223222803Smckusick }
223322803Smckusick 
223422803Smckusick 
223522803Smckusick 
outdata(lvals)223622803Smckusick outdata(lvals)
223722803Smckusick elist *lvals;
223822803Smckusick {
223922803Smckusick   register elist *top;
224022803Smckusick 
224122803Smckusick   top = lvals;
224222803Smckusick 
224322803Smckusick   while (top != NULL && dataerror == NO)
224422803Smckusick     {
224522803Smckusick       if (top->elt->tag == SIMPLE)
224622803Smckusick 	outaelt((aelt *) top->elt);
224722803Smckusick       else
224822803Smckusick 	outdolist((dolist *) top->elt);
224922803Smckusick 
225022803Smckusick       top = top->next;
225122803Smckusick     }
225222803Smckusick 
225322803Smckusick   return;
225422803Smckusick }
225522803Smckusick 
225622803Smckusick 
225722803Smckusick 
outaelt(ap)225822803Smckusick outaelt(ap)
225922803Smckusick aelt *ap;
226022803Smckusick {
226122803Smckusick   static char *toofew = "more data items than data values";
226222803Smckusick   static char *boundserror = "substring expression out of bounds";
226322803Smckusick   static char *order = "substring expressions out of order";
226422803Smckusick 
226522803Smckusick   register Namep np;
226622803Smckusick   register long soffset;
226722803Smckusick   register dvalue *lwb;
226822803Smckusick   register dvalue *upb;
226933256Sbostic   register Constp constant;
227022803Smckusick   register int k;
227122803Smckusick   register vallist *t;
227222803Smckusick   register int type;
227322803Smckusick   register ftnint typelen;
227422803Smckusick   register ftnint repl;
227522803Smckusick 
227622803Smckusick   extern char *packbytes();
227722803Smckusick 
227822803Smckusick   np = ap->var;
227922803Smckusick   setdfiles(np);
228022803Smckusick 
228122803Smckusick   type = np->vtype;
228222803Smckusick 
228322803Smckusick   if (type == TYCHAR)
228433256Sbostic     typelen = np->vleng->constblock.constant.ci;
228522803Smckusick   else if (type == TYLOGICAL)
228622803Smckusick     typelen = typesize[tylogical];
228722803Smckusick   else
228822803Smckusick     typelen = typesize[type];
228922803Smckusick 
229022803Smckusick   if (ap->subs != NULL || np->vdim == NULL)
229122803Smckusick     {
229222803Smckusick       soffset = indexer(ap);
229322803Smckusick       if (soffset == -1)
229422803Smckusick 	{
229522803Smckusick 	  dataerror = YES;
229622803Smckusick 	  return;
229722803Smckusick 	}
229822803Smckusick 
229922803Smckusick       soffset = soffset * typelen;
230022803Smckusick 
230122803Smckusick       if (ap->range != NULL)
230222803Smckusick 	{
230322803Smckusick 	  lwb = (dvalue *) evalvexpr(ap->range->low);
230422803Smckusick 	  upb = (dvalue *) evalvexpr(ap->range->high);
230522803Smckusick 	  if (lwb->status == ERRVAL || upb->status == ERRVAL)
230622803Smckusick 	    {
230722803Smckusick 	      frvexpr((vexpr *) lwb);
230822803Smckusick 	      frvexpr((vexpr *) upb);
230922803Smckusick 	      dataerror = YES;
231022803Smckusick 	      return;
231122803Smckusick 	    }
231222803Smckusick 
231322803Smckusick 	  if (lwb->status != NORMAL ||
231422803Smckusick 	      lwb->value < 1 ||
231522803Smckusick 	      lwb->value > typelen ||
231622803Smckusick 	      upb->status != NORMAL ||
231722803Smckusick 	      upb->value < 1 ||
231822803Smckusick 	      upb->value > typelen)
231922803Smckusick 	    {
232022803Smckusick 	      err(boundserror);
232122803Smckusick 	      frvexpr((vexpr *) lwb);
232222803Smckusick 	      frvexpr((vexpr *) upb);
232322803Smckusick 	      dataerror = YES;
232422803Smckusick 	      return;
232522803Smckusick 	    }
232622803Smckusick 
232722803Smckusick 	  if (lwb->value > upb->value)
232822803Smckusick 	    {
232922803Smckusick 	      err(order);
233022803Smckusick 	      frvexpr((vexpr *) lwb);
233122803Smckusick 	      frvexpr((vexpr *) upb);
233222803Smckusick 	      dataerror = YES;
233322803Smckusick 	      return;
233422803Smckusick 	    }
233522803Smckusick 
233622803Smckusick 	  soffset = soffset + lwb->value - 1;
233722803Smckusick 	  typelen = upb->value - lwb->value + 1;
233822803Smckusick 	  frvexpr((vexpr *) lwb);
233922803Smckusick 	  frvexpr((vexpr *) upb);
234022803Smckusick 	}
234122803Smckusick 
234233256Sbostic       constant = getdatum();
234333256Sbostic       if (constant == NULL || !ISCONST(constant))
234422803Smckusick 	return;
234522803Smckusick 
234633256Sbostic       constant = (Constp) convconst(type, typelen, constant);
234733256Sbostic       if (constant == NULL || !ISCONST(constant))
234822803Smckusick 	{
234933256Sbostic 	  frexpr((tagptr) constant);
235022803Smckusick 	  return;
235122803Smckusick 	}
235222803Smckusick 
235322803Smckusick       if (type == TYCHAR)
235433256Sbostic 	wrtdata(base + soffset, 1, typelen, constant->constant.ccp);
235522803Smckusick       else
235633256Sbostic 	wrtdata(base + soffset, 1, typelen, packbytes(constant));
235722803Smckusick 
235833256Sbostic       frexpr((tagptr) constant);
235922803Smckusick     }
236022803Smckusick   else
236122803Smckusick     {
236222803Smckusick       soffset = 0;
236333256Sbostic       k = np->vdim->nelt->constblock.constant.ci;
236422803Smckusick       while (k > 0 && dataerror == NO)
236522803Smckusick 	{
236622803Smckusick 	  if (grvals == NULL)
236722803Smckusick 	    {
236822803Smckusick 	      err(toofew);
236922803Smckusick 	      dataerror = YES;
237022803Smckusick 	    }
237122803Smckusick 	  else if (grvals->status != NORMAL)
237222803Smckusick 	    dataerror = YES;
237322803Smckusick 	  else if (grvals-> repl <= 0)
237422803Smckusick 	    {
237522803Smckusick 	      badvalue = 0;
237622803Smckusick 	      frexpr((tagptr) grvals->value);
237722803Smckusick 	      t = grvals;
237822803Smckusick 	      grvals = t->next;
237922803Smckusick 	      free((char *) t);
238022803Smckusick 	    }
238122803Smckusick 	  else
238222803Smckusick 	    {
238333256Sbostic 	      constant = grvals->value;
238433256Sbostic 	      if (constant == NULL || !ISCONST(constant))
238522803Smckusick 		{
238622803Smckusick 		  dataerror = YES;
238722803Smckusick 		}
238822803Smckusick 	      else
238922803Smckusick 		{
239033256Sbostic 		  constant = (Constp) convconst(type, typelen, constant);
239133256Sbostic 		  if (constant == NULL || !ISCONST(constant))
239222803Smckusick 		    {
239322803Smckusick 		      dataerror = YES;
239433256Sbostic 		      frexpr((tagptr) constant);
239522803Smckusick 		    }
239622803Smckusick 		  else
239722803Smckusick 		    {
239822803Smckusick 		      if (k > grvals->repl)
239922803Smckusick 			repl = grvals->repl;
240022803Smckusick 		      else
240122803Smckusick 			repl = k;
240222803Smckusick 
240322803Smckusick 		      grvals->repl -= repl;
240422803Smckusick 		      k -= repl;
240522803Smckusick 
240622803Smckusick 		      if (type == TYCHAR)
240733256Sbostic 			wrtdata(base+soffset, repl, typelen, constant->constant.ccp);
240822803Smckusick 		      else
240933256Sbostic 			wrtdata(base+soffset, repl, typelen, packbytes(constant));
241022803Smckusick 
241122803Smckusick 		      soffset = soffset + repl * typelen;
241222803Smckusick 
241333256Sbostic 		      frexpr((tagptr) constant);
241422803Smckusick 		    }
241522803Smckusick 		}
241622803Smckusick 	    }
241722803Smckusick 	}
241822803Smckusick     }
241922803Smckusick 
242022803Smckusick   return;
242122803Smckusick }
242222803Smckusick 
242322803Smckusick 
242422803Smckusick 
outdolist(dp)242522803Smckusick outdolist(dp)
242622803Smckusick dolist *dp;
242722803Smckusick {
242822803Smckusick   static char *zerostep = "zero step in implied-DO";
242922803Smckusick   static char *order = "zero iteration count in implied-DO";
243022803Smckusick 
243122803Smckusick   register dvalue *e1, *e2, *e3;
243222803Smckusick   register int direction;
243322803Smckusick   register dvalue *dv;
243422803Smckusick   register int done;
243522803Smckusick   register int addin;
243622803Smckusick   register int ts;
243722803Smckusick   register ftnint tv;
243822803Smckusick 
243922803Smckusick   e1 = (dvalue *) evalvexpr(dp->init);
244022803Smckusick   e2 = (dvalue *) evalvexpr(dp->limit);
244122803Smckusick   e3 = (dvalue *) evalvexpr(dp->step);
244222803Smckusick 
244322803Smckusick   if (e1->status == ERRVAL ||
244422803Smckusick       e2->status == ERRVAL ||
244522803Smckusick       e3->status == ERRVAL)
244622803Smckusick     {
244722803Smckusick       dataerror = YES;
244822803Smckusick       goto ret;
244922803Smckusick     }
245022803Smckusick 
245122803Smckusick   if (e1->status == NORMAL)
245222803Smckusick     {
245322803Smckusick       if (e2->status == NORMAL)
245422803Smckusick 	{
245522803Smckusick 	  if (e1->value < e2->value)
245622803Smckusick 	    direction = 1;
245722803Smckusick 	  else if (e1->value > e2->value)
245822803Smckusick 	    direction = -1;
245922803Smckusick 	  else
246022803Smckusick 	    direction = 0;
246122803Smckusick 	}
246222803Smckusick       else if (e2->status == MAXPLUS1)
246322803Smckusick 	direction = 1;
246422803Smckusick       else
246522803Smckusick 	direction = -1;
246622803Smckusick     }
246722803Smckusick   else if (e1->status == MAXPLUS1)
246822803Smckusick     {
246922803Smckusick       if (e2->status == MAXPLUS1)
247022803Smckusick 	direction = 0;
247122803Smckusick       else
247222803Smckusick 	direction = -1;
247322803Smckusick     }
247422803Smckusick   else
247522803Smckusick     {
247622803Smckusick       if (e2->status == MINLESS1)
247722803Smckusick 	direction = 0;
247822803Smckusick       else
247922803Smckusick 	direction = 1;
248022803Smckusick     }
248122803Smckusick 
248222803Smckusick   if (e3->status == NORMAL && e3->value == 0)
248322803Smckusick     {
248422803Smckusick       err(zerostep);
248522803Smckusick       dataerror = YES;
248622803Smckusick       goto ret;
248722803Smckusick     }
248822803Smckusick   else if (e3->status == MAXPLUS1 ||
248922803Smckusick 	   (e3->status == NORMAL && e3->value > 0))
249022803Smckusick     {
249122803Smckusick       if (direction == -1)
249222803Smckusick 	{
249322803Smckusick 	  warn(order);
249422803Smckusick 	  goto ret;
249522803Smckusick 	}
249622803Smckusick     }
249722803Smckusick   else
249822803Smckusick     {
249922803Smckusick       if (direction == 1)
250022803Smckusick 	{
250122803Smckusick 	  warn(order);
250222803Smckusick 	  goto ret;
250322803Smckusick 	}
250422803Smckusick     }
250522803Smckusick 
250622803Smckusick   dv = (dvalue *) dp->dovar;
250722803Smckusick   dv->status = e1->status;
250822803Smckusick   dv->value = e1->value;
250922803Smckusick 
251022803Smckusick   done = NO;
251122803Smckusick   while (done == NO && dataerror == NO)
251222803Smckusick     {
251322803Smckusick       outdata(dp->elts);
251422803Smckusick 
251522803Smckusick       if (e3->status == NORMAL && dv->status == NORMAL)
251622803Smckusick 	{
251722803Smckusick 	  addints(e3->value, dv->value);
251822803Smckusick 	  dv->status = rstatus;
251922803Smckusick 	  dv->value = rvalue;
252022803Smckusick 	}
252122803Smckusick       else
252222803Smckusick 	{
252322803Smckusick 	  if (e3->status != NORMAL)
252422803Smckusick 	    {
252522803Smckusick 	      if (e3->status == MAXPLUS1)
252622803Smckusick 		addin = MAXPLUS1;
252722803Smckusick 	      else
252822803Smckusick 		addin = MINLESS1;
252922803Smckusick 	      ts = dv->status;
253022803Smckusick 	      tv = dv->value;
253122803Smckusick 	    }
253222803Smckusick 	  else
253322803Smckusick 	    {
253422803Smckusick 	      if (dv->status == MAXPLUS1)
253522803Smckusick 		addin = MAXPLUS1;
253622803Smckusick 	      else
253722803Smckusick 		addin = MINLESS1;
253822803Smckusick 	      ts = e3->status;
253922803Smckusick 	      tv = e3->value;
254022803Smckusick 	    }
254122803Smckusick 
254222803Smckusick 	  if (addin == MAXPLUS1)
254322803Smckusick 	    {
254422803Smckusick 	      if (ts == MAXPLUS1 || (ts == NORMAL && tv > 0))
254522803Smckusick 		dv->status = ERRVAL;
254622803Smckusick 	      else if (ts == NORMAL && tv == 0)
254722803Smckusick 		dv->status = MAXPLUS1;
254822803Smckusick 	      else if (ts == NORMAL)
254922803Smckusick 		{
255022803Smckusick 		  dv->status = NORMAL;
255122803Smckusick 		  dv->value = tv + MAXINT;
255222803Smckusick 		  dv->value++;
255322803Smckusick 		}
255422803Smckusick 	      else
255522803Smckusick 		{
255622803Smckusick 		  dv->status = NORMAL;
255722803Smckusick 		  dv->value = 0;
255822803Smckusick 		}
255922803Smckusick 	    }
256022803Smckusick 	  else
256122803Smckusick 	    {
256222803Smckusick 	      if (ts == MINLESS1 || (ts == NORMAL && tv < 0))
256322803Smckusick 		dv->status = ERRVAL;
256422803Smckusick 	      else if (ts == NORMAL && tv == 0)
256522803Smckusick 		dv->status = MINLESS1;
256622803Smckusick 	      else if (ts == NORMAL)
256722803Smckusick 		{
256822803Smckusick 		  dv->status = NORMAL;
256922803Smckusick 		  dv->value = tv - MAXINT;
257022803Smckusick 		  dv->value--;
257122803Smckusick 		}
257222803Smckusick 	      else
257322803Smckusick 		{
257422803Smckusick 		  dv->status = NORMAL;
257522803Smckusick 		  dv->value = 0;
257622803Smckusick 		}
257722803Smckusick 	    }
257822803Smckusick 	}
257922803Smckusick 
258022803Smckusick       if (dv->status == ERRVAL)
258122803Smckusick 	done = YES;
258222803Smckusick       else if (direction > 0)
258322803Smckusick 	{
258422803Smckusick 	  if (e2->status == NORMAL)
258522803Smckusick 	    {
258622803Smckusick 	      if (dv->status == MAXPLUS1 ||
258722803Smckusick 		  (dv->status == NORMAL && dv->value > e2->value))
258822803Smckusick 		done = YES;
258922803Smckusick 	    }
259022803Smckusick 	}
259122803Smckusick       else if (direction < 0)
259222803Smckusick 	{
259322803Smckusick 	  if (e2->status == NORMAL)
259422803Smckusick 	    {
259522803Smckusick 	      if (dv->status == MINLESS1 ||
259622803Smckusick 		  (dv->status == NORMAL && dv->value < e2->value))
259722803Smckusick 		done = YES;
259822803Smckusick 	    }
259922803Smckusick 	}
260022803Smckusick       else
260122803Smckusick 	done = YES;
260222803Smckusick     }
260322803Smckusick 
260422803Smckusick ret:
260522803Smckusick   frvexpr((vexpr *) e1);
260622803Smckusick   frvexpr((vexpr *) e2);
260722803Smckusick   frvexpr((vexpr *) e3);
260822803Smckusick   return;
260922803Smckusick }
2610