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