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