xref: /csrg-svn/usr.bin/f77/pass1.tahoe/data.c (revision 46302)
143205Sbostic /*
243205Sbostic  * Copyright (c) 1980 Regents of the University of California.
343205Sbostic  * All rights reserved.  The Berkeley software License Agreement
443205Sbostic  * specifies the terms and conditions for redistribution.
543205Sbostic  */
643205Sbostic 
743205Sbostic #ifndef lint
843205Sbostic static char sccsid[] = "@(#)data.c	5.1 (Berkeley) 6/7/85";
943205Sbostic #endif not lint
1043205Sbostic 
1143205Sbostic /*
1243205Sbostic  * data.c
1343205Sbostic  *
1443205Sbostic  * Routines for handling DATA statements, f77 compiler, 4.2 BSD.
1543205Sbostic  *
1643205Sbostic  * University of Utah CS Dept modification history:
1743205Sbostic  *
1843205Sbostic  * Revision 3.1  84/10/13  01:09:50  donn
1943205Sbostic  * Installed Jerry Berkman's version; added UofU comment header.
2043205Sbostic  *
2143205Sbostic  */
2243205Sbostic 
2343205Sbostic #include "defs.h"
2443205Sbostic #include "data.h"
2543205Sbostic 
2643205Sbostic 
2743205Sbostic /*  global variables  */
2843205Sbostic 
2943205Sbostic flag overlapflag;
3043205Sbostic 
3143205Sbostic 
3243205Sbostic 
3343205Sbostic /*  local variables  */
3443205Sbostic 
3543205Sbostic LOCAL char rstatus;
3643205Sbostic LOCAL ftnint rvalue;
3743205Sbostic LOCAL dovars *dvlist;
3843205Sbostic LOCAL int dataerror;
3943205Sbostic LOCAL vallist *grvals;
4043205Sbostic LOCAL int datafile;
4143205Sbostic LOCAL int chkfile;
4243205Sbostic LOCAL long base;
4343205Sbostic 
4443205Sbostic 
4543205Sbostic 
4643205Sbostic /*  Copied from expr.c  */
4743205Sbostic 
4843205Sbostic LOCAL letter(c)
4943205Sbostic register int c;
5043205Sbostic {
5143205Sbostic if( isupper(c) )
5243205Sbostic 	c = tolower(c);
5343205Sbostic return(c - 'a');
5443205Sbostic }
5543205Sbostic 
5643205Sbostic 
5743205Sbostic 
5843205Sbostic vexpr *
5943205Sbostic cpdvalue(dp)
6043205Sbostic vexpr *dp;
6143205Sbostic {
6243205Sbostic   register dvalue *p;
6343205Sbostic 
6443205Sbostic   if (dp->tag != DVALUE)
6543205Sbostic     badtag("cpdvalue", dp->tag);
6643205Sbostic 
6743205Sbostic   p = ALLOC(Dvalue);
6843205Sbostic   p->tag = DVALUE;
6943205Sbostic   p->status = dp->dvalue.status;
7043205Sbostic   p->value = dp->dvalue.value;
7143205Sbostic 
7243205Sbostic   return ((vexpr *) p);
7343205Sbostic }
7443205Sbostic 
7543205Sbostic 
7643205Sbostic 
7743205Sbostic frvexpr(vp)
7843205Sbostic register vexpr *vp;
7943205Sbostic {
8043205Sbostic   if (vp != NULL)
8143205Sbostic     {
8243205Sbostic       if (vp->tag == DNAME)
8343205Sbostic 	free(vp->dname.repr);
8443205Sbostic       else if (vp->tag == DEXPR)
8543205Sbostic 	{
8643205Sbostic 	  frvexpr(vp->dexpr.left);
8743205Sbostic 	  frvexpr(vp->dexpr.right);
8843205Sbostic 	}
8943205Sbostic 
9043205Sbostic       free((char *) vp);
9143205Sbostic     }
9243205Sbostic 
9343205Sbostic   return;
9443205Sbostic }
9543205Sbostic 
9643205Sbostic 
9743205Sbostic 
9843205Sbostic frvlist(vp)
9943205Sbostic register vlist *vp;
10043205Sbostic {
10143205Sbostic   register vlist *t;
10243205Sbostic 
10343205Sbostic   while (vp)
10443205Sbostic     {
10543205Sbostic       t = vp->next;
10643205Sbostic       frvexpr(vp->val);
10743205Sbostic       free((char *) vp);
10843205Sbostic       vp = t;
10943205Sbostic     }
11043205Sbostic 
11143205Sbostic   return;
11243205Sbostic }
11343205Sbostic 
11443205Sbostic 
11543205Sbostic 
11643205Sbostic frelist(ep)
11743205Sbostic elist *ep;
11843205Sbostic {
11943205Sbostic   register elist *p;
12043205Sbostic   register elist *t;
12143205Sbostic   register aelt *ap;
12243205Sbostic   register dolist *dp;
12343205Sbostic 
12443205Sbostic   p = ep;
12543205Sbostic 
12643205Sbostic   while (p != NULL)
12743205Sbostic     {
12843205Sbostic       if (p->elt->tag == SIMPLE)
12943205Sbostic 	{
13043205Sbostic 	  ap = (aelt *) p->elt;
13143205Sbostic 	  frvlist(ap->subs);
13243205Sbostic 	  if (ap->range != NULL)
13343205Sbostic 	    {
13443205Sbostic 	      frvexpr(ap->range->low);
13543205Sbostic 	      frvexpr(ap->range->high);
13643205Sbostic 	      free((char *) ap->range);
13743205Sbostic 	    }
13843205Sbostic 	  free((char *) ap);
13943205Sbostic 	}
14043205Sbostic       else
14143205Sbostic 	{
14243205Sbostic 	  dp = (dolist *) p->elt;
14343205Sbostic 	  frvexpr(dp->dovar);
14443205Sbostic 	  frvexpr(dp->init);
14543205Sbostic 	  frvexpr(dp->limit);
14643205Sbostic 	  frvexpr(dp->step);
14743205Sbostic 	  frelist(dp->elts);
14843205Sbostic 	  free((char *) dp);
14943205Sbostic 	}
15043205Sbostic 
15143205Sbostic       t = p;
15243205Sbostic       p = p->next;
15343205Sbostic       free((char *) t);
15443205Sbostic     }
15543205Sbostic 
15643205Sbostic   return;
15743205Sbostic }
15843205Sbostic 
15943205Sbostic 
16043205Sbostic 
16143205Sbostic frvallist(vp)
16243205Sbostic vallist *vp;
16343205Sbostic {
16443205Sbostic   register vallist *p;
16543205Sbostic   register vallist *t;
16643205Sbostic 
16743205Sbostic   p = vp;
16843205Sbostic   while (p != NULL)
16943205Sbostic     {
17043205Sbostic       frexpr((tagptr) p->value);
17143205Sbostic       t = p;
17243205Sbostic       p = p->next;
17343205Sbostic       free((char *) t);
17443205Sbostic     }
17543205Sbostic 
17643205Sbostic   return;
17743205Sbostic }
17843205Sbostic 
17943205Sbostic 
18043205Sbostic 
18143205Sbostic elist *revelist(ep)
18243205Sbostic register elist *ep;
18343205Sbostic {
18443205Sbostic   register elist *next;
18543205Sbostic   register elist *t;
18643205Sbostic 
18743205Sbostic   if (ep != NULL)
18843205Sbostic     {
18943205Sbostic       next = ep->next;
19043205Sbostic       ep->next = NULL;
19143205Sbostic 
19243205Sbostic       while (next)
19343205Sbostic 	{
19443205Sbostic 	  t = next->next;
19543205Sbostic 	  next->next = ep;
19643205Sbostic 	  ep = next;
19743205Sbostic 	  next = t;
19843205Sbostic 	}
19943205Sbostic     }
20043205Sbostic 
20143205Sbostic   return (ep);
20243205Sbostic }
20343205Sbostic 
20443205Sbostic 
20543205Sbostic 
20643205Sbostic vlist *revvlist(vp)
20743205Sbostic vlist *vp;
20843205Sbostic {
20943205Sbostic   register vlist *p;
21043205Sbostic   register vlist *next;
21143205Sbostic   register vlist *t;
21243205Sbostic 
21343205Sbostic   if (vp == NULL)
21443205Sbostic     p = NULL;
21543205Sbostic   else
21643205Sbostic     {
21743205Sbostic       p = vp;
21843205Sbostic       next = p->next;
21943205Sbostic       p->next = NULL;
22043205Sbostic 
22143205Sbostic       while (next)
22243205Sbostic 	{
22343205Sbostic 	  t = next->next;
22443205Sbostic 	  next->next = p;
22543205Sbostic 	  p = next;
22643205Sbostic 	  next = t;
22743205Sbostic 	}
22843205Sbostic     }
22943205Sbostic 
23043205Sbostic   return (p);
23143205Sbostic }
23243205Sbostic 
23343205Sbostic 
23443205Sbostic 
23543205Sbostic vallist *
23643205Sbostic revrvals(vp)
23743205Sbostic vallist *vp;
23843205Sbostic {
23943205Sbostic   register vallist *p;
24043205Sbostic   register vallist *next;
24143205Sbostic   register vallist *t;
24243205Sbostic 
24343205Sbostic   if (vp == NULL)
24443205Sbostic     p = NULL;
24543205Sbostic   else
24643205Sbostic     {
24743205Sbostic       p = vp;
24843205Sbostic       next = p->next;
24943205Sbostic       p->next = NULL;
25043205Sbostic       while (next)
25143205Sbostic 	{
25243205Sbostic 	  t = next->next;
25343205Sbostic 	  next->next = p;
25443205Sbostic 	  p = next;
25543205Sbostic 	  next = t;
25643205Sbostic 	}
25743205Sbostic     }
25843205Sbostic 
25943205Sbostic   return (p);
26043205Sbostic }
26143205Sbostic 
26243205Sbostic 
26343205Sbostic 
26443205Sbostic vlist *prepvexpr(tail, head)
26543205Sbostic vlist *tail;
26643205Sbostic vexpr *head;
26743205Sbostic {
26843205Sbostic   register vlist *p;
26943205Sbostic 
27043205Sbostic   p = ALLOC(Vlist);
27143205Sbostic   p->next = tail;
27243205Sbostic   p->val = head;
27343205Sbostic 
27443205Sbostic   return (p);
27543205Sbostic }
27643205Sbostic 
27743205Sbostic 
27843205Sbostic 
27943205Sbostic elist *preplval(tail, head)
28043205Sbostic elist *tail;
28143205Sbostic delt* head;
28243205Sbostic {
28343205Sbostic   register elist *p;
28443205Sbostic   p = ALLOC(Elist);
28543205Sbostic   p->next = tail;
28643205Sbostic   p->elt = head;
28743205Sbostic 
28843205Sbostic   return (p);
28943205Sbostic }
29043205Sbostic 
29143205Sbostic 
29243205Sbostic 
29343205Sbostic delt *mkdlval(name, subs, range)
29443205Sbostic vexpr *name;
29543205Sbostic vlist *subs;
29643205Sbostic rpair *range;
29743205Sbostic {
29843205Sbostic   static char *iscomm =" improper initialization for variable in COMMON";
29943205Sbostic   register aelt *p;
30043205Sbostic 
30143205Sbostic   p = ALLOC(Aelt);
30243205Sbostic   p->tag = SIMPLE;
30343205Sbostic   p->var = mkname(name->dname.len, name->dname.repr);
30443205Sbostic   if ((procclass != CLBLOCK) && (p->var->vstg == STGCOMMON))
30543205Sbostic 	warn(iscomm);
30643205Sbostic   p->subs = subs;
30743205Sbostic   p->range = range;
30843205Sbostic 
30943205Sbostic   return ((delt *) p);
31043205Sbostic }
31143205Sbostic 
31243205Sbostic 
31343205Sbostic 
31443205Sbostic delt *mkdatado(lvals, dovar, params)
31543205Sbostic elist *lvals;
31643205Sbostic vexpr *dovar;
31743205Sbostic vlist *params;
31843205Sbostic {
31943205Sbostic   static char *toofew = "missing loop parameters";
32043205Sbostic   static char *toomany = "too many loop parameters";
32143205Sbostic 
32243205Sbostic   register dolist *p;
32343205Sbostic   register vlist *vp;
32443205Sbostic   register int pcnt;
32543205Sbostic   register dvalue *one;
32643205Sbostic 
32743205Sbostic   p = ALLOC(DoList);
32843205Sbostic   p->tag = NESTED;
32943205Sbostic   p->elts = revelist(lvals);
33043205Sbostic   p->dovar = dovar;
33143205Sbostic 
33243205Sbostic   vp = params;
33343205Sbostic   pcnt = 0;
33443205Sbostic   while (vp)
33543205Sbostic     {
33643205Sbostic       pcnt++;
33743205Sbostic       vp = vp->next;
33843205Sbostic     }
33943205Sbostic 
34043205Sbostic   if (pcnt != 2 && pcnt != 3)
34143205Sbostic     {
34243205Sbostic       if (pcnt < 2)
34343205Sbostic 	err(toofew);
34443205Sbostic       else
34543205Sbostic 	err(toomany);
34643205Sbostic 
34743205Sbostic       p->init = (vexpr *) ALLOC(Derror);
34843205Sbostic       p->init->tag = DERROR;
34943205Sbostic 
35043205Sbostic       p->limit = (vexpr *) ALLOC(Derror);
35143205Sbostic       p->limit->tag = DERROR;
35243205Sbostic 
35343205Sbostic       p->step = (vexpr *) ALLOC(Derror);
35443205Sbostic       p->step->tag = DERROR;
35543205Sbostic     }
35643205Sbostic   else
35743205Sbostic     {
35843205Sbostic       vp = params;
35943205Sbostic 
36043205Sbostic       if (pcnt == 2)
36143205Sbostic 	{
36243205Sbostic 	  one = ALLOC(Dvalue);
36343205Sbostic 	  one->tag = DVALUE;
36443205Sbostic 	  one->status = NORMAL;
36543205Sbostic 	  one->value = 1;
36643205Sbostic 	  p->step = (vexpr *) one;
36743205Sbostic 	}
36843205Sbostic       else
36943205Sbostic 	{
37043205Sbostic 	  p->step = vp->val;
37143205Sbostic 	  vp->val = NULL;
37243205Sbostic 	  vp = vp->next;
37343205Sbostic 	}
37443205Sbostic 
37543205Sbostic       p->limit = vp->val;
37643205Sbostic       vp->val = NULL;
37743205Sbostic       vp = vp->next;
37843205Sbostic 
37943205Sbostic       p->init = vp->val;
38043205Sbostic       vp->val = NULL;
38143205Sbostic     }
38243205Sbostic 
38343205Sbostic   frvlist(params);
38443205Sbostic   return ((delt *) p);
38543205Sbostic }
38643205Sbostic 
38743205Sbostic 
38843205Sbostic 
38943205Sbostic rpair *mkdrange(lb, ub)
39043205Sbostic vexpr *lb, *ub;
39143205Sbostic {
39243205Sbostic   register rpair *p;
39343205Sbostic 
39443205Sbostic   p = ALLOC(Rpair);
39543205Sbostic   p->low = lb;
39643205Sbostic   p->high = ub;
39743205Sbostic 
39843205Sbostic   return (p);
39943205Sbostic }
40043205Sbostic 
40143205Sbostic 
40243205Sbostic 
40343205Sbostic vallist *mkdrval(repl, val)
40443205Sbostic vexpr *repl;
40543205Sbostic expptr val;
40643205Sbostic {
40743205Sbostic   static char *badtag = "bad tag in mkdrval";
40843205Sbostic   static char *negrepl = "negative replicator";
40943205Sbostic   static char *zerorepl = "zero replicator";
41043205Sbostic   static char *toobig = "replicator too large";
41143205Sbostic   static char *nonconst = "%s is not a constant";
41243205Sbostic 
41343205Sbostic   register vexpr *vp;
41443205Sbostic   register vallist *p;
41543205Sbostic   register int status;
41643205Sbostic   register ftnint value;
41743205Sbostic   register int copied;
41843205Sbostic 
41943205Sbostic   copied = 0;
42043205Sbostic 
42143205Sbostic   if (repl->tag == DNAME)
42243205Sbostic     {
42343205Sbostic       vp = evaldname(repl);
42443205Sbostic       copied = 1;
42543205Sbostic     }
42643205Sbostic   else
42743205Sbostic     vp = repl;
42843205Sbostic 
42943205Sbostic   p = ALLOC(ValList);
43043205Sbostic   p->next = NULL;
43143205Sbostic   p->value = (Constp) val;
43243205Sbostic 
43343205Sbostic   if (vp->tag == DVALUE)
43443205Sbostic     {
43543205Sbostic       status = vp->dvalue.status;
43643205Sbostic       value = vp->dvalue.value;
43743205Sbostic 
43843205Sbostic       if ((status == NORMAL && value < 0) || status == MINLESS1)
43943205Sbostic 	{
44043205Sbostic 	  err(negrepl);
44143205Sbostic 	  p->status = ERRVAL;
44243205Sbostic 	}
44343205Sbostic       else if (status == NORMAL)
44443205Sbostic 	{
44543205Sbostic 	  if (value == 0)
44643205Sbostic 	    warn(zerorepl);
44743205Sbostic 	  p->status = NORMAL;
44843205Sbostic 	  p->repl = value;
44943205Sbostic 	}
45043205Sbostic       else if (status == MAXPLUS1)
45143205Sbostic 	{
45243205Sbostic 	  err(toobig);
45343205Sbostic 	  p->status = ERRVAL;
45443205Sbostic 	}
45543205Sbostic       else
45643205Sbostic 	p->status = ERRVAL;
45743205Sbostic     }
45843205Sbostic   else if (vp->tag == DNAME)
45943205Sbostic     {
46043205Sbostic       errnm(nonconst, vp->dname.len, vp->dname.repr);
46143205Sbostic       p->status = ERRVAL;
46243205Sbostic     }
46343205Sbostic   else if (vp->tag == DERROR)
46443205Sbostic     p->status = ERRVAL;
46543205Sbostic   else
46643205Sbostic     fatal(badtag);
46743205Sbostic 
46843205Sbostic   if (copied) frvexpr(vp);
46943205Sbostic   return (p);
47043205Sbostic }
47143205Sbostic 
47243205Sbostic 
47343205Sbostic 
47443205Sbostic /*  Evicon returns the value of the integer constant  */
47543205Sbostic /*  pointed to by token.                              */
47643205Sbostic 
47743205Sbostic vexpr *evicon(len, token)
47843205Sbostic register int len;
47943205Sbostic register char *token;
48043205Sbostic {
48143205Sbostic   static char *badconst = "bad integer constant";
48243205Sbostic   static char *overflow = "integer constant too large";
48343205Sbostic 
48443205Sbostic   register int i;
48543205Sbostic   register ftnint val;
48643205Sbostic   register int digit;
48743205Sbostic   register dvalue *p;
48843205Sbostic 
48943205Sbostic   if (len <= 0)
49043205Sbostic     fatal(badconst);
49143205Sbostic 
49243205Sbostic   p = ALLOC(Dvalue);
49343205Sbostic   p->tag = DVALUE;
49443205Sbostic 
49543205Sbostic   i = 0;
49643205Sbostic   val = 0;
49743205Sbostic   while (i < len)
49843205Sbostic     {
49943205Sbostic       if (val > MAXINT/10)
50043205Sbostic 	{
50143205Sbostic 	  err(overflow);
50243205Sbostic 	  p->status = ERRVAL;
50343205Sbostic 	  goto ret;
50443205Sbostic 	}
50543205Sbostic       val = 10*val;
50643205Sbostic       digit = token[i++];
50743205Sbostic       if (!isdigit(digit))
50843205Sbostic 	fatal(badconst);
50943205Sbostic       digit = digit - '0';
51043205Sbostic       if (MAXINT - val >= digit)
51143205Sbostic 	val = val + digit;
51243205Sbostic       else
51343205Sbostic 	if (i == len && MAXINT - val + 1 == digit)
51443205Sbostic 	  {
51543205Sbostic 	    p->status = MAXPLUS1;
51643205Sbostic 	    goto ret;
51743205Sbostic 	  }
51843205Sbostic 	else
51943205Sbostic 	  {
52043205Sbostic 	    err(overflow);
52143205Sbostic 	    p->status = ERRVAL;
52243205Sbostic 	    goto ret;
52343205Sbostic 	  }
52443205Sbostic     }
52543205Sbostic 
52643205Sbostic   p->status = NORMAL;
52743205Sbostic   p->value = val;
52843205Sbostic 
52943205Sbostic ret:
53043205Sbostic   return ((vexpr *) p);
53143205Sbostic }
53243205Sbostic 
53343205Sbostic 
53443205Sbostic 
53543205Sbostic /*  Ivaltoicon converts a dvalue into a constant block.  */
53643205Sbostic 
53743205Sbostic expptr ivaltoicon(vp)
53843205Sbostic register vexpr *vp;
53943205Sbostic {
54043205Sbostic   static char *badtag = "bad tag in ivaltoicon";
54143205Sbostic   static char *overflow = "integer constant too large";
54243205Sbostic 
54343205Sbostic   register int vs;
54443205Sbostic   register expptr p;
54543205Sbostic 
54643205Sbostic   if (vp->tag == DERROR)
54743205Sbostic     return(errnode());
54843205Sbostic   else if (vp->tag != DVALUE)
54943205Sbostic     fatal(badtag);
55043205Sbostic 
55143205Sbostic   vs = vp->dvalue.status;
55243205Sbostic   if (vs == NORMAL)
55343205Sbostic     p = mkintcon(vp->dvalue.value);
55443205Sbostic   else if ((MAXINT + MININT == -1) && vs == MINLESS1)
55543205Sbostic     p = mkintcon(MININT);
55643205Sbostic   else if (vs == MAXPLUS1 || vs == MINLESS1)
55743205Sbostic     {
55843205Sbostic       err(overflow);
55943205Sbostic       p = errnode();
56043205Sbostic     }
56143205Sbostic   else
56243205Sbostic     p = errnode();
56343205Sbostic 
56443205Sbostic   return (p);
56543205Sbostic }
56643205Sbostic 
56743205Sbostic 
56843205Sbostic 
56943205Sbostic /*  Mkdname stores an identifier as a dname  */
57043205Sbostic 
57143205Sbostic vexpr *mkdname(len, str)
57243205Sbostic int len;
57343205Sbostic register char *str;
57443205Sbostic {
57543205Sbostic   register dname *p;
57643205Sbostic   register int i;
57743205Sbostic   register char *s;
57843205Sbostic 
57943205Sbostic   s = (char *) ckalloc(len + 1);
58043205Sbostic   i = len;
58143205Sbostic   s[i] = '\0';
58243205Sbostic 
58343205Sbostic   while (--i >= 0)
58443205Sbostic     s[i] = str[i];
58543205Sbostic 
58643205Sbostic   p = ALLOC(Dname);
58743205Sbostic   p->tag = DNAME;
58843205Sbostic   p->len = len;
58943205Sbostic   p->repr = s;
59043205Sbostic 
59143205Sbostic   return ((vexpr *) p);
59243205Sbostic }
59343205Sbostic 
59443205Sbostic 
59543205Sbostic 
59643205Sbostic /*  Getname gets the symbol table information associated with  */
59743205Sbostic /*  a name.  Getname differs from mkname in that it will not   */
59843205Sbostic /*  add the name to the symbol table if it is not already      */
59943205Sbostic /*  present.                                                   */
60043205Sbostic 
60143205Sbostic Namep getname(l, s)
60243205Sbostic int l;
60343205Sbostic register char *s;
60443205Sbostic {
60543205Sbostic   struct Hashentry *hp;
60643205Sbostic   int hash;
60743205Sbostic   register Namep q;
60843205Sbostic   register int i;
60943205Sbostic   char n[VL];
61043205Sbostic 
61143205Sbostic   hash = 0;
61243205Sbostic   for (i = 0; i < l && *s != '\0'; ++i)
61343205Sbostic     {
61443205Sbostic       hash += *s;
61543205Sbostic       n[i] = *s++;
61643205Sbostic     }
61743205Sbostic 
61843205Sbostic   while (i < VL)
61943205Sbostic     n[i++] = ' ';
62043205Sbostic 
62143205Sbostic   hash %= maxhash;
62243205Sbostic   hp = hashtab + hash;
62343205Sbostic 
62443205Sbostic   while (q = hp->varp)
62543205Sbostic     if (hash == hp->hashval
62643205Sbostic 	&& eqn(VL, n, q->varname))
62743205Sbostic       goto ret;
62843205Sbostic     else if (++hp >= lasthash)
62943205Sbostic       hp = hashtab;
63043205Sbostic 
63143205Sbostic ret:
63243205Sbostic   return (q);
63343205Sbostic }
63443205Sbostic 
63543205Sbostic 
63643205Sbostic 
63743205Sbostic /*  Evparam returns the value of the constant named by name.  */
63843205Sbostic 
63943205Sbostic expptr evparam(np)
64043205Sbostic register vexpr *np;
64143205Sbostic {
64243205Sbostic   static char *badtag = "bad tag in evparam";
64343205Sbostic   static char *undefined = "%s is undefined";
64443205Sbostic   static char *nonconst = "%s is not constant";
64543205Sbostic 
64643205Sbostic   register struct Paramblock *tp;
64743205Sbostic   register expptr p;
64843205Sbostic   register int len;
64943205Sbostic   register char *repr;
65043205Sbostic 
65143205Sbostic   if (np->tag != DNAME)
65243205Sbostic     fatal(badtag);
65343205Sbostic 
65443205Sbostic   len = np->dname.len;
65543205Sbostic   repr = np->dname.repr;
65643205Sbostic 
65743205Sbostic   tp = (struct Paramblock *) getname(len, repr);
65843205Sbostic 
65943205Sbostic   if (tp == NULL)
66043205Sbostic     {
66143205Sbostic       errnm(undefined, len, repr);
66243205Sbostic       p = errnode();
66343205Sbostic     }
66443205Sbostic   else if (tp->vclass != CLPARAM || !ISCONST(tp->paramval))
66543205Sbostic     {
66643205Sbostic       if (tp->paramval->tag != TERROR)
66743205Sbostic         errnm(nonconst, len, repr);
66843205Sbostic       p = errnode();
66943205Sbostic     }
67043205Sbostic   else
67143205Sbostic     p = (expptr) cpexpr(tp->paramval);
67243205Sbostic 
67343205Sbostic   return (p);
67443205Sbostic }
67543205Sbostic 
67643205Sbostic 
67743205Sbostic 
67843205Sbostic vexpr *evaldname(dp)
67943205Sbostic vexpr *dp;
68043205Sbostic {
68143205Sbostic   static char *undefined = "%s is undefined";
68243205Sbostic   static char *nonconst = "%s is not a constant";
68343205Sbostic   static char *nonint = "%s is not an integer";
68443205Sbostic 
68543205Sbostic   register dvalue *p;
68643205Sbostic   register struct Paramblock *tp;
68743205Sbostic   register int len;
68843205Sbostic   register char *repr;
68943205Sbostic 
69043205Sbostic   p = ALLOC(Dvalue);
69143205Sbostic   p->tag = DVALUE;
69243205Sbostic 
69343205Sbostic   len = dp->dname.len;
69443205Sbostic   repr = dp->dname.repr;
69543205Sbostic 
69643205Sbostic   tp = (struct Paramblock *) getname(len, repr);
69743205Sbostic 
69843205Sbostic   if (tp == NULL)
69943205Sbostic     {
70043205Sbostic       errnm(undefined, len, repr);
70143205Sbostic       p->status = ERRVAL;
70243205Sbostic     }
70343205Sbostic   else if (tp->vclass != CLPARAM || !ISCONST(tp->paramval))
70443205Sbostic     {
70543205Sbostic       if (tp->paramval->tag != TERROR)
70643205Sbostic         errnm(nonconst, len, repr);
70743205Sbostic       p->status = ERRVAL;
70843205Sbostic     }
70943205Sbostic   else if (!ISINT(tp->paramval->constblock.vtype))
71043205Sbostic     {
71143205Sbostic       errnm(nonint, len, repr);
71243205Sbostic       p->status = ERRVAL;
71343205Sbostic     }
71443205Sbostic   else
71543205Sbostic     {
71643205Sbostic       if ((MAXINT + MININT == -1)
717*46302Sbostic 	  && tp->paramval->constblock.constant.ci == MININT)
71843205Sbostic 	p->status = MINLESS1;
71943205Sbostic       else
72043205Sbostic 	{
72143205Sbostic 	  p->status = NORMAL;
722*46302Sbostic           p->value = tp->paramval->constblock.constant.ci;
72343205Sbostic 	}
72443205Sbostic     }
72543205Sbostic 
72643205Sbostic   return ((vexpr *) p);
72743205Sbostic }
72843205Sbostic 
72943205Sbostic 
73043205Sbostic 
73143205Sbostic vexpr *mkdexpr(op, l, r)
73243205Sbostic register int op;
73343205Sbostic register vexpr *l;
73443205Sbostic register vexpr *r;
73543205Sbostic {
73643205Sbostic   static char *badop = "bad operator in mkdexpr";
73743205Sbostic 
73843205Sbostic   register vexpr *p;
73943205Sbostic 
74043205Sbostic   switch (op)
74143205Sbostic     {
74243205Sbostic     default:
74343205Sbostic       fatal(badop);
74443205Sbostic 
74543205Sbostic     case OPNEG:
74643205Sbostic     case OPPLUS:
74743205Sbostic     case OPMINUS:
74843205Sbostic     case OPSTAR:
74943205Sbostic     case OPSLASH:
75043205Sbostic     case OPPOWER:
75143205Sbostic       break;
75243205Sbostic     }
75343205Sbostic 
75443205Sbostic   if ((l != NULL && l->tag == DERROR) || r->tag == DERROR)
75543205Sbostic     {
75643205Sbostic       frvexpr(l);
75743205Sbostic       frvexpr(r);
75843205Sbostic       p = (vexpr *) ALLOC(Derror);
75943205Sbostic       p->tag = DERROR;
76043205Sbostic     }
76143205Sbostic   else if (op == OPNEG && r->tag == DVALUE)
76243205Sbostic     {
76343205Sbostic       p = negival(r);
76443205Sbostic       frvexpr(r);
76543205Sbostic     }
76643205Sbostic   else if (op != OPNEG && l->tag == DVALUE && r->tag == DVALUE)
76743205Sbostic     {
76843205Sbostic       switch (op)
76943205Sbostic 	{
77043205Sbostic 	case OPPLUS:
77143205Sbostic 	  p = addivals(l, r);
77243205Sbostic 	  break;
77343205Sbostic 
77443205Sbostic 	case OPMINUS:
77543205Sbostic 	  p = subivals(l, r);
77643205Sbostic 	  break;
77743205Sbostic 
77843205Sbostic 	case OPSTAR:
77943205Sbostic 	  p = mulivals(l, r);
78043205Sbostic 	  break;
78143205Sbostic 
78243205Sbostic 	case OPSLASH:
78343205Sbostic 	  p = divivals(l, r);
78443205Sbostic 	  break;
78543205Sbostic 
78643205Sbostic 	case OPPOWER:
78743205Sbostic 	  p = powivals(l, r);
78843205Sbostic 	  break;
78943205Sbostic 	}
79043205Sbostic 
79143205Sbostic       frvexpr(l);
79243205Sbostic       frvexpr(r);
79343205Sbostic     }
79443205Sbostic   else
79543205Sbostic     {
79643205Sbostic       p = (vexpr *) ALLOC(Dexpr);
79743205Sbostic       p->tag = DEXPR;
79843205Sbostic       p->dexpr.opcode = op;
79943205Sbostic       p->dexpr.left = l;
80043205Sbostic       p->dexpr.right = r;
80143205Sbostic     }
80243205Sbostic 
80343205Sbostic   return (p);
80443205Sbostic }
80543205Sbostic 
80643205Sbostic 
80743205Sbostic 
80843205Sbostic vexpr *addivals(l, r)
80943205Sbostic vexpr *l;
81043205Sbostic vexpr *r;
81143205Sbostic {
81243205Sbostic   static char *badtag = "bad tag in addivals";
81343205Sbostic   static char *overflow = "integer value too large";
81443205Sbostic 
81543205Sbostic   register int ls, rs;
81643205Sbostic   register ftnint lv, rv;
81743205Sbostic   register dvalue *p;
81843205Sbostic   register ftnint k;
81943205Sbostic 
82043205Sbostic   if (l->tag != DVALUE || r->tag != DVALUE)
82143205Sbostic     fatal(badtag);
82243205Sbostic 
82343205Sbostic   ls = l->dvalue.status;
82443205Sbostic   lv = l->dvalue.value;
82543205Sbostic   rs = r->dvalue.status;
82643205Sbostic   rv = r->dvalue.value;
82743205Sbostic 
82843205Sbostic   p = ALLOC(Dvalue);
82943205Sbostic   p->tag = DVALUE;
83043205Sbostic 
83143205Sbostic   if (ls == ERRVAL || rs == ERRVAL)
83243205Sbostic     p->status = ERRVAL;
83343205Sbostic 
83443205Sbostic   else if (ls == NORMAL && rs == NORMAL)
83543205Sbostic     {
83643205Sbostic       addints(lv, rv);
83743205Sbostic       if (rstatus == ERRVAL)
83843205Sbostic 	err(overflow);
83943205Sbostic       p->status = rstatus;
84043205Sbostic       p->value = rvalue;
84143205Sbostic     }
84243205Sbostic 
84343205Sbostic   else
84443205Sbostic     {
84543205Sbostic       if (rs == MAXPLUS1 || rs == MINLESS1)
84643205Sbostic 	{
84743205Sbostic 	  rs = ls;
84843205Sbostic 	  rv = lv;
84943205Sbostic 	  ls = r->dvalue.status;
85043205Sbostic 	}
85143205Sbostic 
85243205Sbostic       if (rs == NORMAL && rv == 0)
85343205Sbostic 	p->status = ls;
85443205Sbostic       else if (ls == MAXPLUS1)
85543205Sbostic 	{
85643205Sbostic 	  if (rs == NORMAL && rv < 0)
85743205Sbostic 	    {
85843205Sbostic 	      p->status = NORMAL;
85943205Sbostic 	      k = MAXINT + rv;
86043205Sbostic 	      p->value = k + 1;
86143205Sbostic 	    }
86243205Sbostic 	  else if (rs == MINLESS1)
86343205Sbostic 	    {
86443205Sbostic 	      p->status = NORMAL;
86543205Sbostic 	      p->value = 0;
86643205Sbostic 	    }
86743205Sbostic 	  else
86843205Sbostic 	    {
86943205Sbostic 	      err(overflow);
87043205Sbostic 	      p->status = ERRVAL;
87143205Sbostic 	    }
87243205Sbostic 	}
87343205Sbostic       else
87443205Sbostic 	{
87543205Sbostic 	  if (rs == NORMAL && rv > 0)
87643205Sbostic 	    {
87743205Sbostic 	      p->status = NORMAL;
87843205Sbostic 	      k = ( -MAXINT ) + rv;
87943205Sbostic 	      p->value = k - 1;
88043205Sbostic 	    }
88143205Sbostic 	  else if (rs == MAXPLUS1)
88243205Sbostic 	    {
88343205Sbostic 	      p->status = NORMAL;
88443205Sbostic 	      p->value = 0;
88543205Sbostic 	    }
88643205Sbostic 	  else
88743205Sbostic 	    {
88843205Sbostic 	      err(overflow);
88943205Sbostic 	      p->status = ERRVAL;
89043205Sbostic 	    }
89143205Sbostic 	}
89243205Sbostic     }
89343205Sbostic 
89443205Sbostic   return ((vexpr *) p);
89543205Sbostic }
89643205Sbostic 
89743205Sbostic 
89843205Sbostic 
89943205Sbostic vexpr *negival(vp)
90043205Sbostic vexpr *vp;
90143205Sbostic {
90243205Sbostic   static char *badtag = "bad tag in negival";
90343205Sbostic 
90443205Sbostic   register int vs;
90543205Sbostic   register dvalue *p;
90643205Sbostic 
90743205Sbostic   if (vp->tag != DVALUE)
90843205Sbostic     fatal(badtag);
90943205Sbostic 
91043205Sbostic   vs = vp->dvalue.status;
91143205Sbostic 
91243205Sbostic   p = ALLOC(Dvalue);
91343205Sbostic   p->tag = DVALUE;
91443205Sbostic 
91543205Sbostic   if (vs == ERRVAL)
91643205Sbostic     p->status = ERRVAL;
91743205Sbostic   else if (vs == NORMAL)
91843205Sbostic     {
91943205Sbostic       p->status = NORMAL;
92043205Sbostic       p->value = -(vp->dvalue.value);
92143205Sbostic     }
92243205Sbostic   else if (vs == MAXPLUS1)
92343205Sbostic     p->status = MINLESS1;
92443205Sbostic   else
92543205Sbostic     p->status = MAXPLUS1;
92643205Sbostic 
92743205Sbostic   return ((vexpr *) p);
92843205Sbostic }
92943205Sbostic 
93043205Sbostic 
93143205Sbostic 
93243205Sbostic vexpr *subivals(l, r)
93343205Sbostic vexpr *l;
93443205Sbostic vexpr *r;
93543205Sbostic {
93643205Sbostic   static char *badtag = "bad tag in subivals";
93743205Sbostic 
93843205Sbostic   register vexpr *p;
93943205Sbostic   register vexpr *t;
94043205Sbostic 
94143205Sbostic   if (l->tag != DVALUE || r->tag != DVALUE)
94243205Sbostic     fatal(badtag);
94343205Sbostic 
94443205Sbostic   t = negival(r);
94543205Sbostic   p = addivals(l, t);
94643205Sbostic   frvexpr(t);
94743205Sbostic 
94843205Sbostic   return (p);
94943205Sbostic }
95043205Sbostic 
95143205Sbostic 
95243205Sbostic 
95343205Sbostic vexpr *mulivals(l, r)
95443205Sbostic vexpr *l;
95543205Sbostic vexpr *r;
95643205Sbostic {
95743205Sbostic   static char *badtag = "bad tag in mulivals";
95843205Sbostic   static char *overflow = "integer value too large";
95943205Sbostic 
96043205Sbostic   register int ls, rs;
96143205Sbostic   register ftnint lv, rv;
96243205Sbostic   register dvalue *p;
96343205Sbostic 
96443205Sbostic   if (l->tag != DVALUE || r->tag != DVALUE)
96543205Sbostic     fatal(badtag);
96643205Sbostic 
96743205Sbostic   ls = l->dvalue.status;
96843205Sbostic   lv = l->dvalue.value;
96943205Sbostic   rs = r->dvalue.status;
97043205Sbostic   rv = r->dvalue.value;
97143205Sbostic 
97243205Sbostic   p = ALLOC(Dvalue);
97343205Sbostic   p->tag = DVALUE;
97443205Sbostic 
97543205Sbostic   if (ls == ERRVAL || rs == ERRVAL)
97643205Sbostic     p->status = ERRVAL;
97743205Sbostic 
97843205Sbostic   else if (ls == NORMAL && rs == NORMAL)
97943205Sbostic     {
98043205Sbostic       mulints(lv, rv);
98143205Sbostic       if (rstatus == ERRVAL)
98243205Sbostic 	err(overflow);
98343205Sbostic       p->status = rstatus;
98443205Sbostic       p->value = rvalue;
98543205Sbostic     }
98643205Sbostic   else
98743205Sbostic     {
98843205Sbostic       if (rs == MAXPLUS1 || rs == MINLESS1)
98943205Sbostic 	{
99043205Sbostic 	  rs = ls;
99143205Sbostic 	  rv = lv;
99243205Sbostic 	  ls = r->dvalue.status;
99343205Sbostic 	}
99443205Sbostic 
99543205Sbostic       if (rs == NORMAL && rv == 0)
99643205Sbostic 	{
99743205Sbostic 	  p->status = NORMAL;
99843205Sbostic 	  p->value = 0;
99943205Sbostic 	}
100043205Sbostic       else if (rs == NORMAL && rv == 1)
100143205Sbostic 	p->status = ls;
100243205Sbostic       else if (rs == NORMAL && rv == -1)
100343205Sbostic 	if (ls == MAXPLUS1)
100443205Sbostic 	  p->status = MINLESS1;
100543205Sbostic 	else
100643205Sbostic 	  p->status = MAXPLUS1;
100743205Sbostic       else
100843205Sbostic 	{
100943205Sbostic 	  err(overflow);
101043205Sbostic 	  p->status = ERRVAL;
101143205Sbostic 	}
101243205Sbostic     }
101343205Sbostic 
101443205Sbostic   return ((vexpr *) p);
101543205Sbostic }
101643205Sbostic 
101743205Sbostic 
101843205Sbostic 
101943205Sbostic vexpr *divivals(l, r)
102043205Sbostic vexpr *l;
102143205Sbostic vexpr *r;
102243205Sbostic {
102343205Sbostic   static char *badtag = "bad tag in divivals";
102443205Sbostic   static char *zerodivide = "division by zero";
102543205Sbostic 
102643205Sbostic   register int ls, rs;
102743205Sbostic   register ftnint lv, rv;
102843205Sbostic   register dvalue *p;
102943205Sbostic   register ftnint k;
103043205Sbostic   register int sign;
103143205Sbostic 
103243205Sbostic   if (l->tag != DVALUE && r->tag != DVALUE)
103343205Sbostic     fatal(badtag);
103443205Sbostic 
103543205Sbostic   ls = l->dvalue.status;
103643205Sbostic   lv = l->dvalue.value;
103743205Sbostic   rs = r->dvalue.status;
103843205Sbostic   rv = r->dvalue.value;
103943205Sbostic 
104043205Sbostic   p = ALLOC(Dvalue);
104143205Sbostic   p->tag = DVALUE;
104243205Sbostic 
104343205Sbostic   if (ls == ERRVAL || rs == ERRVAL)
104443205Sbostic     p->status = ERRVAL;
104543205Sbostic   else if (rs == NORMAL)
104643205Sbostic     {
104743205Sbostic       if (rv == 0)
104843205Sbostic 	{
104943205Sbostic 	  err(zerodivide);
105043205Sbostic 	  p->status = ERRVAL;
105143205Sbostic 	}
105243205Sbostic       else if (ls == NORMAL)
105343205Sbostic 	{
105443205Sbostic 	  p->status = NORMAL;
105543205Sbostic 	  p->value = lv / rv;
105643205Sbostic 	}
105743205Sbostic       else if (rv == 1)
105843205Sbostic 	p->status = ls;
105943205Sbostic       else if (rv == -1)
106043205Sbostic 	if (ls == MAXPLUS1)
106143205Sbostic 	  p->status = MINLESS1;
106243205Sbostic 	else
106343205Sbostic 	  p->status = MAXPLUS1;
106443205Sbostic       else
106543205Sbostic 	{
106643205Sbostic 	  p->status = NORMAL;
106743205Sbostic 
106843205Sbostic 	  if (ls == MAXPLUS1)
106943205Sbostic 	    sign = 1;
107043205Sbostic 	  else
107143205Sbostic 	    sign = -1;
107243205Sbostic 
107343205Sbostic 	  if (rv < 0)
107443205Sbostic 	    {
107543205Sbostic 	      rv = -rv;
107643205Sbostic 	      sign = -sign;
107743205Sbostic 	    }
107843205Sbostic 
107943205Sbostic 	  k = MAXINT - rv;
108043205Sbostic 	  p->value = sign * ((k + 1)/rv + 1);
108143205Sbostic 	}
108243205Sbostic     }
108343205Sbostic   else
108443205Sbostic     {
108543205Sbostic       p->status = NORMAL;
108643205Sbostic       if (ls == NORMAL)
108743205Sbostic 	p->value = 0;
108843205Sbostic       else if ((ls == MAXPLUS1 && rs == MAXPLUS1)
108943205Sbostic 		|| (ls == MINLESS1 && rs == MINLESS1))
109043205Sbostic 	p->value = 1;
109143205Sbostic       else
109243205Sbostic 	p->value = -1;
109343205Sbostic     }
109443205Sbostic 
109543205Sbostic   return ((vexpr *) p);
109643205Sbostic }
109743205Sbostic 
109843205Sbostic 
109943205Sbostic 
110043205Sbostic vexpr *powivals(l, r)
110143205Sbostic vexpr *l;
110243205Sbostic vexpr *r;
110343205Sbostic {
110443205Sbostic   static char *badtag = "bad tag in powivals";
110543205Sbostic   static char *zerozero = "zero raised to the zero-th power";
110643205Sbostic   static char *zeroneg = "zero raised to a negative power";
110743205Sbostic   static char *overflow = "integer value too large";
110843205Sbostic 
110943205Sbostic   register int ls, rs;
111043205Sbostic   register ftnint lv, rv;
111143205Sbostic   register dvalue *p;
111243205Sbostic 
111343205Sbostic   if (l->tag != DVALUE || r->tag != DVALUE)
111443205Sbostic     fatal(badtag);
111543205Sbostic 
111643205Sbostic   ls = l->dvalue.status;
111743205Sbostic   lv = l->dvalue.value;
111843205Sbostic   rs = r->dvalue.status;
111943205Sbostic   rv = r->dvalue.value;
112043205Sbostic 
112143205Sbostic   p = ALLOC(Dvalue);
112243205Sbostic   p->tag = DVALUE;
112343205Sbostic 
112443205Sbostic   if (ls == ERRVAL || rs == ERRVAL)
112543205Sbostic     p->status = ERRVAL;
112643205Sbostic 
112743205Sbostic   else if (ls == NORMAL)
112843205Sbostic     {
112943205Sbostic       if (lv == 1)
113043205Sbostic 	{
113143205Sbostic 	  p->status = NORMAL;
113243205Sbostic 	  p->value = 1;
113343205Sbostic 	}
113443205Sbostic       else if (lv == 0)
113543205Sbostic 	{
113643205Sbostic 	  if (rs == MAXPLUS1 || (rs == NORMAL && rv > 0))
113743205Sbostic 	    {
113843205Sbostic 	      p->status = NORMAL;
113943205Sbostic 	      p->value = 0;
114043205Sbostic 	    }
114143205Sbostic 	  else if (rs == NORMAL && rv == 0)
114243205Sbostic 	    {
114343205Sbostic 	      warn(zerozero);
114443205Sbostic 	      p->status = NORMAL;
114543205Sbostic 	      p->value = 1;
114643205Sbostic 	    }
114743205Sbostic 	  else
114843205Sbostic 	    {
114943205Sbostic 	      err(zeroneg);
115043205Sbostic 	      p->status = ERRVAL;
115143205Sbostic 	    }
115243205Sbostic 	}
115343205Sbostic       else if (lv == -1)
115443205Sbostic 	{
115543205Sbostic 	  p->status = NORMAL;
115643205Sbostic 	  if (rs == NORMAL)
115743205Sbostic 	    {
115843205Sbostic 	      if (rv < 0) rv = -rv;
115943205Sbostic 	      if (rv % 2 == 0)
116043205Sbostic 		p->value = 1;
116143205Sbostic 	      else
116243205Sbostic 		p->value = -1;
116343205Sbostic 	    }
116443205Sbostic 	  else
116543205Sbostic #	    if (MAXINT % 2 == 1)
116643205Sbostic 	      p->value = 1;
116743205Sbostic #	    else
116843205Sbostic 	      p->value = -1;
116943205Sbostic #	    endif
117043205Sbostic 	}
117143205Sbostic       else
117243205Sbostic 	{
117343205Sbostic 	  if (rs == NORMAL && rv > 0)
117443205Sbostic 	    {
117543205Sbostic 	      rstatus = NORMAL;
117643205Sbostic 	      rvalue = lv;
117743205Sbostic 	      while (--rv && rstatus == NORMAL)
117843205Sbostic 		mulints(rvalue, lv);
117943205Sbostic 	      if (rv == 0 && rstatus != ERRVAL)
118043205Sbostic 		{
118143205Sbostic 		  p->status = rstatus;
118243205Sbostic 		  p->value = rvalue;
118343205Sbostic 		}
118443205Sbostic 	      else
118543205Sbostic 		{
118643205Sbostic 		  err(overflow);
118743205Sbostic 		  p->status = ERRVAL;
118843205Sbostic 		}
118943205Sbostic 	    }
119043205Sbostic 	  else if (rs == MAXPLUS1)
119143205Sbostic 	    {
119243205Sbostic 	      err(overflow);
119343205Sbostic 	      p->status = ERRVAL;
119443205Sbostic 	    }
119543205Sbostic 	  else if (rs == NORMAL && rv == 0)
119643205Sbostic 	    {
119743205Sbostic 	      p->status = NORMAL;
119843205Sbostic 	      p->value = 1;
119943205Sbostic 	    }
120043205Sbostic 	  else
120143205Sbostic 	    {
120243205Sbostic 	      p->status = NORMAL;
120343205Sbostic 	      p->value = 0;
120443205Sbostic 	    }
120543205Sbostic 	}
120643205Sbostic     }
120743205Sbostic 
120843205Sbostic   else
120943205Sbostic     {
121043205Sbostic       if (rs == MAXPLUS1 || (rs == NORMAL && rv > 1))
121143205Sbostic 	{
121243205Sbostic 	  err(overflow);
121343205Sbostic 	  p->status = ERRVAL;
121443205Sbostic 	}
121543205Sbostic       else if (rs == NORMAL && rv == 1)
121643205Sbostic 	p->status = ls;
121743205Sbostic       else if (rs == NORMAL && rv == 0)
121843205Sbostic 	{
121943205Sbostic 	  p->status = NORMAL;
122043205Sbostic 	  p->value = 1;
122143205Sbostic 	}
122243205Sbostic       else
122343205Sbostic 	{
122443205Sbostic 	  p->status = NORMAL;
122543205Sbostic 	  p->value = 0;
122643205Sbostic 	}
122743205Sbostic     }
122843205Sbostic 
122943205Sbostic   return ((vexpr *) p);
123043205Sbostic }
123143205Sbostic 
123243205Sbostic 
123343205Sbostic 
123443205Sbostic /*  Addints adds two integer values.  */
123543205Sbostic 
123643205Sbostic addints(i, j)
123743205Sbostic register ftnint i, j;
123843205Sbostic {
123943205Sbostic   register ftnint margin;
124043205Sbostic 
124143205Sbostic   if (i == 0)
124243205Sbostic     {
124343205Sbostic       rstatus = NORMAL;
124443205Sbostic       rvalue = j;
124543205Sbostic     }
124643205Sbostic   else if (i > 0)
124743205Sbostic     {
124843205Sbostic       margin = MAXINT - i;
124943205Sbostic       if (j <= margin)
125043205Sbostic 	{
125143205Sbostic 	  rstatus = NORMAL;
125243205Sbostic 	  rvalue = i + j;
125343205Sbostic 	}
125443205Sbostic       else if (j == margin + 1)
125543205Sbostic 	rstatus = MAXPLUS1;
125643205Sbostic       else
125743205Sbostic 	rstatus = ERRVAL;
125843205Sbostic     }
125943205Sbostic   else
126043205Sbostic     {
126143205Sbostic       margin = ( -MAXINT ) - i;
126243205Sbostic       if (j >= margin)
126343205Sbostic 	{
126443205Sbostic 	  rstatus = NORMAL;
126543205Sbostic 	  rvalue = i + j;
126643205Sbostic 	}
126743205Sbostic       else if (j == margin - 1)
126843205Sbostic 	rstatus = MINLESS1;
126943205Sbostic       else
127043205Sbostic 	rstatus = ERRVAL;
127143205Sbostic     }
127243205Sbostic 
127343205Sbostic    return;
127443205Sbostic }
127543205Sbostic 
127643205Sbostic 
127743205Sbostic 
127843205Sbostic /*  Mulints multiplies two integer values  */
127943205Sbostic 
128043205Sbostic mulints(i, j)
128143205Sbostic register ftnint i, j;
128243205Sbostic {
128343205Sbostic   register ftnint sign;
128443205Sbostic   register ftnint margin;
128543205Sbostic 
128643205Sbostic   if (i == 0 || j == 0)
128743205Sbostic     {
128843205Sbostic       rstatus = NORMAL;
128943205Sbostic       rvalue = 0;
129043205Sbostic     }
129143205Sbostic   else
129243205Sbostic     {
129343205Sbostic       if ((i > 0 && j > 0) || (i < 0 && j < 0))
129443205Sbostic 	sign = 1;
129543205Sbostic       else
129643205Sbostic 	sign = -1;
129743205Sbostic 
129843205Sbostic       if (i < 0) i = -i;
129943205Sbostic       if (j < 0) j = -j;
130043205Sbostic 
130143205Sbostic       margin = MAXINT - i;
130243205Sbostic       margin = (margin + 1) / i;
130343205Sbostic 
130443205Sbostic       if (j <= margin)
130543205Sbostic 	{
130643205Sbostic 	  rstatus = NORMAL;
130743205Sbostic 	  rvalue = i * j * sign;
130843205Sbostic 	}
130943205Sbostic       else if (j - 1 == margin)
131043205Sbostic 	{
131143205Sbostic 	  margin = i*margin - 1;
131243205Sbostic 	  if (margin == MAXINT - i)
131343205Sbostic 	    if (sign > 0)
131443205Sbostic 	      rstatus = MAXPLUS1;
131543205Sbostic 	    else
131643205Sbostic 	      rstatus = MINLESS1;
131743205Sbostic 	  else
131843205Sbostic 	    {
131943205Sbostic 	      rstatus = NORMAL;
132043205Sbostic 	      rvalue = i * j * sign;
132143205Sbostic 	    }
132243205Sbostic 	}
132343205Sbostic       else
132443205Sbostic 	rstatus = ERRVAL;
132543205Sbostic     }
132643205Sbostic 
132743205Sbostic   return;
132843205Sbostic }
132943205Sbostic 
133043205Sbostic 
133143205Sbostic 
133243205Sbostic vexpr *
133343205Sbostic evalvexpr(ep)
133443205Sbostic vexpr *ep;
133543205Sbostic {
133643205Sbostic   register vexpr *p;
133743205Sbostic   register vexpr *l, *r;
133843205Sbostic 
133943205Sbostic   switch (ep->tag)
134043205Sbostic     {
134143205Sbostic     case DVALUE:
134243205Sbostic       p = cpdvalue(ep);
134343205Sbostic       break;
134443205Sbostic 
134543205Sbostic     case DVAR:
134643205Sbostic       p = cpdvalue((vexpr *) ep->dvar.valp);
134743205Sbostic       break;
134843205Sbostic 
134943205Sbostic     case DNAME:
135043205Sbostic       p = evaldname(ep);
135143205Sbostic       break;
135243205Sbostic 
135343205Sbostic     case DEXPR:
135443205Sbostic       if (ep->dexpr.left == NULL)
135543205Sbostic 	l = NULL;
135643205Sbostic       else
135743205Sbostic 	l = evalvexpr(ep->dexpr.left);
135843205Sbostic 
135943205Sbostic       if (ep->dexpr.right == NULL)
136043205Sbostic 	r = NULL;
136143205Sbostic       else
136243205Sbostic 	r = evalvexpr(ep->dexpr.right);
136343205Sbostic 
136443205Sbostic       switch (ep->dexpr.opcode)
136543205Sbostic 	{
136643205Sbostic 	case OPNEG:
136743205Sbostic 	  p = negival(r);
136843205Sbostic 	  break;
136943205Sbostic 
137043205Sbostic 	case OPPLUS:
137143205Sbostic 	  p = addivals(l, r);
137243205Sbostic 	  break;
137343205Sbostic 
137443205Sbostic 	case OPMINUS:
137543205Sbostic 	  p = subivals(l, r);
137643205Sbostic 	  break;
137743205Sbostic 
137843205Sbostic 	case OPSTAR:
137943205Sbostic 	  p = mulivals(l, r);
138043205Sbostic 	  break;
138143205Sbostic 
138243205Sbostic 	case OPSLASH:
138343205Sbostic 	  p = divivals(l, r);
138443205Sbostic 	  break;
138543205Sbostic 
138643205Sbostic 	case OPPOWER:
138743205Sbostic 	  p = powivals(l, r);
138843205Sbostic 	  break;
138943205Sbostic 	}
139043205Sbostic 
139143205Sbostic       frvexpr(l);
139243205Sbostic       frvexpr(r);
139343205Sbostic       break;
139443205Sbostic 
139543205Sbostic     case DERROR:
139643205Sbostic       p = (vexpr *) ALLOC(Dvalue);
139743205Sbostic       p->tag = DVALUE;
139843205Sbostic       p->dvalue.status = ERRVAL;
139943205Sbostic       break;
140043205Sbostic     }
140143205Sbostic 
140243205Sbostic   return (p);
140343205Sbostic }
140443205Sbostic 
140543205Sbostic 
140643205Sbostic 
140743205Sbostic vexpr *
140843205Sbostic refrigdname(vp)
140943205Sbostic vexpr *vp;
141043205Sbostic {
141143205Sbostic   register vexpr *p;
141243205Sbostic   register int len;
141343205Sbostic   register char *repr;
141443205Sbostic   register int found;
141543205Sbostic   register dovars *dvp;
141643205Sbostic 
141743205Sbostic   len = vp->dname.len;
141843205Sbostic   repr = vp->dname.repr;
141943205Sbostic 
142043205Sbostic   found = NO;
142143205Sbostic   dvp = dvlist;
142243205Sbostic   while (found == NO && dvp != NULL)
142343205Sbostic     {
142443205Sbostic       if (len == dvp->len && eqn(len, repr, dvp->repr))
142543205Sbostic 	found = YES;
142643205Sbostic       else
142743205Sbostic 	dvp = dvp->next;
142843205Sbostic     }
142943205Sbostic 
143043205Sbostic   if (found == YES)
143143205Sbostic     {
143243205Sbostic       p = (vexpr *) ALLOC(Dvar);
143343205Sbostic       p->tag = DVAR;
143443205Sbostic       p->dvar.valp = dvp->valp;
143543205Sbostic     }
143643205Sbostic   else
143743205Sbostic     {
143843205Sbostic       p = evaldname(vp);
143943205Sbostic       if (p->dvalue.status == ERRVAL)
144043205Sbostic 	dataerror = YES;
144143205Sbostic     }
144243205Sbostic 
144343205Sbostic   return (p);
144443205Sbostic }
144543205Sbostic 
144643205Sbostic 
144743205Sbostic 
144843205Sbostic refrigvexpr(vpp)
144943205Sbostic vexpr **vpp;
145043205Sbostic {
145143205Sbostic   register vexpr *vp;
145243205Sbostic 
145343205Sbostic   vp = *vpp;
145443205Sbostic 
145543205Sbostic   switch (vp->tag)
145643205Sbostic     {
145743205Sbostic     case DVALUE:
145843205Sbostic     case DVAR:
145943205Sbostic     case DERROR:
146043205Sbostic       break;
146143205Sbostic 
146243205Sbostic     case DEXPR:
146343205Sbostic       refrigvexpr( &(vp->dexpr.left) );
146443205Sbostic       refrigvexpr( &(vp->dexpr.right) );
146543205Sbostic       break;
146643205Sbostic 
146743205Sbostic     case DNAME:
146843205Sbostic       *(vpp) = refrigdname(vp);
146943205Sbostic       frvexpr(vp);
147043205Sbostic       break;
147143205Sbostic     }
147243205Sbostic 
147343205Sbostic   return;
147443205Sbostic }
147543205Sbostic 
147643205Sbostic 
147743205Sbostic 
147843205Sbostic int
147943205Sbostic chkvar(np, sname)
148043205Sbostic Namep np;
148143205Sbostic char *sname;
148243205Sbostic {
148343205Sbostic   static char *nonvar = "%s is not a variable";
148443205Sbostic   static char *arginit = "attempt to initialize a dummy argument: %s";
148543205Sbostic   static char *autoinit = "attempt to initialize an automatic variable: %s";
148643205Sbostic   static char *badclass = "bad class in chkvar";
148743205Sbostic 
148843205Sbostic   register int status;
148943205Sbostic   register struct Dimblock *dp;
149043205Sbostic   register int i;
149143205Sbostic 
149243205Sbostic   status = YES;
149343205Sbostic 
149443205Sbostic   if (np->vclass == CLUNKNOWN
149543205Sbostic       || (np->vclass == CLVAR && !np->vdcldone))
149643205Sbostic     vardcl(np);
149743205Sbostic 
149843205Sbostic   if (np->vstg == STGARG)
149943205Sbostic     {
150043205Sbostic       errstr(arginit, sname);
150143205Sbostic       dataerror = YES;
150243205Sbostic       status = NO;
150343205Sbostic     }
150443205Sbostic   else if (np->vclass != CLVAR)
150543205Sbostic     {
150643205Sbostic       errstr(nonvar, sname);
150743205Sbostic       dataerror = YES;
150843205Sbostic       status = NO;
150943205Sbostic     }
151043205Sbostic   else if (np->vstg == STGAUTO)
151143205Sbostic     {
151243205Sbostic       errstr(autoinit, sname);
151343205Sbostic       dataerror = YES;
151443205Sbostic       status = NO;
151543205Sbostic     }
151643205Sbostic   else if (np->vstg != STGBSS && np->vstg != STGINIT
151743205Sbostic 	    && np->vstg != STGCOMMON && np->vstg != STGEQUIV)
151843205Sbostic     {
151943205Sbostic       fatal(badclass);
152043205Sbostic     }
152143205Sbostic   else
152243205Sbostic     {
152343205Sbostic       switch (np->vtype)
152443205Sbostic 	{
152543205Sbostic 	case TYERROR:
152643205Sbostic 	  status = NO;
152743205Sbostic 	  dataerror = YES;
152843205Sbostic 	  break;
152943205Sbostic 
153043205Sbostic 	case TYSHORT:
153143205Sbostic 	case TYLONG:
153243205Sbostic 	case TYREAL:
153343205Sbostic 	case TYDREAL:
153443205Sbostic 	case TYCOMPLEX:
153543205Sbostic 	case TYDCOMPLEX:
153643205Sbostic 	case TYLOGICAL:
153743205Sbostic 	case TYCHAR:
153843205Sbostic 	  dp = np->vdim;
153943205Sbostic 	  if (dp != NULL)
154043205Sbostic 	    {
154143205Sbostic 	      if (dp->nelt == NULL || !ISICON(dp->nelt))
154243205Sbostic 	        {
154343205Sbostic 	          status = NO;
154443205Sbostic 	          dataerror = YES;
154543205Sbostic 	        }
154643205Sbostic 	    }
154743205Sbostic 	  break;
154843205Sbostic 
154943205Sbostic 	default:
155043205Sbostic 	  badtype("chkvar", np->vtype);
155143205Sbostic 	}
155243205Sbostic     }
155343205Sbostic 
155443205Sbostic   return (status);
155543205Sbostic }
155643205Sbostic 
155743205Sbostic 
155843205Sbostic 
155943205Sbostic refrigsubs(ap, sname)
156043205Sbostic aelt *ap;
156143205Sbostic char *sname;
156243205Sbostic {
156343205Sbostic   static char *nonarray = "subscripts on a simple variable:  %s";
156443205Sbostic   static char *toofew = "not enough subscripts on %s";
156543205Sbostic   static char *toomany = "too many subscripts on %s";
156643205Sbostic 
156743205Sbostic   register vlist *subp;
156843205Sbostic   register int nsubs;
156943205Sbostic   register Namep np;
157043205Sbostic   register struct Dimblock *dp;
157143205Sbostic   register int i;
157243205Sbostic 
157343205Sbostic   np = ap->var;
157443205Sbostic   dp = np->vdim;
157543205Sbostic 
157643205Sbostic   if (ap->subs != NULL)
157743205Sbostic     {
157843205Sbostic       if (np->vdim == NULL)
157943205Sbostic 	{
158043205Sbostic 	  errstr(nonarray, sname);
158143205Sbostic 	  dataerror = YES;
158243205Sbostic 	}
158343205Sbostic       else
158443205Sbostic 	{
158543205Sbostic 	  nsubs = 0;
158643205Sbostic 	  subp = ap->subs;
158743205Sbostic 	  while (subp != NULL)
158843205Sbostic 	    {
158943205Sbostic 	      nsubs++;
159043205Sbostic 	      refrigvexpr( &(subp->val) );
159143205Sbostic 	      subp = subp->next;
159243205Sbostic 	    }
159343205Sbostic 
159443205Sbostic 	  if (dp->ndim != nsubs)
159543205Sbostic 	    {
159643205Sbostic 	      if (np->vdim->ndim > nsubs)
159743205Sbostic 		errstr(toofew, sname);
159843205Sbostic 	      else
159943205Sbostic 		errstr(toomany, sname);
160043205Sbostic 	      dataerror = YES;
160143205Sbostic 	    }
160243205Sbostic 	  else if (dp->baseoffset == NULL || !ISICON(dp->baseoffset))
160343205Sbostic 	    dataerror = YES;
160443205Sbostic 	  else
160543205Sbostic 	    {
160643205Sbostic 	      i = dp->ndim;
160743205Sbostic 	      while (i-- > 0)
160843205Sbostic 		{
160943205Sbostic 		  if (dp->dims[i].dimsize == NULL
161043205Sbostic 		      || !ISICON(dp->dims[i].dimsize))
161143205Sbostic 		    dataerror = YES;
161243205Sbostic 		}
161343205Sbostic 	    }
161443205Sbostic 	}
161543205Sbostic     }
161643205Sbostic 
161743205Sbostic   return;
161843205Sbostic }
161943205Sbostic 
162043205Sbostic 
162143205Sbostic 
162243205Sbostic refrigrange(ap, sname)
162343205Sbostic aelt *ap;
162443205Sbostic char *sname;
162543205Sbostic {
162643205Sbostic   static char *nonstr = "substring of a noncharacter variable:  %s";
162743205Sbostic   static char *array = "substring applied to an array:  %s";
162843205Sbostic 
162943205Sbostic   register Namep np;
163043205Sbostic   register dvalue *t;
163143205Sbostic   register rpair *rp;
163243205Sbostic 
163343205Sbostic   if (ap->range != NULL)
163443205Sbostic     {
163543205Sbostic       np = ap->var;
163643205Sbostic       if (np->vtype != TYCHAR)
163743205Sbostic 	{
163843205Sbostic 	  errstr(nonstr, sname);
163943205Sbostic 	  dataerror = YES;
164043205Sbostic 	}
164143205Sbostic       else if (ap->subs == NULL && np->vdim != NULL)
164243205Sbostic 	{
164343205Sbostic 	  errstr(array, sname);
164443205Sbostic 	  dataerror = YES;
164543205Sbostic 	}
164643205Sbostic       else
164743205Sbostic 	{
164843205Sbostic 	  rp = ap->range;
164943205Sbostic 
165043205Sbostic 	  if (rp->low != NULL)
165143205Sbostic 	    refrigvexpr( &(rp->low) );
165243205Sbostic 	  else
165343205Sbostic 	    {
165443205Sbostic 	      t = ALLOC(Dvalue);
165543205Sbostic 	      t->tag = DVALUE;
165643205Sbostic 	      t->status = NORMAL;
165743205Sbostic 	      t->value = 1;
165843205Sbostic 	      rp->low = (vexpr *) t;
165943205Sbostic 	    }
166043205Sbostic 
166143205Sbostic 	  if (rp->high != NULL)
166243205Sbostic 	    refrigvexpr( &(rp->high) );
166343205Sbostic 	  else
166443205Sbostic 	    {
166543205Sbostic 	      if (!ISICON(np->vleng))
166643205Sbostic 		{
166743205Sbostic 		  rp->high = (vexpr *) ALLOC(Derror);
166843205Sbostic 		  rp->high->tag = DERROR;
166943205Sbostic 		}
167043205Sbostic 	      else
167143205Sbostic 		{
167243205Sbostic 		  t = ALLOC(Dvalue);
167343205Sbostic 		  t->tag = DVALUE;
167443205Sbostic 		  t->status = NORMAL;
1675*46302Sbostic 		  t->value = np->vleng->constblock.constant.ci;
167643205Sbostic 		  rp->high = (vexpr *) t;
167743205Sbostic 		}
167843205Sbostic 	    }
167943205Sbostic 	}
168043205Sbostic     }
168143205Sbostic 
168243205Sbostic   return;
168343205Sbostic }
168443205Sbostic 
168543205Sbostic 
168643205Sbostic 
168743205Sbostic refrigaelt(ap)
168843205Sbostic aelt *ap;
168943205Sbostic {
169043205Sbostic   register Namep np;
169143205Sbostic   register char *bp, *sp;
169243205Sbostic   register int len;
169343205Sbostic   char buff[VL+1];
169443205Sbostic 
169543205Sbostic   np = ap->var;
169643205Sbostic 
169743205Sbostic   len = 0;
169843205Sbostic   bp = buff;
169943205Sbostic   sp = np->varname;
170043205Sbostic   while (len < VL && *sp != ' ' && *sp != '\0')
170143205Sbostic     {
170243205Sbostic       *bp++ = *sp++;
170343205Sbostic       len++;
170443205Sbostic     }
170543205Sbostic   *bp = '\0';
170643205Sbostic 
170743205Sbostic   if (chkvar(np, buff))
170843205Sbostic     {
170943205Sbostic       refrigsubs(ap, buff);
171043205Sbostic       refrigrange(ap, buff);
171143205Sbostic     }
171243205Sbostic 
171343205Sbostic   return;
171443205Sbostic }
171543205Sbostic 
171643205Sbostic 
171743205Sbostic 
171843205Sbostic refrigdo(dp)
171943205Sbostic dolist *dp;
172043205Sbostic {
172143205Sbostic   static char *duplicates = "implied DO variable %s redefined";
172243205Sbostic   static char *nonvar = "%s is not a variable";
172343205Sbostic   static char *nonint = "%s is not integer";
172443205Sbostic 
172543205Sbostic   register int len;
172643205Sbostic   register char *repr;
172743205Sbostic   register int found;
172843205Sbostic   register dovars *dvp;
172943205Sbostic   register Namep np;
173043205Sbostic   register dovars *t;
173143205Sbostic 
173243205Sbostic   refrigvexpr( &(dp->init) );
173343205Sbostic   refrigvexpr( &(dp->limit) );
173443205Sbostic   refrigvexpr( &(dp->step) );
173543205Sbostic 
173643205Sbostic   len = dp->dovar->dname.len;
173743205Sbostic   repr = dp->dovar->dname.repr;
173843205Sbostic 
173943205Sbostic   found = NO;
174043205Sbostic   dvp = dvlist;
174143205Sbostic   while (found == NO && dvp != NULL)
174243205Sbostic     if (len == dvp->len && eqn(len, repr, dvp->repr))
174343205Sbostic       found = YES;
174443205Sbostic     else
174543205Sbostic       dvp = dvp->next;
174643205Sbostic 
174743205Sbostic   if (found == YES)
174843205Sbostic     {
174943205Sbostic       errnm(duplicates, len, repr);
175043205Sbostic       dataerror = YES;
175143205Sbostic     }
175243205Sbostic   else
175343205Sbostic     {
175443205Sbostic       np = getname(len, repr);
175543205Sbostic       if (np == NULL)
175643205Sbostic 	{
175743205Sbostic 	  if (!ISINT(impltype[letter(*repr)]))
175843205Sbostic 	    warnnm(nonint, len, repr);
175943205Sbostic 	}
176043205Sbostic       else
176143205Sbostic 	{
176243205Sbostic 	  if (np->vclass == CLUNKNOWN)
176343205Sbostic 	    vardcl(np);
176443205Sbostic 	  if (np->vclass != CLVAR)
176543205Sbostic 	    warnnm(nonvar, len, repr);
176643205Sbostic 	  else if (!ISINT(np->vtype))
176743205Sbostic 	    warnnm(nonint, len, repr);
176843205Sbostic 	}
176943205Sbostic     }
177043205Sbostic 
177143205Sbostic   t = ALLOC(DoVars);
177243205Sbostic   t->next = dvlist;
177343205Sbostic   t->len = len;
177443205Sbostic   t->repr = repr;
177543205Sbostic   t->valp = ALLOC(Dvalue);
177643205Sbostic   t->valp->tag = DVALUE;
177743205Sbostic   dp->dovar = (vexpr *) t->valp;
177843205Sbostic 
177943205Sbostic   dvlist = t;
178043205Sbostic 
178143205Sbostic   refriglvals(dp->elts);
178243205Sbostic 
178343205Sbostic   dvlist = t->next;
178443205Sbostic   free((char *) t);
178543205Sbostic 
178643205Sbostic   return;
178743205Sbostic }
178843205Sbostic 
178943205Sbostic 
179043205Sbostic 
179143205Sbostic refriglvals(lvals)
179243205Sbostic elist *lvals;
179343205Sbostic {
179443205Sbostic   register elist *top;
179543205Sbostic 
179643205Sbostic   top = lvals;
179743205Sbostic 
179843205Sbostic   while (top != NULL)
179943205Sbostic     {
180043205Sbostic       if (top->elt->tag == SIMPLE)
180143205Sbostic 	refrigaelt((aelt *) top->elt);
180243205Sbostic       else
180343205Sbostic 	refrigdo((dolist *) top->elt);
180443205Sbostic 
180543205Sbostic       top = top->next;
180643205Sbostic     }
180743205Sbostic 
180843205Sbostic   return;
180943205Sbostic }
181043205Sbostic 
181143205Sbostic 
181243205Sbostic 
181343205Sbostic /*  Refrig freezes name/value bindings in the DATA name list  */
181443205Sbostic 
181543205Sbostic 
181643205Sbostic refrig(lvals)
181743205Sbostic elist *lvals;
181843205Sbostic {
181943205Sbostic   dvlist = NULL;
182043205Sbostic   refriglvals(lvals);
182143205Sbostic   return;
182243205Sbostic }
182343205Sbostic 
182443205Sbostic 
182543205Sbostic 
182643205Sbostic ftnint
182743205Sbostic indexer(ap)
182843205Sbostic aelt *ap;
182943205Sbostic {
183043205Sbostic   static char *badvar = "bad variable in indexer";
183143205Sbostic   static char *boundserror = "subscript out of bounds";
183243205Sbostic 
183343205Sbostic   register ftnint index;
183443205Sbostic   register vlist *sp;
183543205Sbostic   register Namep np;
183643205Sbostic   register struct Dimblock *dp;
183743205Sbostic   register int i;
183843205Sbostic   register dvalue *vp;
183943205Sbostic   register ftnint size;
184043205Sbostic   ftnint sub[MAXDIM];
184143205Sbostic 
184243205Sbostic   sp = ap->subs;
184343205Sbostic   if (sp == NULL) return (0);
184443205Sbostic 
184543205Sbostic   np = ap->var;
184643205Sbostic   dp = np->vdim;
184743205Sbostic 
184843205Sbostic   if (dp == NULL)
184943205Sbostic     fatal(badvar);
185043205Sbostic 
185143205Sbostic   i = 0;
185243205Sbostic   while (sp != NULL)
185343205Sbostic     {
185443205Sbostic       vp = (dvalue *) evalvexpr(sp->val);
185543205Sbostic 
185643205Sbostic       if (vp->status == NORMAL)
185743205Sbostic 	sub[i++] = vp->value;
185843205Sbostic       else if ((MININT + MAXINT == -1) && vp->status == MINLESS1)
185943205Sbostic 	sub[i++] = MININT;
186043205Sbostic       else
186143205Sbostic 	{
186243205Sbostic 	  frvexpr((vexpr *) vp);
186343205Sbostic 	  return (-1);
186443205Sbostic 	}
186543205Sbostic 
186643205Sbostic       frvexpr((vexpr *) vp);
186743205Sbostic       sp = sp->next;
186843205Sbostic     }
186943205Sbostic 
187043205Sbostic   index = sub[--i];
187143205Sbostic   while (i-- > 0)
187243205Sbostic     {
1873*46302Sbostic       size = dp->dims[i].dimsize->constblock.constant.ci;
187443205Sbostic       index = sub[i] + index * size;
187543205Sbostic     }
187643205Sbostic 
1877*46302Sbostic   index -= dp->baseoffset->constblock.constant.ci;
187843205Sbostic 
1879*46302Sbostic   if (index < 0 || index >= dp->nelt->constblock.constant.ci)
188043205Sbostic     {
188143205Sbostic       err(boundserror);
188243205Sbostic       return (-1);
188343205Sbostic     }
188443205Sbostic 
188543205Sbostic   return (index);
188643205Sbostic }
188743205Sbostic 
188843205Sbostic 
188943205Sbostic 
189043205Sbostic savedata(lvals, rvals)
189143205Sbostic elist *lvals;
189243205Sbostic vallist *rvals;
189343205Sbostic {
189443205Sbostic   static char *toomany = "more data values than data items";
189543205Sbostic 
189643205Sbostic   register elist *top;
189743205Sbostic 
189843205Sbostic   dataerror = NO;
189943205Sbostic   badvalue = NO;
190043205Sbostic 
190143205Sbostic   lvals = revelist(lvals);
190243205Sbostic   grvals = revrvals(rvals);
190343205Sbostic 
190443205Sbostic   refrig(lvals);
190543205Sbostic 
190643205Sbostic   if (!dataerror)
190743205Sbostic     outdata(lvals);
190843205Sbostic 
190943205Sbostic   frelist(lvals);
191043205Sbostic 
191143205Sbostic   while (grvals != NULL && dataerror == NO)
191243205Sbostic     {
191343205Sbostic       if (grvals->status != NORMAL)
191443205Sbostic 	dataerror = YES;
191543205Sbostic       else if (grvals->repl <= 0)
191643205Sbostic         grvals = grvals->next;
191743205Sbostic       else
191843205Sbostic 	{
191943205Sbostic 	  err(toomany);
192043205Sbostic 	  dataerror = YES;
192143205Sbostic 	}
192243205Sbostic     }
192343205Sbostic 
192443205Sbostic   frvallist(grvals);
192543205Sbostic 
192643205Sbostic   return;
192743205Sbostic }
192843205Sbostic 
192943205Sbostic 
193043205Sbostic 
193143205Sbostic setdfiles(np)
193243205Sbostic register Namep np;
193343205Sbostic {
193443205Sbostic   register struct Extsym *cp;
193543205Sbostic   register struct Equivblock *ep;
193643205Sbostic   register int stg;
193743205Sbostic   register int type;
193843205Sbostic   register ftnint typelen;
193943205Sbostic   register ftnint nelt;
194043205Sbostic   register ftnint varsize;
194143205Sbostic 
194243205Sbostic   stg = np->vstg;
194343205Sbostic 
194443205Sbostic   if (stg == STGBSS || stg == STGINIT)
194543205Sbostic     {
194643205Sbostic       datafile = vdatafile;
194743205Sbostic       chkfile = vchkfile;
194843205Sbostic       if (np->init == YES)
194943205Sbostic 	base = np->initoffset;
195043205Sbostic       else
195143205Sbostic 	{
195243205Sbostic 	  np->init = YES;
195343205Sbostic 	  np->initoffset = base = vdatahwm;
195443205Sbostic 	  if (np->vdim != NULL)
1955*46302Sbostic 	    nelt = np->vdim->nelt->constblock.constant.ci;
195643205Sbostic 	  else
195743205Sbostic 	    nelt = 1;
195843205Sbostic 	  type = np->vtype;
195943205Sbostic 	  if (type == TYCHAR)
1960*46302Sbostic 	    typelen = np->vleng->constblock.constant.ci;
196143205Sbostic 	  else if (type == TYLOGICAL)
196243205Sbostic 	    typelen = typesize[tylogical];
196343205Sbostic 	  else
196443205Sbostic 	    typelen = typesize[type];
196543205Sbostic 	  varsize = nelt * typelen;
196643205Sbostic 	  vdatahwm += varsize;
196743205Sbostic 	}
196843205Sbostic     }
196943205Sbostic   else if (stg == STGEQUIV)
197043205Sbostic     {
197143205Sbostic       datafile = vdatafile;
197243205Sbostic       chkfile = vchkfile;
197343205Sbostic       ep = &eqvclass[np->vardesc.varno];
197443205Sbostic       if (ep->init == YES)
197543205Sbostic 	base = ep->initoffset;
197643205Sbostic       else
197743205Sbostic 	{
197843205Sbostic 	  ep->init = YES;
197943205Sbostic 	  ep->initoffset = base = vdatahwm;
198043205Sbostic 	  vdatahwm += ep->eqvleng;
198143205Sbostic 	}
198243205Sbostic       base += np->voffset;
198343205Sbostic     }
198443205Sbostic   else if (stg == STGCOMMON)
198543205Sbostic     {
198643205Sbostic       datafile = cdatafile;
198743205Sbostic       chkfile = cchkfile;
198843205Sbostic       cp = &extsymtab[np->vardesc.varno];
198943205Sbostic       if (cp->init == YES)
199043205Sbostic 	base = cp->initoffset;
199143205Sbostic       else
199243205Sbostic 	{
199343205Sbostic 	  cp->init = YES;
199443205Sbostic 	  cp->initoffset = base = cdatahwm;
199543205Sbostic 	  cdatahwm += cp->maxleng;
199643205Sbostic 	}
199743205Sbostic       base += np->voffset;
199843205Sbostic     }
199943205Sbostic 
200043205Sbostic   return;
200143205Sbostic }
200243205Sbostic 
200343205Sbostic 
200443205Sbostic 
2005*46302Sbostic wrtdata(offset, repl, len, constant)
200643205Sbostic long offset;
200743205Sbostic ftnint repl;
200843205Sbostic ftnint len;
2009*46302Sbostic char *constant;
201043205Sbostic {
201143205Sbostic   static char *badoffset = "bad offset in wrtdata";
201243205Sbostic   static char *toomuch = "too much data";
201343205Sbostic   static char *readerror = "read error on tmp file";
201443205Sbostic   static char *writeerror = "write error on tmp file";
201543205Sbostic   static char *seekerror = "seek error on tmp file";
201643205Sbostic 
201743205Sbostic   register ftnint k;
201843205Sbostic   long lastbyte;
201943205Sbostic   int bitpos;
202043205Sbostic   long chkoff;
202143205Sbostic   long lastoff;
202243205Sbostic   long chklen;
202343205Sbostic   long pos;
202443205Sbostic   int n;
202543205Sbostic   ftnint nbytes;
202643205Sbostic   int mask;
202743205Sbostic   register int i;
202843205Sbostic   char overlap;
202943205Sbostic   char allzero;
203043205Sbostic   char buff[BUFSIZ];
203143205Sbostic 
203243205Sbostic   if (offset < 0)
203343205Sbostic     fatal(badoffset);
203443205Sbostic 
203543205Sbostic   overlap = NO;
203643205Sbostic 
203743205Sbostic   k = repl * len;
203843205Sbostic   lastbyte = offset + k - 1;
203943205Sbostic   if (lastbyte < 0)
204043205Sbostic     {
204143205Sbostic       err(toomuch);
204243205Sbostic       dataerror = YES;
204343205Sbostic       return;
204443205Sbostic     }
204543205Sbostic 
204643205Sbostic   bitpos = offset % BYTESIZE;
204743205Sbostic   chkoff = offset/BYTESIZE;
204843205Sbostic   lastoff = lastbyte/BYTESIZE;
204943205Sbostic   chklen = lastoff - chkoff + 1;
205043205Sbostic 
205143205Sbostic   pos = lseek(chkfile, chkoff, 0);
205243205Sbostic   if (pos == -1)
205343205Sbostic     {
205443205Sbostic       err(seekerror);
205543205Sbostic       done(1);
205643205Sbostic     }
205743205Sbostic 
205843205Sbostic   while (k > 0)
205943205Sbostic     {
206043205Sbostic       if (chklen <= BUFSIZ)
206143205Sbostic 	n = chklen;
206243205Sbostic       else
206343205Sbostic 	{
206443205Sbostic 	  n = BUFSIZ;
206543205Sbostic 	  chklen -= BUFSIZ;
206643205Sbostic 	}
206743205Sbostic 
206843205Sbostic       nbytes = read(chkfile, buff, n);
206943205Sbostic       if (nbytes < 0)
207043205Sbostic 	{
207143205Sbostic 	  err(readerror);
207243205Sbostic 	  done(1);
207343205Sbostic 	}
207443205Sbostic 
207543205Sbostic       if (nbytes == 0)
207643205Sbostic 	buff[0] = '\0';
207743205Sbostic 
207843205Sbostic       if (nbytes < n)
207943205Sbostic 	buff[ n-1 ] = '\0';
208043205Sbostic 
208143205Sbostic       i = 0;
208243205Sbostic 
208343205Sbostic       if (bitpos > 0)
208443205Sbostic 	{
208543205Sbostic 	  while (k > 0 && bitpos < BYTESIZE)
208643205Sbostic 	    {
208743205Sbostic 	      mask = 1 << bitpos;
208843205Sbostic 
208943205Sbostic 	      if (mask & buff[0])
209043205Sbostic 		overlap = YES;
209143205Sbostic 	      else
209243205Sbostic 		buff[0] |= mask;
209343205Sbostic 
209443205Sbostic 	      k--;
209543205Sbostic 	      bitpos++;
209643205Sbostic 	    }
209743205Sbostic 
209843205Sbostic 	  if (bitpos == BYTESIZE)
209943205Sbostic 	    {
210043205Sbostic 	      bitpos = 0;
210143205Sbostic 	      i++;
210243205Sbostic 	    }
210343205Sbostic 	}
210443205Sbostic 
210543205Sbostic       while (i < nbytes && overlap == NO)
210643205Sbostic 	{
210743205Sbostic 	  if (buff[i] == 0 && k >= BYTESIZE)
210843205Sbostic 	    {
210943205Sbostic 	      buff[i++] = MAXBYTE;
211043205Sbostic 	      k -= BYTESIZE;
211143205Sbostic 	    }
211243205Sbostic 	  else if (k < BYTESIZE)
211343205Sbostic 	    {
211443205Sbostic 	      while (k-- > 0)
211543205Sbostic 		{
211643205Sbostic 		  mask = 1 << k;
211743205Sbostic 		  if (mask & buff[i])
211843205Sbostic 		    overlap = YES;
211943205Sbostic 		  else
212043205Sbostic 		    buff[i] |= mask;
212143205Sbostic 		}
212243205Sbostic 	      i++;
212343205Sbostic 	    }
212443205Sbostic 	  else
212543205Sbostic 	    {
212643205Sbostic 	      overlap = YES;
212743205Sbostic 	      buff[i++] = MAXBYTE;
212843205Sbostic 	      k -= BYTESIZE;
212943205Sbostic 	    }
213043205Sbostic 	}
213143205Sbostic 
213243205Sbostic       while (i < n)
213343205Sbostic 	{
213443205Sbostic 	  if (k >= BYTESIZE)
213543205Sbostic 	    {
213643205Sbostic 	      buff[i++] = MAXBYTE;
213743205Sbostic 	      k -= BYTESIZE;
213843205Sbostic 	    }
213943205Sbostic 	  else
214043205Sbostic 	    {
214143205Sbostic 	      while (k-- > 0)
214243205Sbostic 		{
214343205Sbostic 		  mask = 1 << k;
214443205Sbostic 		  buff[i] |= mask;
214543205Sbostic 		}
214643205Sbostic 	      i++;
214743205Sbostic 	    }
214843205Sbostic 	}
214943205Sbostic 
215043205Sbostic       pos = lseek(chkfile, -nbytes, 1);
215143205Sbostic       if (pos == -1)
215243205Sbostic 	{
215343205Sbostic 	  err(seekerror);
215443205Sbostic 	  done(1);
215543205Sbostic 	}
215643205Sbostic 
215743205Sbostic       nbytes = write(chkfile, buff, n);
215843205Sbostic       if (nbytes != n)
215943205Sbostic 	{
216043205Sbostic 	  err(writeerror);
216143205Sbostic 	  done(1);
216243205Sbostic 	}
216343205Sbostic     }
216443205Sbostic 
216543205Sbostic   if (overlap == NO)
216643205Sbostic     {
216743205Sbostic       allzero = YES;
216843205Sbostic       k = len;
216943205Sbostic 
217043205Sbostic       while (k > 0 && allzero != NO)
2171*46302Sbostic 	if (constant[--k] != 0) allzero = NO;
217243205Sbostic 
217343205Sbostic       if (allzero == YES)
217443205Sbostic 	return;
217543205Sbostic     }
217643205Sbostic 
217743205Sbostic   pos = lseek(datafile, offset, 0);
217843205Sbostic   if (pos == -1)
217943205Sbostic     {
218043205Sbostic       err(seekerror);
218143205Sbostic       done(1);
218243205Sbostic     }
218343205Sbostic 
218443205Sbostic   k = repl;
218543205Sbostic   while (k-- > 0)
218643205Sbostic     {
2187*46302Sbostic       nbytes = write(datafile, constant, len);
218843205Sbostic       if (nbytes != len)
218943205Sbostic 	{
219043205Sbostic 	  err(writeerror);
219143205Sbostic 	  done(1);
219243205Sbostic 	}
219343205Sbostic     }
219443205Sbostic 
219543205Sbostic   if (overlap) overlapflag = YES;
219643205Sbostic 
219743205Sbostic   return;
219843205Sbostic }
219943205Sbostic 
220043205Sbostic 
220143205Sbostic 
220243205Sbostic Constp
220343205Sbostic getdatum()
220443205Sbostic {
220543205Sbostic   static char *toofew = "more data items than data values";
220643205Sbostic 
220743205Sbostic   register vallist *t;
220843205Sbostic 
220943205Sbostic   while (grvals != NULL)
221043205Sbostic     {
221143205Sbostic       if (grvals->status != NORMAL)
221243205Sbostic 	{
221343205Sbostic 	  dataerror = YES;
221443205Sbostic 	  return (NULL);
221543205Sbostic 	}
221643205Sbostic       else if (grvals->repl > 0)
221743205Sbostic 	{
221843205Sbostic 	  grvals->repl--;
221943205Sbostic 	  return (grvals->value);
222043205Sbostic 	}
222143205Sbostic       else
222243205Sbostic 	{
222343205Sbostic 	  badvalue = 0;
222443205Sbostic 	  frexpr ((tagptr) grvals->value);
222543205Sbostic 	  t = grvals;
222643205Sbostic 	  grvals = t->next;
222743205Sbostic 	  free((char *) t);
222843205Sbostic 	}
222943205Sbostic     }
223043205Sbostic 
223143205Sbostic   err(toofew);
223243205Sbostic   dataerror = YES;
223343205Sbostic   return (NULL);
223443205Sbostic }
223543205Sbostic 
223643205Sbostic 
223743205Sbostic 
223843205Sbostic outdata(lvals)
223943205Sbostic elist *lvals;
224043205Sbostic {
224143205Sbostic   register elist *top;
224243205Sbostic 
224343205Sbostic   top = lvals;
224443205Sbostic 
224543205Sbostic   while (top != NULL && dataerror == NO)
224643205Sbostic     {
224743205Sbostic       if (top->elt->tag == SIMPLE)
224843205Sbostic 	outaelt((aelt *) top->elt);
224943205Sbostic       else
225043205Sbostic 	outdolist((dolist *) top->elt);
225143205Sbostic 
225243205Sbostic       top = top->next;
225343205Sbostic     }
225443205Sbostic 
225543205Sbostic   return;
225643205Sbostic }
225743205Sbostic 
225843205Sbostic 
225943205Sbostic 
226043205Sbostic outaelt(ap)
226143205Sbostic aelt *ap;
226243205Sbostic {
226343205Sbostic   static char *toofew = "more data items than data values";
226443205Sbostic   static char *boundserror = "substring expression out of bounds";
226543205Sbostic   static char *order = "substring expressions out of order";
226643205Sbostic 
226743205Sbostic   register Namep np;
226843205Sbostic   register long soffset;
226943205Sbostic   register dvalue *lwb;
227043205Sbostic   register dvalue *upb;
2271*46302Sbostic   register Constp constant;
227243205Sbostic   register int k;
227343205Sbostic   register vallist *t;
227443205Sbostic   register int type;
227543205Sbostic   register ftnint typelen;
227643205Sbostic   register ftnint repl;
227743205Sbostic 
227843205Sbostic   extern char *packbytes();
227943205Sbostic 
228043205Sbostic   np = ap->var;
228143205Sbostic   setdfiles(np);
228243205Sbostic 
228343205Sbostic   type = np->vtype;
228443205Sbostic 
228543205Sbostic   if (type == TYCHAR)
2286*46302Sbostic     typelen = np->vleng->constblock.constant.ci;
228743205Sbostic   else if (type == TYLOGICAL)
228843205Sbostic     typelen = typesize[tylogical];
228943205Sbostic   else
229043205Sbostic     typelen = typesize[type];
229143205Sbostic 
229243205Sbostic   if (ap->subs != NULL || np->vdim == NULL)
229343205Sbostic     {
229443205Sbostic       soffset = indexer(ap);
229543205Sbostic       if (soffset == -1)
229643205Sbostic 	{
229743205Sbostic 	  dataerror = YES;
229843205Sbostic 	  return;
229943205Sbostic 	}
230043205Sbostic 
230143205Sbostic       soffset = soffset * typelen;
230243205Sbostic 
230343205Sbostic       if (ap->range != NULL)
230443205Sbostic 	{
230543205Sbostic 	  lwb = (dvalue *) evalvexpr(ap->range->low);
230643205Sbostic 	  upb = (dvalue *) evalvexpr(ap->range->high);
230743205Sbostic 	  if (lwb->status == ERRVAL || upb->status == ERRVAL)
230843205Sbostic 	    {
230943205Sbostic 	      frvexpr((vexpr *) lwb);
231043205Sbostic 	      frvexpr((vexpr *) upb);
231143205Sbostic 	      dataerror = YES;
231243205Sbostic 	      return;
231343205Sbostic 	    }
231443205Sbostic 
231543205Sbostic 	  if (lwb->status != NORMAL ||
231643205Sbostic 	      lwb->value < 1 ||
231743205Sbostic 	      lwb->value > typelen ||
231843205Sbostic 	      upb->status != NORMAL ||
231943205Sbostic 	      upb->value < 1 ||
232043205Sbostic 	      upb->value > typelen)
232143205Sbostic 	    {
232243205Sbostic 	      err(boundserror);
232343205Sbostic 	      frvexpr((vexpr *) lwb);
232443205Sbostic 	      frvexpr((vexpr *) upb);
232543205Sbostic 	      dataerror = YES;
232643205Sbostic 	      return;
232743205Sbostic 	    }
232843205Sbostic 
232943205Sbostic 	  if (lwb->value > upb->value)
233043205Sbostic 	    {
233143205Sbostic 	      err(order);
233243205Sbostic 	      frvexpr((vexpr *) lwb);
233343205Sbostic 	      frvexpr((vexpr *) upb);
233443205Sbostic 	      dataerror = YES;
233543205Sbostic 	      return;
233643205Sbostic 	    }
233743205Sbostic 
233843205Sbostic 	  soffset = soffset + lwb->value - 1;
233943205Sbostic 	  typelen = upb->value - lwb->value + 1;
234043205Sbostic 	  frvexpr((vexpr *) lwb);
234143205Sbostic 	  frvexpr((vexpr *) upb);
234243205Sbostic 	}
234343205Sbostic 
2344*46302Sbostic       constant = getdatum();
2345*46302Sbostic       if (constant == NULL || !ISCONST(constant))
234643205Sbostic 	return;
234743205Sbostic 
2348*46302Sbostic       constant = (Constp) convconst(type, typelen, constant);
2349*46302Sbostic       if (constant == NULL || !ISCONST(constant))
235043205Sbostic 	{
2351*46302Sbostic 	  frexpr((tagptr) constant);
235243205Sbostic 	  return;
235343205Sbostic 	}
235443205Sbostic 
235543205Sbostic       if (type == TYCHAR)
2356*46302Sbostic 	wrtdata(base + soffset, 1, typelen, constant->constant.ccp);
235743205Sbostic       else
2358*46302Sbostic 	wrtdata(base + soffset, 1, typelen, packbytes(constant));
235943205Sbostic 
2360*46302Sbostic       frexpr((tagptr) constant);
236143205Sbostic     }
236243205Sbostic   else
236343205Sbostic     {
236443205Sbostic       soffset = 0;
2365*46302Sbostic       k = np->vdim->nelt->constblock.constant.ci;
236643205Sbostic       while (k > 0 && dataerror == NO)
236743205Sbostic 	{
236843205Sbostic 	  if (grvals == NULL)
236943205Sbostic 	    {
237043205Sbostic 	      err(toofew);
237143205Sbostic 	      dataerror = YES;
237243205Sbostic 	    }
237343205Sbostic 	  else if (grvals->status != NORMAL)
237443205Sbostic 	    dataerror = YES;
237543205Sbostic 	  else if (grvals-> repl <= 0)
237643205Sbostic 	    {
237743205Sbostic 	      badvalue = 0;
237843205Sbostic 	      frexpr((tagptr) grvals->value);
237943205Sbostic 	      t = grvals;
238043205Sbostic 	      grvals = t->next;
238143205Sbostic 	      free((char *) t);
238243205Sbostic 	    }
238343205Sbostic 	  else
238443205Sbostic 	    {
2385*46302Sbostic 	      constant = grvals->value;
2386*46302Sbostic 	      if (constant == NULL || !ISCONST(constant))
238743205Sbostic 		{
238843205Sbostic 		  dataerror = YES;
238943205Sbostic 		}
239043205Sbostic 	      else
239143205Sbostic 		{
2392*46302Sbostic 		  constant = (Constp) convconst(type, typelen, constant);
2393*46302Sbostic 		  if (constant == NULL || !ISCONST(constant))
239443205Sbostic 		    {
239543205Sbostic 		      dataerror = YES;
2396*46302Sbostic 		      frexpr((tagptr) constant);
239743205Sbostic 		    }
239843205Sbostic 		  else
239943205Sbostic 		    {
240043205Sbostic 		      if (k > grvals->repl)
240143205Sbostic 			repl = grvals->repl;
240243205Sbostic 		      else
240343205Sbostic 			repl = k;
240443205Sbostic 
240543205Sbostic 		      grvals->repl -= repl;
240643205Sbostic 		      k -= repl;
240743205Sbostic 
240843205Sbostic 		      if (type == TYCHAR)
2409*46302Sbostic 			wrtdata(base+soffset, repl, typelen,
2410*46302Sbostic 			    constant->constant.ccp);
241143205Sbostic 		      else
2412*46302Sbostic 			wrtdata(base+soffset, repl, typelen,
2413*46302Sbostic 			    packbytes(constant));
241443205Sbostic 
241543205Sbostic 		      soffset = soffset + repl * typelen;
241643205Sbostic 
2417*46302Sbostic 		      frexpr((tagptr) constant);
241843205Sbostic 		    }
241943205Sbostic 		}
242043205Sbostic 	    }
242143205Sbostic 	}
242243205Sbostic     }
242343205Sbostic 
242443205Sbostic   return;
242543205Sbostic }
242643205Sbostic 
242743205Sbostic 
242843205Sbostic 
242943205Sbostic outdolist(dp)
243043205Sbostic dolist *dp;
243143205Sbostic {
243243205Sbostic   static char *zerostep = "zero step in implied-DO";
243343205Sbostic   static char *order = "zero iteration count in implied-DO";
243443205Sbostic 
243543205Sbostic   register dvalue *e1, *e2, *e3;
243643205Sbostic   register int direction;
243743205Sbostic   register dvalue *dv;
243843205Sbostic   register int done;
243943205Sbostic   register int addin;
244043205Sbostic   register int ts;
244143205Sbostic   register ftnint tv;
244243205Sbostic 
244343205Sbostic   e1 = (dvalue *) evalvexpr(dp->init);
244443205Sbostic   e2 = (dvalue *) evalvexpr(dp->limit);
244543205Sbostic   e3 = (dvalue *) evalvexpr(dp->step);
244643205Sbostic 
244743205Sbostic   if (e1->status == ERRVAL ||
244843205Sbostic       e2->status == ERRVAL ||
244943205Sbostic       e3->status == ERRVAL)
245043205Sbostic     {
245143205Sbostic       dataerror = YES;
245243205Sbostic       goto ret;
245343205Sbostic     }
245443205Sbostic 
245543205Sbostic   if (e1->status == NORMAL)
245643205Sbostic     {
245743205Sbostic       if (e2->status == NORMAL)
245843205Sbostic 	{
245943205Sbostic 	  if (e1->value < e2->value)
246043205Sbostic 	    direction = 1;
246143205Sbostic 	  else if (e1->value > e2->value)
246243205Sbostic 	    direction = -1;
246343205Sbostic 	  else
246443205Sbostic 	    direction = 0;
246543205Sbostic 	}
246643205Sbostic       else if (e2->status == MAXPLUS1)
246743205Sbostic 	direction = 1;
246843205Sbostic       else
246943205Sbostic 	direction = -1;
247043205Sbostic     }
247143205Sbostic   else if (e1->status == MAXPLUS1)
247243205Sbostic     {
247343205Sbostic       if (e2->status == MAXPLUS1)
247443205Sbostic 	direction = 0;
247543205Sbostic       else
247643205Sbostic 	direction = -1;
247743205Sbostic     }
247843205Sbostic   else
247943205Sbostic     {
248043205Sbostic       if (e2->status == MINLESS1)
248143205Sbostic 	direction = 0;
248243205Sbostic       else
248343205Sbostic 	direction = 1;
248443205Sbostic     }
248543205Sbostic 
248643205Sbostic   if (e3->status == NORMAL && e3->value == 0)
248743205Sbostic     {
248843205Sbostic       err(zerostep);
248943205Sbostic       dataerror = YES;
249043205Sbostic       goto ret;
249143205Sbostic     }
249243205Sbostic   else if (e3->status == MAXPLUS1 ||
249343205Sbostic 	   (e3->status == NORMAL && e3->value > 0))
249443205Sbostic     {
249543205Sbostic       if (direction == -1)
249643205Sbostic 	{
249743205Sbostic 	  warn(order);
249843205Sbostic 	  goto ret;
249943205Sbostic 	}
250043205Sbostic     }
250143205Sbostic   else
250243205Sbostic     {
250343205Sbostic       if (direction == 1)
250443205Sbostic 	{
250543205Sbostic 	  warn(order);
250643205Sbostic 	  goto ret;
250743205Sbostic 	}
250843205Sbostic     }
250943205Sbostic 
251043205Sbostic   dv = (dvalue *) dp->dovar;
251143205Sbostic   dv->status = e1->status;
251243205Sbostic   dv->value = e1->value;
251343205Sbostic 
251443205Sbostic   done = NO;
251543205Sbostic   while (done == NO && dataerror == NO)
251643205Sbostic     {
251743205Sbostic       outdata(dp->elts);
251843205Sbostic 
251943205Sbostic       if (e3->status == NORMAL && dv->status == NORMAL)
252043205Sbostic 	{
252143205Sbostic 	  addints(e3->value, dv->value);
252243205Sbostic 	  dv->status = rstatus;
252343205Sbostic 	  dv->value = rvalue;
252443205Sbostic 	}
252543205Sbostic       else
252643205Sbostic 	{
252743205Sbostic 	  if (e3->status != NORMAL)
252843205Sbostic 	    {
252943205Sbostic 	      if (e3->status == MAXPLUS1)
253043205Sbostic 		addin = MAXPLUS1;
253143205Sbostic 	      else
253243205Sbostic 		addin = MINLESS1;
253343205Sbostic 	      ts = dv->status;
253443205Sbostic 	      tv = dv->value;
253543205Sbostic 	    }
253643205Sbostic 	  else
253743205Sbostic 	    {
253843205Sbostic 	      if (dv->status == MAXPLUS1)
253943205Sbostic 		addin = MAXPLUS1;
254043205Sbostic 	      else
254143205Sbostic 		addin = MINLESS1;
254243205Sbostic 	      ts = e3->status;
254343205Sbostic 	      tv = e3->value;
254443205Sbostic 	    }
254543205Sbostic 
254643205Sbostic 	  if (addin == MAXPLUS1)
254743205Sbostic 	    {
254843205Sbostic 	      if (ts == MAXPLUS1 || (ts == NORMAL && tv > 0))
254943205Sbostic 		dv->status = ERRVAL;
255043205Sbostic 	      else if (ts == NORMAL && tv == 0)
255143205Sbostic 		dv->status = MAXPLUS1;
255243205Sbostic 	      else if (ts == NORMAL)
255343205Sbostic 		{
255443205Sbostic 		  dv->status = NORMAL;
255543205Sbostic 		  dv->value = tv + MAXINT;
255643205Sbostic 		  dv->value++;
255743205Sbostic 		}
255843205Sbostic 	      else
255943205Sbostic 		{
256043205Sbostic 		  dv->status = NORMAL;
256143205Sbostic 		  dv->value = 0;
256243205Sbostic 		}
256343205Sbostic 	    }
256443205Sbostic 	  else
256543205Sbostic 	    {
256643205Sbostic 	      if (ts == MINLESS1 || (ts == NORMAL && tv < 0))
256743205Sbostic 		dv->status = ERRVAL;
256843205Sbostic 	      else if (ts == NORMAL && tv == 0)
256943205Sbostic 		dv->status = MINLESS1;
257043205Sbostic 	      else if (ts == NORMAL)
257143205Sbostic 		{
257243205Sbostic 		  dv->status = NORMAL;
257343205Sbostic 		  dv->value = tv - MAXINT;
257443205Sbostic 		  dv->value--;
257543205Sbostic 		}
257643205Sbostic 	      else
257743205Sbostic 		{
257843205Sbostic 		  dv->status = NORMAL;
257943205Sbostic 		  dv->value = 0;
258043205Sbostic 		}
258143205Sbostic 	    }
258243205Sbostic 	}
258343205Sbostic 
258443205Sbostic       if (dv->status == ERRVAL)
258543205Sbostic 	done = YES;
258643205Sbostic       else if (direction > 0)
258743205Sbostic 	{
258843205Sbostic 	  if (e2->status == NORMAL)
258943205Sbostic 	    {
259043205Sbostic 	      if (dv->status == MAXPLUS1 ||
259143205Sbostic 		  (dv->status == NORMAL && dv->value > e2->value))
259243205Sbostic 		done = YES;
259343205Sbostic 	    }
259443205Sbostic 	}
259543205Sbostic       else if (direction < 0)
259643205Sbostic 	{
259743205Sbostic 	  if (e2->status == NORMAL)
259843205Sbostic 	    {
259943205Sbostic 	      if (dv->status == MINLESS1 ||
260043205Sbostic 		  (dv->status == NORMAL && dv->value < e2->value))
260143205Sbostic 		done = YES;
260243205Sbostic 	    }
260343205Sbostic 	}
260443205Sbostic       else
260543205Sbostic 	done = YES;
260643205Sbostic     }
260743205Sbostic 
260843205Sbostic ret:
260943205Sbostic   frvexpr((vexpr *) e1);
261043205Sbostic   frvexpr((vexpr *) e2);
261143205Sbostic   frvexpr((vexpr *) e3);
261243205Sbostic   return;
261343205Sbostic }
2614