xref: /original-bsd/usr.bin/f77/pass1.tahoe/data.c (revision b8be84b8)
1*b8be84b8Sbostic /*-
2*b8be84b8Sbostic  * Copyright (c) 1980 The Regents of the University of California.
3*b8be84b8Sbostic  * All rights reserved.
4*b8be84b8Sbostic  *
5*b8be84b8Sbostic  * %sccs.include.proprietary.c%
67a9d5071Sbostic  */
77a9d5071Sbostic 
87a9d5071Sbostic #ifndef lint
9*b8be84b8Sbostic static char sccsid[] = "@(#)data.c	5.3 (Berkeley) 04/12/91";
10*b8be84b8Sbostic #endif /* not lint */
117a9d5071Sbostic 
127a9d5071Sbostic /*
137a9d5071Sbostic  * data.c
147a9d5071Sbostic  *
157a9d5071Sbostic  * Routines for handling DATA statements, f77 compiler, 4.2 BSD.
167a9d5071Sbostic  *
177a9d5071Sbostic  * University of Utah CS Dept modification history:
187a9d5071Sbostic  *
197a9d5071Sbostic  * Revision 3.1  84/10/13  01:09:50  donn
207a9d5071Sbostic  * Installed Jerry Berkman's version; added UofU comment header.
217a9d5071Sbostic  *
227a9d5071Sbostic  */
237a9d5071Sbostic 
247a9d5071Sbostic #include "defs.h"
257a9d5071Sbostic #include "data.h"
267a9d5071Sbostic 
277a9d5071Sbostic 
287a9d5071Sbostic /*  global variables  */
297a9d5071Sbostic 
307a9d5071Sbostic flag overlapflag;
317a9d5071Sbostic 
327a9d5071Sbostic 
337a9d5071Sbostic 
347a9d5071Sbostic /*  local variables  */
357a9d5071Sbostic 
367a9d5071Sbostic LOCAL char rstatus;
377a9d5071Sbostic LOCAL ftnint rvalue;
387a9d5071Sbostic LOCAL dovars *dvlist;
397a9d5071Sbostic LOCAL int dataerror;
407a9d5071Sbostic LOCAL vallist *grvals;
417a9d5071Sbostic LOCAL int datafile;
427a9d5071Sbostic LOCAL int chkfile;
437a9d5071Sbostic LOCAL long base;
447a9d5071Sbostic 
457a9d5071Sbostic 
467a9d5071Sbostic 
477a9d5071Sbostic /*  Copied from expr.c  */
487a9d5071Sbostic 
letter(c)497a9d5071Sbostic LOCAL letter(c)
507a9d5071Sbostic register int c;
517a9d5071Sbostic {
527a9d5071Sbostic if( isupper(c) )
537a9d5071Sbostic 	c = tolower(c);
547a9d5071Sbostic return(c - 'a');
557a9d5071Sbostic }
567a9d5071Sbostic 
577a9d5071Sbostic 
587a9d5071Sbostic 
597a9d5071Sbostic vexpr *
cpdvalue(dp)607a9d5071Sbostic cpdvalue(dp)
617a9d5071Sbostic vexpr *dp;
627a9d5071Sbostic {
637a9d5071Sbostic   register dvalue *p;
647a9d5071Sbostic 
657a9d5071Sbostic   if (dp->tag != DVALUE)
667a9d5071Sbostic     badtag("cpdvalue", dp->tag);
677a9d5071Sbostic 
687a9d5071Sbostic   p = ALLOC(Dvalue);
697a9d5071Sbostic   p->tag = DVALUE;
707a9d5071Sbostic   p->status = dp->dvalue.status;
717a9d5071Sbostic   p->value = dp->dvalue.value;
727a9d5071Sbostic 
737a9d5071Sbostic   return ((vexpr *) p);
747a9d5071Sbostic }
757a9d5071Sbostic 
767a9d5071Sbostic 
777a9d5071Sbostic 
frvexpr(vp)787a9d5071Sbostic frvexpr(vp)
797a9d5071Sbostic register vexpr *vp;
807a9d5071Sbostic {
817a9d5071Sbostic   if (vp != NULL)
827a9d5071Sbostic     {
837a9d5071Sbostic       if (vp->tag == DNAME)
847a9d5071Sbostic 	free(vp->dname.repr);
857a9d5071Sbostic       else if (vp->tag == DEXPR)
867a9d5071Sbostic 	{
877a9d5071Sbostic 	  frvexpr(vp->dexpr.left);
887a9d5071Sbostic 	  frvexpr(vp->dexpr.right);
897a9d5071Sbostic 	}
907a9d5071Sbostic 
917a9d5071Sbostic       free((char *) vp);
927a9d5071Sbostic     }
937a9d5071Sbostic 
947a9d5071Sbostic   return;
957a9d5071Sbostic }
967a9d5071Sbostic 
977a9d5071Sbostic 
987a9d5071Sbostic 
frvlist(vp)997a9d5071Sbostic frvlist(vp)
1007a9d5071Sbostic register vlist *vp;
1017a9d5071Sbostic {
1027a9d5071Sbostic   register vlist *t;
1037a9d5071Sbostic 
1047a9d5071Sbostic   while (vp)
1057a9d5071Sbostic     {
1067a9d5071Sbostic       t = vp->next;
1077a9d5071Sbostic       frvexpr(vp->val);
1087a9d5071Sbostic       free((char *) vp);
1097a9d5071Sbostic       vp = t;
1107a9d5071Sbostic     }
1117a9d5071Sbostic 
1127a9d5071Sbostic   return;
1137a9d5071Sbostic }
1147a9d5071Sbostic 
1157a9d5071Sbostic 
1167a9d5071Sbostic 
frelist(ep)1177a9d5071Sbostic frelist(ep)
1187a9d5071Sbostic elist *ep;
1197a9d5071Sbostic {
1207a9d5071Sbostic   register elist *p;
1217a9d5071Sbostic   register elist *t;
1227a9d5071Sbostic   register aelt *ap;
1237a9d5071Sbostic   register dolist *dp;
1247a9d5071Sbostic 
1257a9d5071Sbostic   p = ep;
1267a9d5071Sbostic 
1277a9d5071Sbostic   while (p != NULL)
1287a9d5071Sbostic     {
1297a9d5071Sbostic       if (p->elt->tag == SIMPLE)
1307a9d5071Sbostic 	{
1317a9d5071Sbostic 	  ap = (aelt *) p->elt;
1327a9d5071Sbostic 	  frvlist(ap->subs);
1337a9d5071Sbostic 	  if (ap->range != NULL)
1347a9d5071Sbostic 	    {
1357a9d5071Sbostic 	      frvexpr(ap->range->low);
1367a9d5071Sbostic 	      frvexpr(ap->range->high);
1377a9d5071Sbostic 	      free((char *) ap->range);
1387a9d5071Sbostic 	    }
1397a9d5071Sbostic 	  free((char *) ap);
1407a9d5071Sbostic 	}
1417a9d5071Sbostic       else
1427a9d5071Sbostic 	{
1437a9d5071Sbostic 	  dp = (dolist *) p->elt;
1447a9d5071Sbostic 	  frvexpr(dp->dovar);
1457a9d5071Sbostic 	  frvexpr(dp->init);
1467a9d5071Sbostic 	  frvexpr(dp->limit);
1477a9d5071Sbostic 	  frvexpr(dp->step);
1487a9d5071Sbostic 	  frelist(dp->elts);
1497a9d5071Sbostic 	  free((char *) dp);
1507a9d5071Sbostic 	}
1517a9d5071Sbostic 
1527a9d5071Sbostic       t = p;
1537a9d5071Sbostic       p = p->next;
1547a9d5071Sbostic       free((char *) t);
1557a9d5071Sbostic     }
1567a9d5071Sbostic 
1577a9d5071Sbostic   return;
1587a9d5071Sbostic }
1597a9d5071Sbostic 
1607a9d5071Sbostic 
1617a9d5071Sbostic 
frvallist(vp)1627a9d5071Sbostic frvallist(vp)
1637a9d5071Sbostic vallist *vp;
1647a9d5071Sbostic {
1657a9d5071Sbostic   register vallist *p;
1667a9d5071Sbostic   register vallist *t;
1677a9d5071Sbostic 
1687a9d5071Sbostic   p = vp;
1697a9d5071Sbostic   while (p != NULL)
1707a9d5071Sbostic     {
1717a9d5071Sbostic       frexpr((tagptr) p->value);
1727a9d5071Sbostic       t = p;
1737a9d5071Sbostic       p = p->next;
1747a9d5071Sbostic       free((char *) t);
1757a9d5071Sbostic     }
1767a9d5071Sbostic 
1777a9d5071Sbostic   return;
1787a9d5071Sbostic }
1797a9d5071Sbostic 
1807a9d5071Sbostic 
1817a9d5071Sbostic 
revelist(ep)1827a9d5071Sbostic elist *revelist(ep)
1837a9d5071Sbostic register elist *ep;
1847a9d5071Sbostic {
1857a9d5071Sbostic   register elist *next;
1867a9d5071Sbostic   register elist *t;
1877a9d5071Sbostic 
1887a9d5071Sbostic   if (ep != NULL)
1897a9d5071Sbostic     {
1907a9d5071Sbostic       next = ep->next;
1917a9d5071Sbostic       ep->next = NULL;
1927a9d5071Sbostic 
1937a9d5071Sbostic       while (next)
1947a9d5071Sbostic 	{
1957a9d5071Sbostic 	  t = next->next;
1967a9d5071Sbostic 	  next->next = ep;
1977a9d5071Sbostic 	  ep = next;
1987a9d5071Sbostic 	  next = t;
1997a9d5071Sbostic 	}
2007a9d5071Sbostic     }
2017a9d5071Sbostic 
2027a9d5071Sbostic   return (ep);
2037a9d5071Sbostic }
2047a9d5071Sbostic 
2057a9d5071Sbostic 
2067a9d5071Sbostic 
revvlist(vp)2077a9d5071Sbostic vlist *revvlist(vp)
2087a9d5071Sbostic vlist *vp;
2097a9d5071Sbostic {
2107a9d5071Sbostic   register vlist *p;
2117a9d5071Sbostic   register vlist *next;
2127a9d5071Sbostic   register vlist *t;
2137a9d5071Sbostic 
2147a9d5071Sbostic   if (vp == NULL)
2157a9d5071Sbostic     p = NULL;
2167a9d5071Sbostic   else
2177a9d5071Sbostic     {
2187a9d5071Sbostic       p = vp;
2197a9d5071Sbostic       next = p->next;
2207a9d5071Sbostic       p->next = NULL;
2217a9d5071Sbostic 
2227a9d5071Sbostic       while (next)
2237a9d5071Sbostic 	{
2247a9d5071Sbostic 	  t = next->next;
2257a9d5071Sbostic 	  next->next = p;
2267a9d5071Sbostic 	  p = next;
2277a9d5071Sbostic 	  next = t;
2287a9d5071Sbostic 	}
2297a9d5071Sbostic     }
2307a9d5071Sbostic 
2317a9d5071Sbostic   return (p);
2327a9d5071Sbostic }
2337a9d5071Sbostic 
2347a9d5071Sbostic 
2357a9d5071Sbostic 
2367a9d5071Sbostic vallist *
revrvals(vp)2377a9d5071Sbostic revrvals(vp)
2387a9d5071Sbostic vallist *vp;
2397a9d5071Sbostic {
2407a9d5071Sbostic   register vallist *p;
2417a9d5071Sbostic   register vallist *next;
2427a9d5071Sbostic   register vallist *t;
2437a9d5071Sbostic 
2447a9d5071Sbostic   if (vp == NULL)
2457a9d5071Sbostic     p = NULL;
2467a9d5071Sbostic   else
2477a9d5071Sbostic     {
2487a9d5071Sbostic       p = vp;
2497a9d5071Sbostic       next = p->next;
2507a9d5071Sbostic       p->next = NULL;
2517a9d5071Sbostic       while (next)
2527a9d5071Sbostic 	{
2537a9d5071Sbostic 	  t = next->next;
2547a9d5071Sbostic 	  next->next = p;
2557a9d5071Sbostic 	  p = next;
2567a9d5071Sbostic 	  next = t;
2577a9d5071Sbostic 	}
2587a9d5071Sbostic     }
2597a9d5071Sbostic 
2607a9d5071Sbostic   return (p);
2617a9d5071Sbostic }
2627a9d5071Sbostic 
2637a9d5071Sbostic 
2647a9d5071Sbostic 
prepvexpr(tail,head)2657a9d5071Sbostic vlist *prepvexpr(tail, head)
2667a9d5071Sbostic vlist *tail;
2677a9d5071Sbostic vexpr *head;
2687a9d5071Sbostic {
2697a9d5071Sbostic   register vlist *p;
2707a9d5071Sbostic 
2717a9d5071Sbostic   p = ALLOC(Vlist);
2727a9d5071Sbostic   p->next = tail;
2737a9d5071Sbostic   p->val = head;
2747a9d5071Sbostic 
2757a9d5071Sbostic   return (p);
2767a9d5071Sbostic }
2777a9d5071Sbostic 
2787a9d5071Sbostic 
2797a9d5071Sbostic 
preplval(tail,head)2807a9d5071Sbostic elist *preplval(tail, head)
2817a9d5071Sbostic elist *tail;
2827a9d5071Sbostic delt* head;
2837a9d5071Sbostic {
2847a9d5071Sbostic   register elist *p;
2857a9d5071Sbostic   p = ALLOC(Elist);
2867a9d5071Sbostic   p->next = tail;
2877a9d5071Sbostic   p->elt = head;
2887a9d5071Sbostic 
2897a9d5071Sbostic   return (p);
2907a9d5071Sbostic }
2917a9d5071Sbostic 
2927a9d5071Sbostic 
2937a9d5071Sbostic 
mkdlval(name,subs,range)2947a9d5071Sbostic delt *mkdlval(name, subs, range)
2957a9d5071Sbostic vexpr *name;
2967a9d5071Sbostic vlist *subs;
2977a9d5071Sbostic rpair *range;
2987a9d5071Sbostic {
2997a9d5071Sbostic   static char *iscomm =" improper initialization for variable in COMMON";
3007a9d5071Sbostic   register aelt *p;
3017a9d5071Sbostic 
3027a9d5071Sbostic   p = ALLOC(Aelt);
3037a9d5071Sbostic   p->tag = SIMPLE;
3047a9d5071Sbostic   p->var = mkname(name->dname.len, name->dname.repr);
3057a9d5071Sbostic   if ((procclass != CLBLOCK) && (p->var->vstg == STGCOMMON))
3067a9d5071Sbostic 	warn(iscomm);
3077a9d5071Sbostic   p->subs = subs;
3087a9d5071Sbostic   p->range = range;
3097a9d5071Sbostic 
3107a9d5071Sbostic   return ((delt *) p);
3117a9d5071Sbostic }
3127a9d5071Sbostic 
3137a9d5071Sbostic 
3147a9d5071Sbostic 
mkdatado(lvals,dovar,params)3157a9d5071Sbostic delt *mkdatado(lvals, dovar, params)
3167a9d5071Sbostic elist *lvals;
3177a9d5071Sbostic vexpr *dovar;
3187a9d5071Sbostic vlist *params;
3197a9d5071Sbostic {
3207a9d5071Sbostic   static char *toofew = "missing loop parameters";
3217a9d5071Sbostic   static char *toomany = "too many loop parameters";
3227a9d5071Sbostic 
3237a9d5071Sbostic   register dolist *p;
3247a9d5071Sbostic   register vlist *vp;
3257a9d5071Sbostic   register int pcnt;
3267a9d5071Sbostic   register dvalue *one;
3277a9d5071Sbostic 
3287a9d5071Sbostic   p = ALLOC(DoList);
3297a9d5071Sbostic   p->tag = NESTED;
3307a9d5071Sbostic   p->elts = revelist(lvals);
3317a9d5071Sbostic   p->dovar = dovar;
3327a9d5071Sbostic 
3337a9d5071Sbostic   vp = params;
3347a9d5071Sbostic   pcnt = 0;
3357a9d5071Sbostic   while (vp)
3367a9d5071Sbostic     {
3377a9d5071Sbostic       pcnt++;
3387a9d5071Sbostic       vp = vp->next;
3397a9d5071Sbostic     }
3407a9d5071Sbostic 
3417a9d5071Sbostic   if (pcnt != 2 && pcnt != 3)
3427a9d5071Sbostic     {
3437a9d5071Sbostic       if (pcnt < 2)
3447a9d5071Sbostic 	err(toofew);
3457a9d5071Sbostic       else
3467a9d5071Sbostic 	err(toomany);
3477a9d5071Sbostic 
3487a9d5071Sbostic       p->init = (vexpr *) ALLOC(Derror);
3497a9d5071Sbostic       p->init->tag = DERROR;
3507a9d5071Sbostic 
3517a9d5071Sbostic       p->limit = (vexpr *) ALLOC(Derror);
3527a9d5071Sbostic       p->limit->tag = DERROR;
3537a9d5071Sbostic 
3547a9d5071Sbostic       p->step = (vexpr *) ALLOC(Derror);
3557a9d5071Sbostic       p->step->tag = DERROR;
3567a9d5071Sbostic     }
3577a9d5071Sbostic   else
3587a9d5071Sbostic     {
3597a9d5071Sbostic       vp = params;
3607a9d5071Sbostic 
3617a9d5071Sbostic       if (pcnt == 2)
3627a9d5071Sbostic 	{
3637a9d5071Sbostic 	  one = ALLOC(Dvalue);
3647a9d5071Sbostic 	  one->tag = DVALUE;
3657a9d5071Sbostic 	  one->status = NORMAL;
3667a9d5071Sbostic 	  one->value = 1;
3677a9d5071Sbostic 	  p->step = (vexpr *) one;
3687a9d5071Sbostic 	}
3697a9d5071Sbostic       else
3707a9d5071Sbostic 	{
3717a9d5071Sbostic 	  p->step = vp->val;
3727a9d5071Sbostic 	  vp->val = NULL;
3737a9d5071Sbostic 	  vp = vp->next;
3747a9d5071Sbostic 	}
3757a9d5071Sbostic 
3767a9d5071Sbostic       p->limit = vp->val;
3777a9d5071Sbostic       vp->val = NULL;
3787a9d5071Sbostic       vp = vp->next;
3797a9d5071Sbostic 
3807a9d5071Sbostic       p->init = vp->val;
3817a9d5071Sbostic       vp->val = NULL;
3827a9d5071Sbostic     }
3837a9d5071Sbostic 
3847a9d5071Sbostic   frvlist(params);
3857a9d5071Sbostic   return ((delt *) p);
3867a9d5071Sbostic }
3877a9d5071Sbostic 
3887a9d5071Sbostic 
3897a9d5071Sbostic 
mkdrange(lb,ub)3907a9d5071Sbostic rpair *mkdrange(lb, ub)
3917a9d5071Sbostic vexpr *lb, *ub;
3927a9d5071Sbostic {
3937a9d5071Sbostic   register rpair *p;
3947a9d5071Sbostic 
3957a9d5071Sbostic   p = ALLOC(Rpair);
3967a9d5071Sbostic   p->low = lb;
3977a9d5071Sbostic   p->high = ub;
3987a9d5071Sbostic 
3997a9d5071Sbostic   return (p);
4007a9d5071Sbostic }
4017a9d5071Sbostic 
4027a9d5071Sbostic 
4037a9d5071Sbostic 
mkdrval(repl,val)4047a9d5071Sbostic vallist *mkdrval(repl, val)
4057a9d5071Sbostic vexpr *repl;
4067a9d5071Sbostic expptr val;
4077a9d5071Sbostic {
4087a9d5071Sbostic   static char *badtag = "bad tag in mkdrval";
4097a9d5071Sbostic   static char *negrepl = "negative replicator";
4107a9d5071Sbostic   static char *zerorepl = "zero replicator";
4117a9d5071Sbostic   static char *toobig = "replicator too large";
4127a9d5071Sbostic   static char *nonconst = "%s is not a constant";
4137a9d5071Sbostic 
4147a9d5071Sbostic   register vexpr *vp;
4157a9d5071Sbostic   register vallist *p;
4167a9d5071Sbostic   register int status;
4177a9d5071Sbostic   register ftnint value;
4187a9d5071Sbostic   register int copied;
4197a9d5071Sbostic 
4207a9d5071Sbostic   copied = 0;
4217a9d5071Sbostic 
4227a9d5071Sbostic   if (repl->tag == DNAME)
4237a9d5071Sbostic     {
4247a9d5071Sbostic       vp = evaldname(repl);
4257a9d5071Sbostic       copied = 1;
4267a9d5071Sbostic     }
4277a9d5071Sbostic   else
4287a9d5071Sbostic     vp = repl;
4297a9d5071Sbostic 
4307a9d5071Sbostic   p = ALLOC(ValList);
4317a9d5071Sbostic   p->next = NULL;
4327a9d5071Sbostic   p->value = (Constp) val;
4337a9d5071Sbostic 
4347a9d5071Sbostic   if (vp->tag == DVALUE)
4357a9d5071Sbostic     {
4367a9d5071Sbostic       status = vp->dvalue.status;
4377a9d5071Sbostic       value = vp->dvalue.value;
4387a9d5071Sbostic 
4397a9d5071Sbostic       if ((status == NORMAL && value < 0) || status == MINLESS1)
4407a9d5071Sbostic 	{
4417a9d5071Sbostic 	  err(negrepl);
4427a9d5071Sbostic 	  p->status = ERRVAL;
4437a9d5071Sbostic 	}
4447a9d5071Sbostic       else if (status == NORMAL)
4457a9d5071Sbostic 	{
4467a9d5071Sbostic 	  if (value == 0)
4477a9d5071Sbostic 	    warn(zerorepl);
4487a9d5071Sbostic 	  p->status = NORMAL;
4497a9d5071Sbostic 	  p->repl = value;
4507a9d5071Sbostic 	}
4517a9d5071Sbostic       else if (status == MAXPLUS1)
4527a9d5071Sbostic 	{
4537a9d5071Sbostic 	  err(toobig);
4547a9d5071Sbostic 	  p->status = ERRVAL;
4557a9d5071Sbostic 	}
4567a9d5071Sbostic       else
4577a9d5071Sbostic 	p->status = ERRVAL;
4587a9d5071Sbostic     }
4597a9d5071Sbostic   else if (vp->tag == DNAME)
4607a9d5071Sbostic     {
4617a9d5071Sbostic       errnm(nonconst, vp->dname.len, vp->dname.repr);
4627a9d5071Sbostic       p->status = ERRVAL;
4637a9d5071Sbostic     }
4647a9d5071Sbostic   else if (vp->tag == DERROR)
4657a9d5071Sbostic     p->status = ERRVAL;
4667a9d5071Sbostic   else
4677a9d5071Sbostic     fatal(badtag);
4687a9d5071Sbostic 
4697a9d5071Sbostic   if (copied) frvexpr(vp);
4707a9d5071Sbostic   return (p);
4717a9d5071Sbostic }
4727a9d5071Sbostic 
4737a9d5071Sbostic 
4747a9d5071Sbostic 
4757a9d5071Sbostic /*  Evicon returns the value of the integer constant  */
4767a9d5071Sbostic /*  pointed to by token.                              */
4777a9d5071Sbostic 
evicon(len,token)4787a9d5071Sbostic vexpr *evicon(len, token)
4797a9d5071Sbostic register int len;
4807a9d5071Sbostic register char *token;
4817a9d5071Sbostic {
4827a9d5071Sbostic   static char *badconst = "bad integer constant";
4837a9d5071Sbostic   static char *overflow = "integer constant too large";
4847a9d5071Sbostic 
4857a9d5071Sbostic   register int i;
4867a9d5071Sbostic   register ftnint val;
4877a9d5071Sbostic   register int digit;
4887a9d5071Sbostic   register dvalue *p;
4897a9d5071Sbostic 
4907a9d5071Sbostic   if (len <= 0)
4917a9d5071Sbostic     fatal(badconst);
4927a9d5071Sbostic 
4937a9d5071Sbostic   p = ALLOC(Dvalue);
4947a9d5071Sbostic   p->tag = DVALUE;
4957a9d5071Sbostic 
4967a9d5071Sbostic   i = 0;
4977a9d5071Sbostic   val = 0;
4987a9d5071Sbostic   while (i < len)
4997a9d5071Sbostic     {
5007a9d5071Sbostic       if (val > MAXINT/10)
5017a9d5071Sbostic 	{
5027a9d5071Sbostic 	  err(overflow);
5037a9d5071Sbostic 	  p->status = ERRVAL;
5047a9d5071Sbostic 	  goto ret;
5057a9d5071Sbostic 	}
5067a9d5071Sbostic       val = 10*val;
5077a9d5071Sbostic       digit = token[i++];
5087a9d5071Sbostic       if (!isdigit(digit))
5097a9d5071Sbostic 	fatal(badconst);
5107a9d5071Sbostic       digit = digit - '0';
5117a9d5071Sbostic       if (MAXINT - val >= digit)
5127a9d5071Sbostic 	val = val + digit;
5137a9d5071Sbostic       else
5147a9d5071Sbostic 	if (i == len && MAXINT - val + 1 == digit)
5157a9d5071Sbostic 	  {
5167a9d5071Sbostic 	    p->status = MAXPLUS1;
5177a9d5071Sbostic 	    goto ret;
5187a9d5071Sbostic 	  }
5197a9d5071Sbostic 	else
5207a9d5071Sbostic 	  {
5217a9d5071Sbostic 	    err(overflow);
5227a9d5071Sbostic 	    p->status = ERRVAL;
5237a9d5071Sbostic 	    goto ret;
5247a9d5071Sbostic 	  }
5257a9d5071Sbostic     }
5267a9d5071Sbostic 
5277a9d5071Sbostic   p->status = NORMAL;
5287a9d5071Sbostic   p->value = val;
5297a9d5071Sbostic 
5307a9d5071Sbostic ret:
5317a9d5071Sbostic   return ((vexpr *) p);
5327a9d5071Sbostic }
5337a9d5071Sbostic 
5347a9d5071Sbostic 
5357a9d5071Sbostic 
5367a9d5071Sbostic /*  Ivaltoicon converts a dvalue into a constant block.  */
5377a9d5071Sbostic 
ivaltoicon(vp)5387a9d5071Sbostic expptr ivaltoicon(vp)
5397a9d5071Sbostic register vexpr *vp;
5407a9d5071Sbostic {
5417a9d5071Sbostic   static char *badtag = "bad tag in ivaltoicon";
5427a9d5071Sbostic   static char *overflow = "integer constant too large";
5437a9d5071Sbostic 
5447a9d5071Sbostic   register int vs;
5457a9d5071Sbostic   register expptr p;
5467a9d5071Sbostic 
5477a9d5071Sbostic   if (vp->tag == DERROR)
5487a9d5071Sbostic     return(errnode());
5497a9d5071Sbostic   else if (vp->tag != DVALUE)
5507a9d5071Sbostic     fatal(badtag);
5517a9d5071Sbostic 
5527a9d5071Sbostic   vs = vp->dvalue.status;
5537a9d5071Sbostic   if (vs == NORMAL)
5547a9d5071Sbostic     p = mkintcon(vp->dvalue.value);
5557a9d5071Sbostic   else if ((MAXINT + MININT == -1) && vs == MINLESS1)
5567a9d5071Sbostic     p = mkintcon(MININT);
5577a9d5071Sbostic   else if (vs == MAXPLUS1 || vs == MINLESS1)
5587a9d5071Sbostic     {
5597a9d5071Sbostic       err(overflow);
5607a9d5071Sbostic       p = errnode();
5617a9d5071Sbostic     }
5627a9d5071Sbostic   else
5637a9d5071Sbostic     p = errnode();
5647a9d5071Sbostic 
5657a9d5071Sbostic   return (p);
5667a9d5071Sbostic }
5677a9d5071Sbostic 
5687a9d5071Sbostic 
5697a9d5071Sbostic 
5707a9d5071Sbostic /*  Mkdname stores an identifier as a dname  */
5717a9d5071Sbostic 
mkdname(len,str)5727a9d5071Sbostic vexpr *mkdname(len, str)
5737a9d5071Sbostic int len;
5747a9d5071Sbostic register char *str;
5757a9d5071Sbostic {
5767a9d5071Sbostic   register dname *p;
5777a9d5071Sbostic   register int i;
5787a9d5071Sbostic   register char *s;
5797a9d5071Sbostic 
5807a9d5071Sbostic   s = (char *) ckalloc(len + 1);
5817a9d5071Sbostic   i = len;
5827a9d5071Sbostic   s[i] = '\0';
5837a9d5071Sbostic 
5847a9d5071Sbostic   while (--i >= 0)
5857a9d5071Sbostic     s[i] = str[i];
5867a9d5071Sbostic 
5877a9d5071Sbostic   p = ALLOC(Dname);
5887a9d5071Sbostic   p->tag = DNAME;
5897a9d5071Sbostic   p->len = len;
5907a9d5071Sbostic   p->repr = s;
5917a9d5071Sbostic 
5927a9d5071Sbostic   return ((vexpr *) p);
5937a9d5071Sbostic }
5947a9d5071Sbostic 
5957a9d5071Sbostic 
5967a9d5071Sbostic 
5977a9d5071Sbostic /*  Getname gets the symbol table information associated with  */
5987a9d5071Sbostic /*  a name.  Getname differs from mkname in that it will not   */
5997a9d5071Sbostic /*  add the name to the symbol table if it is not already      */
6007a9d5071Sbostic /*  present.                                                   */
6017a9d5071Sbostic 
getname(l,s)6027a9d5071Sbostic Namep getname(l, s)
6037a9d5071Sbostic int l;
6047a9d5071Sbostic register char *s;
6057a9d5071Sbostic {
6067a9d5071Sbostic   struct Hashentry *hp;
6077a9d5071Sbostic   int hash;
6087a9d5071Sbostic   register Namep q;
6097a9d5071Sbostic   register int i;
6107a9d5071Sbostic   char n[VL];
6117a9d5071Sbostic 
6127a9d5071Sbostic   hash = 0;
6137a9d5071Sbostic   for (i = 0; i < l && *s != '\0'; ++i)
6147a9d5071Sbostic     {
6157a9d5071Sbostic       hash += *s;
6167a9d5071Sbostic       n[i] = *s++;
6177a9d5071Sbostic     }
6187a9d5071Sbostic 
6197a9d5071Sbostic   while (i < VL)
6207a9d5071Sbostic     n[i++] = ' ';
6217a9d5071Sbostic 
6227a9d5071Sbostic   hash %= maxhash;
6237a9d5071Sbostic   hp = hashtab + hash;
6247a9d5071Sbostic 
6257a9d5071Sbostic   while (q = hp->varp)
6267a9d5071Sbostic     if (hash == hp->hashval
6277a9d5071Sbostic 	&& eqn(VL, n, q->varname))
6287a9d5071Sbostic       goto ret;
6297a9d5071Sbostic     else if (++hp >= lasthash)
6307a9d5071Sbostic       hp = hashtab;
6317a9d5071Sbostic 
6327a9d5071Sbostic ret:
6337a9d5071Sbostic   return (q);
6347a9d5071Sbostic }
6357a9d5071Sbostic 
6367a9d5071Sbostic 
6377a9d5071Sbostic 
6387a9d5071Sbostic /*  Evparam returns the value of the constant named by name.  */
6397a9d5071Sbostic 
evparam(np)6407a9d5071Sbostic expptr evparam(np)
6417a9d5071Sbostic register vexpr *np;
6427a9d5071Sbostic {
6437a9d5071Sbostic   static char *badtag = "bad tag in evparam";
6447a9d5071Sbostic   static char *undefined = "%s is undefined";
6457a9d5071Sbostic   static char *nonconst = "%s is not constant";
6467a9d5071Sbostic 
6477a9d5071Sbostic   register struct Paramblock *tp;
6487a9d5071Sbostic   register expptr p;
6497a9d5071Sbostic   register int len;
6507a9d5071Sbostic   register char *repr;
6517a9d5071Sbostic 
6527a9d5071Sbostic   if (np->tag != DNAME)
6537a9d5071Sbostic     fatal(badtag);
6547a9d5071Sbostic 
6557a9d5071Sbostic   len = np->dname.len;
6567a9d5071Sbostic   repr = np->dname.repr;
6577a9d5071Sbostic 
6587a9d5071Sbostic   tp = (struct Paramblock *) getname(len, repr);
6597a9d5071Sbostic 
6607a9d5071Sbostic   if (tp == NULL)
6617a9d5071Sbostic     {
6627a9d5071Sbostic       errnm(undefined, len, repr);
6637a9d5071Sbostic       p = errnode();
6647a9d5071Sbostic     }
6657a9d5071Sbostic   else if (tp->vclass != CLPARAM || !ISCONST(tp->paramval))
6667a9d5071Sbostic     {
6677a9d5071Sbostic       if (tp->paramval->tag != TERROR)
6687a9d5071Sbostic         errnm(nonconst, len, repr);
6697a9d5071Sbostic       p = errnode();
6707a9d5071Sbostic     }
6717a9d5071Sbostic   else
6727a9d5071Sbostic     p = (expptr) cpexpr(tp->paramval);
6737a9d5071Sbostic 
6747a9d5071Sbostic   return (p);
6757a9d5071Sbostic }
6767a9d5071Sbostic 
6777a9d5071Sbostic 
6787a9d5071Sbostic 
evaldname(dp)6797a9d5071Sbostic vexpr *evaldname(dp)
6807a9d5071Sbostic vexpr *dp;
6817a9d5071Sbostic {
6827a9d5071Sbostic   static char *undefined = "%s is undefined";
6837a9d5071Sbostic   static char *nonconst = "%s is not a constant";
6847a9d5071Sbostic   static char *nonint = "%s is not an integer";
6857a9d5071Sbostic 
6867a9d5071Sbostic   register dvalue *p;
6877a9d5071Sbostic   register struct Paramblock *tp;
6887a9d5071Sbostic   register int len;
6897a9d5071Sbostic   register char *repr;
6907a9d5071Sbostic 
6917a9d5071Sbostic   p = ALLOC(Dvalue);
6927a9d5071Sbostic   p->tag = DVALUE;
6937a9d5071Sbostic 
6947a9d5071Sbostic   len = dp->dname.len;
6957a9d5071Sbostic   repr = dp->dname.repr;
6967a9d5071Sbostic 
6977a9d5071Sbostic   tp = (struct Paramblock *) getname(len, repr);
6987a9d5071Sbostic 
6997a9d5071Sbostic   if (tp == NULL)
7007a9d5071Sbostic     {
7017a9d5071Sbostic       errnm(undefined, len, repr);
7027a9d5071Sbostic       p->status = ERRVAL;
7037a9d5071Sbostic     }
7047a9d5071Sbostic   else if (tp->vclass != CLPARAM || !ISCONST(tp->paramval))
7057a9d5071Sbostic     {
7067a9d5071Sbostic       if (tp->paramval->tag != TERROR)
7077a9d5071Sbostic         errnm(nonconst, len, repr);
7087a9d5071Sbostic       p->status = ERRVAL;
7097a9d5071Sbostic     }
7107a9d5071Sbostic   else if (!ISINT(tp->paramval->constblock.vtype))
7117a9d5071Sbostic     {
7127a9d5071Sbostic       errnm(nonint, len, repr);
7137a9d5071Sbostic       p->status = ERRVAL;
7147a9d5071Sbostic     }
7157a9d5071Sbostic   else
7167a9d5071Sbostic     {
7177a9d5071Sbostic       if ((MAXINT + MININT == -1)
718ee554660Sbostic 	  && tp->paramval->constblock.constant.ci == MININT)
7197a9d5071Sbostic 	p->status = MINLESS1;
7207a9d5071Sbostic       else
7217a9d5071Sbostic 	{
7227a9d5071Sbostic 	  p->status = NORMAL;
723ee554660Sbostic           p->value = tp->paramval->constblock.constant.ci;
7247a9d5071Sbostic 	}
7257a9d5071Sbostic     }
7267a9d5071Sbostic 
7277a9d5071Sbostic   return ((vexpr *) p);
7287a9d5071Sbostic }
7297a9d5071Sbostic 
7307a9d5071Sbostic 
7317a9d5071Sbostic 
mkdexpr(op,l,r)7327a9d5071Sbostic vexpr *mkdexpr(op, l, r)
7337a9d5071Sbostic register int op;
7347a9d5071Sbostic register vexpr *l;
7357a9d5071Sbostic register vexpr *r;
7367a9d5071Sbostic {
7377a9d5071Sbostic   static char *badop = "bad operator in mkdexpr";
7387a9d5071Sbostic 
7397a9d5071Sbostic   register vexpr *p;
7407a9d5071Sbostic 
7417a9d5071Sbostic   switch (op)
7427a9d5071Sbostic     {
7437a9d5071Sbostic     default:
7447a9d5071Sbostic       fatal(badop);
7457a9d5071Sbostic 
7467a9d5071Sbostic     case OPNEG:
7477a9d5071Sbostic     case OPPLUS:
7487a9d5071Sbostic     case OPMINUS:
7497a9d5071Sbostic     case OPSTAR:
7507a9d5071Sbostic     case OPSLASH:
7517a9d5071Sbostic     case OPPOWER:
7527a9d5071Sbostic       break;
7537a9d5071Sbostic     }
7547a9d5071Sbostic 
7557a9d5071Sbostic   if ((l != NULL && l->tag == DERROR) || r->tag == DERROR)
7567a9d5071Sbostic     {
7577a9d5071Sbostic       frvexpr(l);
7587a9d5071Sbostic       frvexpr(r);
7597a9d5071Sbostic       p = (vexpr *) ALLOC(Derror);
7607a9d5071Sbostic       p->tag = DERROR;
7617a9d5071Sbostic     }
7627a9d5071Sbostic   else if (op == OPNEG && r->tag == DVALUE)
7637a9d5071Sbostic     {
7647a9d5071Sbostic       p = negival(r);
7657a9d5071Sbostic       frvexpr(r);
7667a9d5071Sbostic     }
7677a9d5071Sbostic   else if (op != OPNEG && l->tag == DVALUE && r->tag == DVALUE)
7687a9d5071Sbostic     {
7697a9d5071Sbostic       switch (op)
7707a9d5071Sbostic 	{
7717a9d5071Sbostic 	case OPPLUS:
7727a9d5071Sbostic 	  p = addivals(l, r);
7737a9d5071Sbostic 	  break;
7747a9d5071Sbostic 
7757a9d5071Sbostic 	case OPMINUS:
7767a9d5071Sbostic 	  p = subivals(l, r);
7777a9d5071Sbostic 	  break;
7787a9d5071Sbostic 
7797a9d5071Sbostic 	case OPSTAR:
7807a9d5071Sbostic 	  p = mulivals(l, r);
7817a9d5071Sbostic 	  break;
7827a9d5071Sbostic 
7837a9d5071Sbostic 	case OPSLASH:
7847a9d5071Sbostic 	  p = divivals(l, r);
7857a9d5071Sbostic 	  break;
7867a9d5071Sbostic 
7877a9d5071Sbostic 	case OPPOWER:
7887a9d5071Sbostic 	  p = powivals(l, r);
7897a9d5071Sbostic 	  break;
7907a9d5071Sbostic 	}
7917a9d5071Sbostic 
7927a9d5071Sbostic       frvexpr(l);
7937a9d5071Sbostic       frvexpr(r);
7947a9d5071Sbostic     }
7957a9d5071Sbostic   else
7967a9d5071Sbostic     {
7977a9d5071Sbostic       p = (vexpr *) ALLOC(Dexpr);
7987a9d5071Sbostic       p->tag = DEXPR;
7997a9d5071Sbostic       p->dexpr.opcode = op;
8007a9d5071Sbostic       p->dexpr.left = l;
8017a9d5071Sbostic       p->dexpr.right = r;
8027a9d5071Sbostic     }
8037a9d5071Sbostic 
8047a9d5071Sbostic   return (p);
8057a9d5071Sbostic }
8067a9d5071Sbostic 
8077a9d5071Sbostic 
8087a9d5071Sbostic 
addivals(l,r)8097a9d5071Sbostic vexpr *addivals(l, r)
8107a9d5071Sbostic vexpr *l;
8117a9d5071Sbostic vexpr *r;
8127a9d5071Sbostic {
8137a9d5071Sbostic   static char *badtag = "bad tag in addivals";
8147a9d5071Sbostic   static char *overflow = "integer value too large";
8157a9d5071Sbostic 
8167a9d5071Sbostic   register int ls, rs;
8177a9d5071Sbostic   register ftnint lv, rv;
8187a9d5071Sbostic   register dvalue *p;
8197a9d5071Sbostic   register ftnint k;
8207a9d5071Sbostic 
8217a9d5071Sbostic   if (l->tag != DVALUE || r->tag != DVALUE)
8227a9d5071Sbostic     fatal(badtag);
8237a9d5071Sbostic 
8247a9d5071Sbostic   ls = l->dvalue.status;
8257a9d5071Sbostic   lv = l->dvalue.value;
8267a9d5071Sbostic   rs = r->dvalue.status;
8277a9d5071Sbostic   rv = r->dvalue.value;
8287a9d5071Sbostic 
8297a9d5071Sbostic   p = ALLOC(Dvalue);
8307a9d5071Sbostic   p->tag = DVALUE;
8317a9d5071Sbostic 
8327a9d5071Sbostic   if (ls == ERRVAL || rs == ERRVAL)
8337a9d5071Sbostic     p->status = ERRVAL;
8347a9d5071Sbostic 
8357a9d5071Sbostic   else if (ls == NORMAL && rs == NORMAL)
8367a9d5071Sbostic     {
8377a9d5071Sbostic       addints(lv, rv);
8387a9d5071Sbostic       if (rstatus == ERRVAL)
8397a9d5071Sbostic 	err(overflow);
8407a9d5071Sbostic       p->status = rstatus;
8417a9d5071Sbostic       p->value = rvalue;
8427a9d5071Sbostic     }
8437a9d5071Sbostic 
8447a9d5071Sbostic   else
8457a9d5071Sbostic     {
8467a9d5071Sbostic       if (rs == MAXPLUS1 || rs == MINLESS1)
8477a9d5071Sbostic 	{
8487a9d5071Sbostic 	  rs = ls;
8497a9d5071Sbostic 	  rv = lv;
8507a9d5071Sbostic 	  ls = r->dvalue.status;
8517a9d5071Sbostic 	}
8527a9d5071Sbostic 
8537a9d5071Sbostic       if (rs == NORMAL && rv == 0)
8547a9d5071Sbostic 	p->status = ls;
8557a9d5071Sbostic       else if (ls == MAXPLUS1)
8567a9d5071Sbostic 	{
8577a9d5071Sbostic 	  if (rs == NORMAL && rv < 0)
8587a9d5071Sbostic 	    {
8597a9d5071Sbostic 	      p->status = NORMAL;
8607a9d5071Sbostic 	      k = MAXINT + rv;
8617a9d5071Sbostic 	      p->value = k + 1;
8627a9d5071Sbostic 	    }
8637a9d5071Sbostic 	  else if (rs == MINLESS1)
8647a9d5071Sbostic 	    {
8657a9d5071Sbostic 	      p->status = NORMAL;
8667a9d5071Sbostic 	      p->value = 0;
8677a9d5071Sbostic 	    }
8687a9d5071Sbostic 	  else
8697a9d5071Sbostic 	    {
8707a9d5071Sbostic 	      err(overflow);
8717a9d5071Sbostic 	      p->status = ERRVAL;
8727a9d5071Sbostic 	    }
8737a9d5071Sbostic 	}
8747a9d5071Sbostic       else
8757a9d5071Sbostic 	{
8767a9d5071Sbostic 	  if (rs == NORMAL && rv > 0)
8777a9d5071Sbostic 	    {
8787a9d5071Sbostic 	      p->status = NORMAL;
8797a9d5071Sbostic 	      k = ( -MAXINT ) + rv;
8807a9d5071Sbostic 	      p->value = k - 1;
8817a9d5071Sbostic 	    }
8827a9d5071Sbostic 	  else if (rs == MAXPLUS1)
8837a9d5071Sbostic 	    {
8847a9d5071Sbostic 	      p->status = NORMAL;
8857a9d5071Sbostic 	      p->value = 0;
8867a9d5071Sbostic 	    }
8877a9d5071Sbostic 	  else
8887a9d5071Sbostic 	    {
8897a9d5071Sbostic 	      err(overflow);
8907a9d5071Sbostic 	      p->status = ERRVAL;
8917a9d5071Sbostic 	    }
8927a9d5071Sbostic 	}
8937a9d5071Sbostic     }
8947a9d5071Sbostic 
8957a9d5071Sbostic   return ((vexpr *) p);
8967a9d5071Sbostic }
8977a9d5071Sbostic 
8987a9d5071Sbostic 
8997a9d5071Sbostic 
negival(vp)9007a9d5071Sbostic vexpr *negival(vp)
9017a9d5071Sbostic vexpr *vp;
9027a9d5071Sbostic {
9037a9d5071Sbostic   static char *badtag = "bad tag in negival";
9047a9d5071Sbostic 
9057a9d5071Sbostic   register int vs;
9067a9d5071Sbostic   register dvalue *p;
9077a9d5071Sbostic 
9087a9d5071Sbostic   if (vp->tag != DVALUE)
9097a9d5071Sbostic     fatal(badtag);
9107a9d5071Sbostic 
9117a9d5071Sbostic   vs = vp->dvalue.status;
9127a9d5071Sbostic 
9137a9d5071Sbostic   p = ALLOC(Dvalue);
9147a9d5071Sbostic   p->tag = DVALUE;
9157a9d5071Sbostic 
9167a9d5071Sbostic   if (vs == ERRVAL)
9177a9d5071Sbostic     p->status = ERRVAL;
9187a9d5071Sbostic   else if (vs == NORMAL)
9197a9d5071Sbostic     {
9207a9d5071Sbostic       p->status = NORMAL;
9217a9d5071Sbostic       p->value = -(vp->dvalue.value);
9227a9d5071Sbostic     }
9237a9d5071Sbostic   else if (vs == MAXPLUS1)
9247a9d5071Sbostic     p->status = MINLESS1;
9257a9d5071Sbostic   else
9267a9d5071Sbostic     p->status = MAXPLUS1;
9277a9d5071Sbostic 
9287a9d5071Sbostic   return ((vexpr *) p);
9297a9d5071Sbostic }
9307a9d5071Sbostic 
9317a9d5071Sbostic 
9327a9d5071Sbostic 
subivals(l,r)9337a9d5071Sbostic vexpr *subivals(l, r)
9347a9d5071Sbostic vexpr *l;
9357a9d5071Sbostic vexpr *r;
9367a9d5071Sbostic {
9377a9d5071Sbostic   static char *badtag = "bad tag in subivals";
9387a9d5071Sbostic 
9397a9d5071Sbostic   register vexpr *p;
9407a9d5071Sbostic   register vexpr *t;
9417a9d5071Sbostic 
9427a9d5071Sbostic   if (l->tag != DVALUE || r->tag != DVALUE)
9437a9d5071Sbostic     fatal(badtag);
9447a9d5071Sbostic 
9457a9d5071Sbostic   t = negival(r);
9467a9d5071Sbostic   p = addivals(l, t);
9477a9d5071Sbostic   frvexpr(t);
9487a9d5071Sbostic 
9497a9d5071Sbostic   return (p);
9507a9d5071Sbostic }
9517a9d5071Sbostic 
9527a9d5071Sbostic 
9537a9d5071Sbostic 
mulivals(l,r)9547a9d5071Sbostic vexpr *mulivals(l, r)
9557a9d5071Sbostic vexpr *l;
9567a9d5071Sbostic vexpr *r;
9577a9d5071Sbostic {
9587a9d5071Sbostic   static char *badtag = "bad tag in mulivals";
9597a9d5071Sbostic   static char *overflow = "integer value too large";
9607a9d5071Sbostic 
9617a9d5071Sbostic   register int ls, rs;
9627a9d5071Sbostic   register ftnint lv, rv;
9637a9d5071Sbostic   register dvalue *p;
9647a9d5071Sbostic 
9657a9d5071Sbostic   if (l->tag != DVALUE || r->tag != DVALUE)
9667a9d5071Sbostic     fatal(badtag);
9677a9d5071Sbostic 
9687a9d5071Sbostic   ls = l->dvalue.status;
9697a9d5071Sbostic   lv = l->dvalue.value;
9707a9d5071Sbostic   rs = r->dvalue.status;
9717a9d5071Sbostic   rv = r->dvalue.value;
9727a9d5071Sbostic 
9737a9d5071Sbostic   p = ALLOC(Dvalue);
9747a9d5071Sbostic   p->tag = DVALUE;
9757a9d5071Sbostic 
9767a9d5071Sbostic   if (ls == ERRVAL || rs == ERRVAL)
9777a9d5071Sbostic     p->status = ERRVAL;
9787a9d5071Sbostic 
9797a9d5071Sbostic   else if (ls == NORMAL && rs == NORMAL)
9807a9d5071Sbostic     {
9817a9d5071Sbostic       mulints(lv, rv);
9827a9d5071Sbostic       if (rstatus == ERRVAL)
9837a9d5071Sbostic 	err(overflow);
9847a9d5071Sbostic       p->status = rstatus;
9857a9d5071Sbostic       p->value = rvalue;
9867a9d5071Sbostic     }
9877a9d5071Sbostic   else
9887a9d5071Sbostic     {
9897a9d5071Sbostic       if (rs == MAXPLUS1 || rs == MINLESS1)
9907a9d5071Sbostic 	{
9917a9d5071Sbostic 	  rs = ls;
9927a9d5071Sbostic 	  rv = lv;
9937a9d5071Sbostic 	  ls = r->dvalue.status;
9947a9d5071Sbostic 	}
9957a9d5071Sbostic 
9967a9d5071Sbostic       if (rs == NORMAL && rv == 0)
9977a9d5071Sbostic 	{
9987a9d5071Sbostic 	  p->status = NORMAL;
9997a9d5071Sbostic 	  p->value = 0;
10007a9d5071Sbostic 	}
10017a9d5071Sbostic       else if (rs == NORMAL && rv == 1)
10027a9d5071Sbostic 	p->status = ls;
10037a9d5071Sbostic       else if (rs == NORMAL && rv == -1)
10047a9d5071Sbostic 	if (ls == MAXPLUS1)
10057a9d5071Sbostic 	  p->status = MINLESS1;
10067a9d5071Sbostic 	else
10077a9d5071Sbostic 	  p->status = MAXPLUS1;
10087a9d5071Sbostic       else
10097a9d5071Sbostic 	{
10107a9d5071Sbostic 	  err(overflow);
10117a9d5071Sbostic 	  p->status = ERRVAL;
10127a9d5071Sbostic 	}
10137a9d5071Sbostic     }
10147a9d5071Sbostic 
10157a9d5071Sbostic   return ((vexpr *) p);
10167a9d5071Sbostic }
10177a9d5071Sbostic 
10187a9d5071Sbostic 
10197a9d5071Sbostic 
divivals(l,r)10207a9d5071Sbostic vexpr *divivals(l, r)
10217a9d5071Sbostic vexpr *l;
10227a9d5071Sbostic vexpr *r;
10237a9d5071Sbostic {
10247a9d5071Sbostic   static char *badtag = "bad tag in divivals";
10257a9d5071Sbostic   static char *zerodivide = "division by zero";
10267a9d5071Sbostic 
10277a9d5071Sbostic   register int ls, rs;
10287a9d5071Sbostic   register ftnint lv, rv;
10297a9d5071Sbostic   register dvalue *p;
10307a9d5071Sbostic   register ftnint k;
10317a9d5071Sbostic   register int sign;
10327a9d5071Sbostic 
10337a9d5071Sbostic   if (l->tag != DVALUE && r->tag != DVALUE)
10347a9d5071Sbostic     fatal(badtag);
10357a9d5071Sbostic 
10367a9d5071Sbostic   ls = l->dvalue.status;
10377a9d5071Sbostic   lv = l->dvalue.value;
10387a9d5071Sbostic   rs = r->dvalue.status;
10397a9d5071Sbostic   rv = r->dvalue.value;
10407a9d5071Sbostic 
10417a9d5071Sbostic   p = ALLOC(Dvalue);
10427a9d5071Sbostic   p->tag = DVALUE;
10437a9d5071Sbostic 
10447a9d5071Sbostic   if (ls == ERRVAL || rs == ERRVAL)
10457a9d5071Sbostic     p->status = ERRVAL;
10467a9d5071Sbostic   else if (rs == NORMAL)
10477a9d5071Sbostic     {
10487a9d5071Sbostic       if (rv == 0)
10497a9d5071Sbostic 	{
10507a9d5071Sbostic 	  err(zerodivide);
10517a9d5071Sbostic 	  p->status = ERRVAL;
10527a9d5071Sbostic 	}
10537a9d5071Sbostic       else if (ls == NORMAL)
10547a9d5071Sbostic 	{
10557a9d5071Sbostic 	  p->status = NORMAL;
10567a9d5071Sbostic 	  p->value = lv / rv;
10577a9d5071Sbostic 	}
10587a9d5071Sbostic       else if (rv == 1)
10597a9d5071Sbostic 	p->status = ls;
10607a9d5071Sbostic       else if (rv == -1)
10617a9d5071Sbostic 	if (ls == MAXPLUS1)
10627a9d5071Sbostic 	  p->status = MINLESS1;
10637a9d5071Sbostic 	else
10647a9d5071Sbostic 	  p->status = MAXPLUS1;
10657a9d5071Sbostic       else
10667a9d5071Sbostic 	{
10677a9d5071Sbostic 	  p->status = NORMAL;
10687a9d5071Sbostic 
10697a9d5071Sbostic 	  if (ls == MAXPLUS1)
10707a9d5071Sbostic 	    sign = 1;
10717a9d5071Sbostic 	  else
10727a9d5071Sbostic 	    sign = -1;
10737a9d5071Sbostic 
10747a9d5071Sbostic 	  if (rv < 0)
10757a9d5071Sbostic 	    {
10767a9d5071Sbostic 	      rv = -rv;
10777a9d5071Sbostic 	      sign = -sign;
10787a9d5071Sbostic 	    }
10797a9d5071Sbostic 
10807a9d5071Sbostic 	  k = MAXINT - rv;
10817a9d5071Sbostic 	  p->value = sign * ((k + 1)/rv + 1);
10827a9d5071Sbostic 	}
10837a9d5071Sbostic     }
10847a9d5071Sbostic   else
10857a9d5071Sbostic     {
10867a9d5071Sbostic       p->status = NORMAL;
10877a9d5071Sbostic       if (ls == NORMAL)
10887a9d5071Sbostic 	p->value = 0;
10897a9d5071Sbostic       else if ((ls == MAXPLUS1 && rs == MAXPLUS1)
10907a9d5071Sbostic 		|| (ls == MINLESS1 && rs == MINLESS1))
10917a9d5071Sbostic 	p->value = 1;
10927a9d5071Sbostic       else
10937a9d5071Sbostic 	p->value = -1;
10947a9d5071Sbostic     }
10957a9d5071Sbostic 
10967a9d5071Sbostic   return ((vexpr *) p);
10977a9d5071Sbostic }
10987a9d5071Sbostic 
10997a9d5071Sbostic 
11007a9d5071Sbostic 
powivals(l,r)11017a9d5071Sbostic vexpr *powivals(l, r)
11027a9d5071Sbostic vexpr *l;
11037a9d5071Sbostic vexpr *r;
11047a9d5071Sbostic {
11057a9d5071Sbostic   static char *badtag = "bad tag in powivals";
11067a9d5071Sbostic   static char *zerozero = "zero raised to the zero-th power";
11077a9d5071Sbostic   static char *zeroneg = "zero raised to a negative power";
11087a9d5071Sbostic   static char *overflow = "integer value too large";
11097a9d5071Sbostic 
11107a9d5071Sbostic   register int ls, rs;
11117a9d5071Sbostic   register ftnint lv, rv;
11127a9d5071Sbostic   register dvalue *p;
11137a9d5071Sbostic 
11147a9d5071Sbostic   if (l->tag != DVALUE || r->tag != DVALUE)
11157a9d5071Sbostic     fatal(badtag);
11167a9d5071Sbostic 
11177a9d5071Sbostic   ls = l->dvalue.status;
11187a9d5071Sbostic   lv = l->dvalue.value;
11197a9d5071Sbostic   rs = r->dvalue.status;
11207a9d5071Sbostic   rv = r->dvalue.value;
11217a9d5071Sbostic 
11227a9d5071Sbostic   p = ALLOC(Dvalue);
11237a9d5071Sbostic   p->tag = DVALUE;
11247a9d5071Sbostic 
11257a9d5071Sbostic   if (ls == ERRVAL || rs == ERRVAL)
11267a9d5071Sbostic     p->status = ERRVAL;
11277a9d5071Sbostic 
11287a9d5071Sbostic   else if (ls == NORMAL)
11297a9d5071Sbostic     {
11307a9d5071Sbostic       if (lv == 1)
11317a9d5071Sbostic 	{
11327a9d5071Sbostic 	  p->status = NORMAL;
11337a9d5071Sbostic 	  p->value = 1;
11347a9d5071Sbostic 	}
11357a9d5071Sbostic       else if (lv == 0)
11367a9d5071Sbostic 	{
11377a9d5071Sbostic 	  if (rs == MAXPLUS1 || (rs == NORMAL && rv > 0))
11387a9d5071Sbostic 	    {
11397a9d5071Sbostic 	      p->status = NORMAL;
11407a9d5071Sbostic 	      p->value = 0;
11417a9d5071Sbostic 	    }
11427a9d5071Sbostic 	  else if (rs == NORMAL && rv == 0)
11437a9d5071Sbostic 	    {
11447a9d5071Sbostic 	      warn(zerozero);
11457a9d5071Sbostic 	      p->status = NORMAL;
11467a9d5071Sbostic 	      p->value = 1;
11477a9d5071Sbostic 	    }
11487a9d5071Sbostic 	  else
11497a9d5071Sbostic 	    {
11507a9d5071Sbostic 	      err(zeroneg);
11517a9d5071Sbostic 	      p->status = ERRVAL;
11527a9d5071Sbostic 	    }
11537a9d5071Sbostic 	}
11547a9d5071Sbostic       else if (lv == -1)
11557a9d5071Sbostic 	{
11567a9d5071Sbostic 	  p->status = NORMAL;
11577a9d5071Sbostic 	  if (rs == NORMAL)
11587a9d5071Sbostic 	    {
11597a9d5071Sbostic 	      if (rv < 0) rv = -rv;
11607a9d5071Sbostic 	      if (rv % 2 == 0)
11617a9d5071Sbostic 		p->value = 1;
11627a9d5071Sbostic 	      else
11637a9d5071Sbostic 		p->value = -1;
11647a9d5071Sbostic 	    }
11657a9d5071Sbostic 	  else
11667a9d5071Sbostic #	    if (MAXINT % 2 == 1)
11677a9d5071Sbostic 	      p->value = 1;
11687a9d5071Sbostic #	    else
11697a9d5071Sbostic 	      p->value = -1;
11707a9d5071Sbostic #	    endif
11717a9d5071Sbostic 	}
11727a9d5071Sbostic       else
11737a9d5071Sbostic 	{
11747a9d5071Sbostic 	  if (rs == NORMAL && rv > 0)
11757a9d5071Sbostic 	    {
11767a9d5071Sbostic 	      rstatus = NORMAL;
11777a9d5071Sbostic 	      rvalue = lv;
11787a9d5071Sbostic 	      while (--rv && rstatus == NORMAL)
11797a9d5071Sbostic 		mulints(rvalue, lv);
11807a9d5071Sbostic 	      if (rv == 0 && rstatus != ERRVAL)
11817a9d5071Sbostic 		{
11827a9d5071Sbostic 		  p->status = rstatus;
11837a9d5071Sbostic 		  p->value = rvalue;
11847a9d5071Sbostic 		}
11857a9d5071Sbostic 	      else
11867a9d5071Sbostic 		{
11877a9d5071Sbostic 		  err(overflow);
11887a9d5071Sbostic 		  p->status = ERRVAL;
11897a9d5071Sbostic 		}
11907a9d5071Sbostic 	    }
11917a9d5071Sbostic 	  else if (rs == MAXPLUS1)
11927a9d5071Sbostic 	    {
11937a9d5071Sbostic 	      err(overflow);
11947a9d5071Sbostic 	      p->status = ERRVAL;
11957a9d5071Sbostic 	    }
11967a9d5071Sbostic 	  else if (rs == NORMAL && rv == 0)
11977a9d5071Sbostic 	    {
11987a9d5071Sbostic 	      p->status = NORMAL;
11997a9d5071Sbostic 	      p->value = 1;
12007a9d5071Sbostic 	    }
12017a9d5071Sbostic 	  else
12027a9d5071Sbostic 	    {
12037a9d5071Sbostic 	      p->status = NORMAL;
12047a9d5071Sbostic 	      p->value = 0;
12057a9d5071Sbostic 	    }
12067a9d5071Sbostic 	}
12077a9d5071Sbostic     }
12087a9d5071Sbostic 
12097a9d5071Sbostic   else
12107a9d5071Sbostic     {
12117a9d5071Sbostic       if (rs == MAXPLUS1 || (rs == NORMAL && rv > 1))
12127a9d5071Sbostic 	{
12137a9d5071Sbostic 	  err(overflow);
12147a9d5071Sbostic 	  p->status = ERRVAL;
12157a9d5071Sbostic 	}
12167a9d5071Sbostic       else if (rs == NORMAL && rv == 1)
12177a9d5071Sbostic 	p->status = ls;
12187a9d5071Sbostic       else if (rs == NORMAL && rv == 0)
12197a9d5071Sbostic 	{
12207a9d5071Sbostic 	  p->status = NORMAL;
12217a9d5071Sbostic 	  p->value = 1;
12227a9d5071Sbostic 	}
12237a9d5071Sbostic       else
12247a9d5071Sbostic 	{
12257a9d5071Sbostic 	  p->status = NORMAL;
12267a9d5071Sbostic 	  p->value = 0;
12277a9d5071Sbostic 	}
12287a9d5071Sbostic     }
12297a9d5071Sbostic 
12307a9d5071Sbostic   return ((vexpr *) p);
12317a9d5071Sbostic }
12327a9d5071Sbostic 
12337a9d5071Sbostic 
12347a9d5071Sbostic 
12357a9d5071Sbostic /*  Addints adds two integer values.  */
12367a9d5071Sbostic 
addints(i,j)12377a9d5071Sbostic addints(i, j)
12387a9d5071Sbostic register ftnint i, j;
12397a9d5071Sbostic {
12407a9d5071Sbostic   register ftnint margin;
12417a9d5071Sbostic 
12427a9d5071Sbostic   if (i == 0)
12437a9d5071Sbostic     {
12447a9d5071Sbostic       rstatus = NORMAL;
12457a9d5071Sbostic       rvalue = j;
12467a9d5071Sbostic     }
12477a9d5071Sbostic   else if (i > 0)
12487a9d5071Sbostic     {
12497a9d5071Sbostic       margin = MAXINT - i;
12507a9d5071Sbostic       if (j <= margin)
12517a9d5071Sbostic 	{
12527a9d5071Sbostic 	  rstatus = NORMAL;
12537a9d5071Sbostic 	  rvalue = i + j;
12547a9d5071Sbostic 	}
12557a9d5071Sbostic       else if (j == margin + 1)
12567a9d5071Sbostic 	rstatus = MAXPLUS1;
12577a9d5071Sbostic       else
12587a9d5071Sbostic 	rstatus = ERRVAL;
12597a9d5071Sbostic     }
12607a9d5071Sbostic   else
12617a9d5071Sbostic     {
12627a9d5071Sbostic       margin = ( -MAXINT ) - i;
12637a9d5071Sbostic       if (j >= margin)
12647a9d5071Sbostic 	{
12657a9d5071Sbostic 	  rstatus = NORMAL;
12667a9d5071Sbostic 	  rvalue = i + j;
12677a9d5071Sbostic 	}
12687a9d5071Sbostic       else if (j == margin - 1)
12697a9d5071Sbostic 	rstatus = MINLESS1;
12707a9d5071Sbostic       else
12717a9d5071Sbostic 	rstatus = ERRVAL;
12727a9d5071Sbostic     }
12737a9d5071Sbostic 
12747a9d5071Sbostic    return;
12757a9d5071Sbostic }
12767a9d5071Sbostic 
12777a9d5071Sbostic 
12787a9d5071Sbostic 
12797a9d5071Sbostic /*  Mulints multiplies two integer values  */
12807a9d5071Sbostic 
mulints(i,j)12817a9d5071Sbostic mulints(i, j)
12827a9d5071Sbostic register ftnint i, j;
12837a9d5071Sbostic {
12847a9d5071Sbostic   register ftnint sign;
12857a9d5071Sbostic   register ftnint margin;
12867a9d5071Sbostic 
12877a9d5071Sbostic   if (i == 0 || j == 0)
12887a9d5071Sbostic     {
12897a9d5071Sbostic       rstatus = NORMAL;
12907a9d5071Sbostic       rvalue = 0;
12917a9d5071Sbostic     }
12927a9d5071Sbostic   else
12937a9d5071Sbostic     {
12947a9d5071Sbostic       if ((i > 0 && j > 0) || (i < 0 && j < 0))
12957a9d5071Sbostic 	sign = 1;
12967a9d5071Sbostic       else
12977a9d5071Sbostic 	sign = -1;
12987a9d5071Sbostic 
12997a9d5071Sbostic       if (i < 0) i = -i;
13007a9d5071Sbostic       if (j < 0) j = -j;
13017a9d5071Sbostic 
13027a9d5071Sbostic       margin = MAXINT - i;
13037a9d5071Sbostic       margin = (margin + 1) / i;
13047a9d5071Sbostic 
13057a9d5071Sbostic       if (j <= margin)
13067a9d5071Sbostic 	{
13077a9d5071Sbostic 	  rstatus = NORMAL;
13087a9d5071Sbostic 	  rvalue = i * j * sign;
13097a9d5071Sbostic 	}
13107a9d5071Sbostic       else if (j - 1 == margin)
13117a9d5071Sbostic 	{
13127a9d5071Sbostic 	  margin = i*margin - 1;
13137a9d5071Sbostic 	  if (margin == MAXINT - i)
13147a9d5071Sbostic 	    if (sign > 0)
13157a9d5071Sbostic 	      rstatus = MAXPLUS1;
13167a9d5071Sbostic 	    else
13177a9d5071Sbostic 	      rstatus = MINLESS1;
13187a9d5071Sbostic 	  else
13197a9d5071Sbostic 	    {
13207a9d5071Sbostic 	      rstatus = NORMAL;
13217a9d5071Sbostic 	      rvalue = i * j * sign;
13227a9d5071Sbostic 	    }
13237a9d5071Sbostic 	}
13247a9d5071Sbostic       else
13257a9d5071Sbostic 	rstatus = ERRVAL;
13267a9d5071Sbostic     }
13277a9d5071Sbostic 
13287a9d5071Sbostic   return;
13297a9d5071Sbostic }
13307a9d5071Sbostic 
13317a9d5071Sbostic 
13327a9d5071Sbostic 
13337a9d5071Sbostic vexpr *
evalvexpr(ep)13347a9d5071Sbostic evalvexpr(ep)
13357a9d5071Sbostic vexpr *ep;
13367a9d5071Sbostic {
13377a9d5071Sbostic   register vexpr *p;
13387a9d5071Sbostic   register vexpr *l, *r;
13397a9d5071Sbostic 
13407a9d5071Sbostic   switch (ep->tag)
13417a9d5071Sbostic     {
13427a9d5071Sbostic     case DVALUE:
13437a9d5071Sbostic       p = cpdvalue(ep);
13447a9d5071Sbostic       break;
13457a9d5071Sbostic 
13467a9d5071Sbostic     case DVAR:
13477a9d5071Sbostic       p = cpdvalue((vexpr *) ep->dvar.valp);
13487a9d5071Sbostic       break;
13497a9d5071Sbostic 
13507a9d5071Sbostic     case DNAME:
13517a9d5071Sbostic       p = evaldname(ep);
13527a9d5071Sbostic       break;
13537a9d5071Sbostic 
13547a9d5071Sbostic     case DEXPR:
13557a9d5071Sbostic       if (ep->dexpr.left == NULL)
13567a9d5071Sbostic 	l = NULL;
13577a9d5071Sbostic       else
13587a9d5071Sbostic 	l = evalvexpr(ep->dexpr.left);
13597a9d5071Sbostic 
13607a9d5071Sbostic       if (ep->dexpr.right == NULL)
13617a9d5071Sbostic 	r = NULL;
13627a9d5071Sbostic       else
13637a9d5071Sbostic 	r = evalvexpr(ep->dexpr.right);
13647a9d5071Sbostic 
13657a9d5071Sbostic       switch (ep->dexpr.opcode)
13667a9d5071Sbostic 	{
13677a9d5071Sbostic 	case OPNEG:
13687a9d5071Sbostic 	  p = negival(r);
13697a9d5071Sbostic 	  break;
13707a9d5071Sbostic 
13717a9d5071Sbostic 	case OPPLUS:
13727a9d5071Sbostic 	  p = addivals(l, r);
13737a9d5071Sbostic 	  break;
13747a9d5071Sbostic 
13757a9d5071Sbostic 	case OPMINUS:
13767a9d5071Sbostic 	  p = subivals(l, r);
13777a9d5071Sbostic 	  break;
13787a9d5071Sbostic 
13797a9d5071Sbostic 	case OPSTAR:
13807a9d5071Sbostic 	  p = mulivals(l, r);
13817a9d5071Sbostic 	  break;
13827a9d5071Sbostic 
13837a9d5071Sbostic 	case OPSLASH:
13847a9d5071Sbostic 	  p = divivals(l, r);
13857a9d5071Sbostic 	  break;
13867a9d5071Sbostic 
13877a9d5071Sbostic 	case OPPOWER:
13887a9d5071Sbostic 	  p = powivals(l, r);
13897a9d5071Sbostic 	  break;
13907a9d5071Sbostic 	}
13917a9d5071Sbostic 
13927a9d5071Sbostic       frvexpr(l);
13937a9d5071Sbostic       frvexpr(r);
13947a9d5071Sbostic       break;
13957a9d5071Sbostic 
13967a9d5071Sbostic     case DERROR:
13977a9d5071Sbostic       p = (vexpr *) ALLOC(Dvalue);
13987a9d5071Sbostic       p->tag = DVALUE;
13997a9d5071Sbostic       p->dvalue.status = ERRVAL;
14007a9d5071Sbostic       break;
14017a9d5071Sbostic     }
14027a9d5071Sbostic 
14037a9d5071Sbostic   return (p);
14047a9d5071Sbostic }
14057a9d5071Sbostic 
14067a9d5071Sbostic 
14077a9d5071Sbostic 
14087a9d5071Sbostic vexpr *
refrigdname(vp)14097a9d5071Sbostic refrigdname(vp)
14107a9d5071Sbostic vexpr *vp;
14117a9d5071Sbostic {
14127a9d5071Sbostic   register vexpr *p;
14137a9d5071Sbostic   register int len;
14147a9d5071Sbostic   register char *repr;
14157a9d5071Sbostic   register int found;
14167a9d5071Sbostic   register dovars *dvp;
14177a9d5071Sbostic 
14187a9d5071Sbostic   len = vp->dname.len;
14197a9d5071Sbostic   repr = vp->dname.repr;
14207a9d5071Sbostic 
14217a9d5071Sbostic   found = NO;
14227a9d5071Sbostic   dvp = dvlist;
14237a9d5071Sbostic   while (found == NO && dvp != NULL)
14247a9d5071Sbostic     {
14257a9d5071Sbostic       if (len == dvp->len && eqn(len, repr, dvp->repr))
14267a9d5071Sbostic 	found = YES;
14277a9d5071Sbostic       else
14287a9d5071Sbostic 	dvp = dvp->next;
14297a9d5071Sbostic     }
14307a9d5071Sbostic 
14317a9d5071Sbostic   if (found == YES)
14327a9d5071Sbostic     {
14337a9d5071Sbostic       p = (vexpr *) ALLOC(Dvar);
14347a9d5071Sbostic       p->tag = DVAR;
14357a9d5071Sbostic       p->dvar.valp = dvp->valp;
14367a9d5071Sbostic     }
14377a9d5071Sbostic   else
14387a9d5071Sbostic     {
14397a9d5071Sbostic       p = evaldname(vp);
14407a9d5071Sbostic       if (p->dvalue.status == ERRVAL)
14417a9d5071Sbostic 	dataerror = YES;
14427a9d5071Sbostic     }
14437a9d5071Sbostic 
14447a9d5071Sbostic   return (p);
14457a9d5071Sbostic }
14467a9d5071Sbostic 
14477a9d5071Sbostic 
14487a9d5071Sbostic 
refrigvexpr(vpp)14497a9d5071Sbostic refrigvexpr(vpp)
14507a9d5071Sbostic vexpr **vpp;
14517a9d5071Sbostic {
14527a9d5071Sbostic   register vexpr *vp;
14537a9d5071Sbostic 
14547a9d5071Sbostic   vp = *vpp;
14557a9d5071Sbostic 
14567a9d5071Sbostic   switch (vp->tag)
14577a9d5071Sbostic     {
14587a9d5071Sbostic     case DVALUE:
14597a9d5071Sbostic     case DVAR:
14607a9d5071Sbostic     case DERROR:
14617a9d5071Sbostic       break;
14627a9d5071Sbostic 
14637a9d5071Sbostic     case DEXPR:
14647a9d5071Sbostic       refrigvexpr( &(vp->dexpr.left) );
14657a9d5071Sbostic       refrigvexpr( &(vp->dexpr.right) );
14667a9d5071Sbostic       break;
14677a9d5071Sbostic 
14687a9d5071Sbostic     case DNAME:
14697a9d5071Sbostic       *(vpp) = refrigdname(vp);
14707a9d5071Sbostic       frvexpr(vp);
14717a9d5071Sbostic       break;
14727a9d5071Sbostic     }
14737a9d5071Sbostic 
14747a9d5071Sbostic   return;
14757a9d5071Sbostic }
14767a9d5071Sbostic 
14777a9d5071Sbostic 
14787a9d5071Sbostic 
14797a9d5071Sbostic int
chkvar(np,sname)14807a9d5071Sbostic chkvar(np, sname)
14817a9d5071Sbostic Namep np;
14827a9d5071Sbostic char *sname;
14837a9d5071Sbostic {
14847a9d5071Sbostic   static char *nonvar = "%s is not a variable";
14857a9d5071Sbostic   static char *arginit = "attempt to initialize a dummy argument: %s";
14867a9d5071Sbostic   static char *autoinit = "attempt to initialize an automatic variable: %s";
14877a9d5071Sbostic   static char *badclass = "bad class in chkvar";
14887a9d5071Sbostic 
14897a9d5071Sbostic   register int status;
14907a9d5071Sbostic   register struct Dimblock *dp;
14917a9d5071Sbostic   register int i;
14927a9d5071Sbostic 
14937a9d5071Sbostic   status = YES;
14947a9d5071Sbostic 
14957a9d5071Sbostic   if (np->vclass == CLUNKNOWN
14967a9d5071Sbostic       || (np->vclass == CLVAR && !np->vdcldone))
14977a9d5071Sbostic     vardcl(np);
14987a9d5071Sbostic 
14997a9d5071Sbostic   if (np->vstg == STGARG)
15007a9d5071Sbostic     {
15017a9d5071Sbostic       errstr(arginit, sname);
15027a9d5071Sbostic       dataerror = YES;
15037a9d5071Sbostic       status = NO;
15047a9d5071Sbostic     }
15057a9d5071Sbostic   else if (np->vclass != CLVAR)
15067a9d5071Sbostic     {
15077a9d5071Sbostic       errstr(nonvar, sname);
15087a9d5071Sbostic       dataerror = YES;
15097a9d5071Sbostic       status = NO;
15107a9d5071Sbostic     }
15117a9d5071Sbostic   else if (np->vstg == STGAUTO)
15127a9d5071Sbostic     {
15137a9d5071Sbostic       errstr(autoinit, sname);
15147a9d5071Sbostic       dataerror = YES;
15157a9d5071Sbostic       status = NO;
15167a9d5071Sbostic     }
15177a9d5071Sbostic   else if (np->vstg != STGBSS && np->vstg != STGINIT
15187a9d5071Sbostic 	    && np->vstg != STGCOMMON && np->vstg != STGEQUIV)
15197a9d5071Sbostic     {
15207a9d5071Sbostic       fatal(badclass);
15217a9d5071Sbostic     }
15227a9d5071Sbostic   else
15237a9d5071Sbostic     {
15247a9d5071Sbostic       switch (np->vtype)
15257a9d5071Sbostic 	{
15267a9d5071Sbostic 	case TYERROR:
15277a9d5071Sbostic 	  status = NO;
15287a9d5071Sbostic 	  dataerror = YES;
15297a9d5071Sbostic 	  break;
15307a9d5071Sbostic 
15317a9d5071Sbostic 	case TYSHORT:
15327a9d5071Sbostic 	case TYLONG:
15337a9d5071Sbostic 	case TYREAL:
15347a9d5071Sbostic 	case TYDREAL:
15357a9d5071Sbostic 	case TYCOMPLEX:
15367a9d5071Sbostic 	case TYDCOMPLEX:
15377a9d5071Sbostic 	case TYLOGICAL:
15387a9d5071Sbostic 	case TYCHAR:
15397a9d5071Sbostic 	  dp = np->vdim;
15407a9d5071Sbostic 	  if (dp != NULL)
15417a9d5071Sbostic 	    {
15427a9d5071Sbostic 	      if (dp->nelt == NULL || !ISICON(dp->nelt))
15437a9d5071Sbostic 	        {
15447a9d5071Sbostic 	          status = NO;
15457a9d5071Sbostic 	          dataerror = YES;
15467a9d5071Sbostic 	        }
15477a9d5071Sbostic 	    }
15487a9d5071Sbostic 	  break;
15497a9d5071Sbostic 
15507a9d5071Sbostic 	default:
15517a9d5071Sbostic 	  badtype("chkvar", np->vtype);
15527a9d5071Sbostic 	}
15537a9d5071Sbostic     }
15547a9d5071Sbostic 
15557a9d5071Sbostic   return (status);
15567a9d5071Sbostic }
15577a9d5071Sbostic 
15587a9d5071Sbostic 
15597a9d5071Sbostic 
refrigsubs(ap,sname)15607a9d5071Sbostic refrigsubs(ap, sname)
15617a9d5071Sbostic aelt *ap;
15627a9d5071Sbostic char *sname;
15637a9d5071Sbostic {
15647a9d5071Sbostic   static char *nonarray = "subscripts on a simple variable:  %s";
15657a9d5071Sbostic   static char *toofew = "not enough subscripts on %s";
15667a9d5071Sbostic   static char *toomany = "too many subscripts on %s";
15677a9d5071Sbostic 
15687a9d5071Sbostic   register vlist *subp;
15697a9d5071Sbostic   register int nsubs;
15707a9d5071Sbostic   register Namep np;
15717a9d5071Sbostic   register struct Dimblock *dp;
15727a9d5071Sbostic   register int i;
15737a9d5071Sbostic 
15747a9d5071Sbostic   np = ap->var;
15757a9d5071Sbostic   dp = np->vdim;
15767a9d5071Sbostic 
15777a9d5071Sbostic   if (ap->subs != NULL)
15787a9d5071Sbostic     {
15797a9d5071Sbostic       if (np->vdim == NULL)
15807a9d5071Sbostic 	{
15817a9d5071Sbostic 	  errstr(nonarray, sname);
15827a9d5071Sbostic 	  dataerror = YES;
15837a9d5071Sbostic 	}
15847a9d5071Sbostic       else
15857a9d5071Sbostic 	{
15867a9d5071Sbostic 	  nsubs = 0;
15877a9d5071Sbostic 	  subp = ap->subs;
15887a9d5071Sbostic 	  while (subp != NULL)
15897a9d5071Sbostic 	    {
15907a9d5071Sbostic 	      nsubs++;
15917a9d5071Sbostic 	      refrigvexpr( &(subp->val) );
15927a9d5071Sbostic 	      subp = subp->next;
15937a9d5071Sbostic 	    }
15947a9d5071Sbostic 
15957a9d5071Sbostic 	  if (dp->ndim != nsubs)
15967a9d5071Sbostic 	    {
15977a9d5071Sbostic 	      if (np->vdim->ndim > nsubs)
15987a9d5071Sbostic 		errstr(toofew, sname);
15997a9d5071Sbostic 	      else
16007a9d5071Sbostic 		errstr(toomany, sname);
16017a9d5071Sbostic 	      dataerror = YES;
16027a9d5071Sbostic 	    }
16037a9d5071Sbostic 	  else if (dp->baseoffset == NULL || !ISICON(dp->baseoffset))
16047a9d5071Sbostic 	    dataerror = YES;
16057a9d5071Sbostic 	  else
16067a9d5071Sbostic 	    {
16077a9d5071Sbostic 	      i = dp->ndim;
16087a9d5071Sbostic 	      while (i-- > 0)
16097a9d5071Sbostic 		{
16107a9d5071Sbostic 		  if (dp->dims[i].dimsize == NULL
16117a9d5071Sbostic 		      || !ISICON(dp->dims[i].dimsize))
16127a9d5071Sbostic 		    dataerror = YES;
16137a9d5071Sbostic 		}
16147a9d5071Sbostic 	    }
16157a9d5071Sbostic 	}
16167a9d5071Sbostic     }
16177a9d5071Sbostic 
16187a9d5071Sbostic   return;
16197a9d5071Sbostic }
16207a9d5071Sbostic 
16217a9d5071Sbostic 
16227a9d5071Sbostic 
refrigrange(ap,sname)16237a9d5071Sbostic refrigrange(ap, sname)
16247a9d5071Sbostic aelt *ap;
16257a9d5071Sbostic char *sname;
16267a9d5071Sbostic {
16277a9d5071Sbostic   static char *nonstr = "substring of a noncharacter variable:  %s";
16287a9d5071Sbostic   static char *array = "substring applied to an array:  %s";
16297a9d5071Sbostic 
16307a9d5071Sbostic   register Namep np;
16317a9d5071Sbostic   register dvalue *t;
16327a9d5071Sbostic   register rpair *rp;
16337a9d5071Sbostic 
16347a9d5071Sbostic   if (ap->range != NULL)
16357a9d5071Sbostic     {
16367a9d5071Sbostic       np = ap->var;
16377a9d5071Sbostic       if (np->vtype != TYCHAR)
16387a9d5071Sbostic 	{
16397a9d5071Sbostic 	  errstr(nonstr, sname);
16407a9d5071Sbostic 	  dataerror = YES;
16417a9d5071Sbostic 	}
16427a9d5071Sbostic       else if (ap->subs == NULL && np->vdim != NULL)
16437a9d5071Sbostic 	{
16447a9d5071Sbostic 	  errstr(array, sname);
16457a9d5071Sbostic 	  dataerror = YES;
16467a9d5071Sbostic 	}
16477a9d5071Sbostic       else
16487a9d5071Sbostic 	{
16497a9d5071Sbostic 	  rp = ap->range;
16507a9d5071Sbostic 
16517a9d5071Sbostic 	  if (rp->low != NULL)
16527a9d5071Sbostic 	    refrigvexpr( &(rp->low) );
16537a9d5071Sbostic 	  else
16547a9d5071Sbostic 	    {
16557a9d5071Sbostic 	      t = ALLOC(Dvalue);
16567a9d5071Sbostic 	      t->tag = DVALUE;
16577a9d5071Sbostic 	      t->status = NORMAL;
16587a9d5071Sbostic 	      t->value = 1;
16597a9d5071Sbostic 	      rp->low = (vexpr *) t;
16607a9d5071Sbostic 	    }
16617a9d5071Sbostic 
16627a9d5071Sbostic 	  if (rp->high != NULL)
16637a9d5071Sbostic 	    refrigvexpr( &(rp->high) );
16647a9d5071Sbostic 	  else
16657a9d5071Sbostic 	    {
16667a9d5071Sbostic 	      if (!ISICON(np->vleng))
16677a9d5071Sbostic 		{
16687a9d5071Sbostic 		  rp->high = (vexpr *) ALLOC(Derror);
16697a9d5071Sbostic 		  rp->high->tag = DERROR;
16707a9d5071Sbostic 		}
16717a9d5071Sbostic 	      else
16727a9d5071Sbostic 		{
16737a9d5071Sbostic 		  t = ALLOC(Dvalue);
16747a9d5071Sbostic 		  t->tag = DVALUE;
16757a9d5071Sbostic 		  t->status = NORMAL;
1676ee554660Sbostic 		  t->value = np->vleng->constblock.constant.ci;
16777a9d5071Sbostic 		  rp->high = (vexpr *) t;
16787a9d5071Sbostic 		}
16797a9d5071Sbostic 	    }
16807a9d5071Sbostic 	}
16817a9d5071Sbostic     }
16827a9d5071Sbostic 
16837a9d5071Sbostic   return;
16847a9d5071Sbostic }
16857a9d5071Sbostic 
16867a9d5071Sbostic 
16877a9d5071Sbostic 
refrigaelt(ap)16887a9d5071Sbostic refrigaelt(ap)
16897a9d5071Sbostic aelt *ap;
16907a9d5071Sbostic {
16917a9d5071Sbostic   register Namep np;
16927a9d5071Sbostic   register char *bp, *sp;
16937a9d5071Sbostic   register int len;
16947a9d5071Sbostic   char buff[VL+1];
16957a9d5071Sbostic 
16967a9d5071Sbostic   np = ap->var;
16977a9d5071Sbostic 
16987a9d5071Sbostic   len = 0;
16997a9d5071Sbostic   bp = buff;
17007a9d5071Sbostic   sp = np->varname;
17017a9d5071Sbostic   while (len < VL && *sp != ' ' && *sp != '\0')
17027a9d5071Sbostic     {
17037a9d5071Sbostic       *bp++ = *sp++;
17047a9d5071Sbostic       len++;
17057a9d5071Sbostic     }
17067a9d5071Sbostic   *bp = '\0';
17077a9d5071Sbostic 
17087a9d5071Sbostic   if (chkvar(np, buff))
17097a9d5071Sbostic     {
17107a9d5071Sbostic       refrigsubs(ap, buff);
17117a9d5071Sbostic       refrigrange(ap, buff);
17127a9d5071Sbostic     }
17137a9d5071Sbostic 
17147a9d5071Sbostic   return;
17157a9d5071Sbostic }
17167a9d5071Sbostic 
17177a9d5071Sbostic 
17187a9d5071Sbostic 
refrigdo(dp)17197a9d5071Sbostic refrigdo(dp)
17207a9d5071Sbostic dolist *dp;
17217a9d5071Sbostic {
17227a9d5071Sbostic   static char *duplicates = "implied DO variable %s redefined";
17237a9d5071Sbostic   static char *nonvar = "%s is not a variable";
17247a9d5071Sbostic   static char *nonint = "%s is not integer";
17257a9d5071Sbostic 
17267a9d5071Sbostic   register int len;
17277a9d5071Sbostic   register char *repr;
17287a9d5071Sbostic   register int found;
17297a9d5071Sbostic   register dovars *dvp;
17307a9d5071Sbostic   register Namep np;
17317a9d5071Sbostic   register dovars *t;
17327a9d5071Sbostic 
17337a9d5071Sbostic   refrigvexpr( &(dp->init) );
17347a9d5071Sbostic   refrigvexpr( &(dp->limit) );
17357a9d5071Sbostic   refrigvexpr( &(dp->step) );
17367a9d5071Sbostic 
17377a9d5071Sbostic   len = dp->dovar->dname.len;
17387a9d5071Sbostic   repr = dp->dovar->dname.repr;
17397a9d5071Sbostic 
17407a9d5071Sbostic   found = NO;
17417a9d5071Sbostic   dvp = dvlist;
17427a9d5071Sbostic   while (found == NO && dvp != NULL)
17437a9d5071Sbostic     if (len == dvp->len && eqn(len, repr, dvp->repr))
17447a9d5071Sbostic       found = YES;
17457a9d5071Sbostic     else
17467a9d5071Sbostic       dvp = dvp->next;
17477a9d5071Sbostic 
17487a9d5071Sbostic   if (found == YES)
17497a9d5071Sbostic     {
17507a9d5071Sbostic       errnm(duplicates, len, repr);
17517a9d5071Sbostic       dataerror = YES;
17527a9d5071Sbostic     }
17537a9d5071Sbostic   else
17547a9d5071Sbostic     {
17557a9d5071Sbostic       np = getname(len, repr);
17567a9d5071Sbostic       if (np == NULL)
17577a9d5071Sbostic 	{
17587a9d5071Sbostic 	  if (!ISINT(impltype[letter(*repr)]))
17597a9d5071Sbostic 	    warnnm(nonint, len, repr);
17607a9d5071Sbostic 	}
17617a9d5071Sbostic       else
17627a9d5071Sbostic 	{
17637a9d5071Sbostic 	  if (np->vclass == CLUNKNOWN)
17647a9d5071Sbostic 	    vardcl(np);
17657a9d5071Sbostic 	  if (np->vclass != CLVAR)
17667a9d5071Sbostic 	    warnnm(nonvar, len, repr);
17677a9d5071Sbostic 	  else if (!ISINT(np->vtype))
17687a9d5071Sbostic 	    warnnm(nonint, len, repr);
17697a9d5071Sbostic 	}
17707a9d5071Sbostic     }
17717a9d5071Sbostic 
17727a9d5071Sbostic   t = ALLOC(DoVars);
17737a9d5071Sbostic   t->next = dvlist;
17747a9d5071Sbostic   t->len = len;
17757a9d5071Sbostic   t->repr = repr;
17767a9d5071Sbostic   t->valp = ALLOC(Dvalue);
17777a9d5071Sbostic   t->valp->tag = DVALUE;
17787a9d5071Sbostic   dp->dovar = (vexpr *) t->valp;
17797a9d5071Sbostic 
17807a9d5071Sbostic   dvlist = t;
17817a9d5071Sbostic 
17827a9d5071Sbostic   refriglvals(dp->elts);
17837a9d5071Sbostic 
17847a9d5071Sbostic   dvlist = t->next;
17857a9d5071Sbostic   free((char *) t);
17867a9d5071Sbostic 
17877a9d5071Sbostic   return;
17887a9d5071Sbostic }
17897a9d5071Sbostic 
17907a9d5071Sbostic 
17917a9d5071Sbostic 
refriglvals(lvals)17927a9d5071Sbostic refriglvals(lvals)
17937a9d5071Sbostic elist *lvals;
17947a9d5071Sbostic {
17957a9d5071Sbostic   register elist *top;
17967a9d5071Sbostic 
17977a9d5071Sbostic   top = lvals;
17987a9d5071Sbostic 
17997a9d5071Sbostic   while (top != NULL)
18007a9d5071Sbostic     {
18017a9d5071Sbostic       if (top->elt->tag == SIMPLE)
18027a9d5071Sbostic 	refrigaelt((aelt *) top->elt);
18037a9d5071Sbostic       else
18047a9d5071Sbostic 	refrigdo((dolist *) top->elt);
18057a9d5071Sbostic 
18067a9d5071Sbostic       top = top->next;
18077a9d5071Sbostic     }
18087a9d5071Sbostic 
18097a9d5071Sbostic   return;
18107a9d5071Sbostic }
18117a9d5071Sbostic 
18127a9d5071Sbostic 
18137a9d5071Sbostic 
18147a9d5071Sbostic /*  Refrig freezes name/value bindings in the DATA name list  */
18157a9d5071Sbostic 
18167a9d5071Sbostic 
refrig(lvals)18177a9d5071Sbostic refrig(lvals)
18187a9d5071Sbostic elist *lvals;
18197a9d5071Sbostic {
18207a9d5071Sbostic   dvlist = NULL;
18217a9d5071Sbostic   refriglvals(lvals);
18227a9d5071Sbostic   return;
18237a9d5071Sbostic }
18247a9d5071Sbostic 
18257a9d5071Sbostic 
18267a9d5071Sbostic 
18277a9d5071Sbostic ftnint
indexer(ap)18287a9d5071Sbostic indexer(ap)
18297a9d5071Sbostic aelt *ap;
18307a9d5071Sbostic {
18317a9d5071Sbostic   static char *badvar = "bad variable in indexer";
18327a9d5071Sbostic   static char *boundserror = "subscript out of bounds";
18337a9d5071Sbostic 
18347a9d5071Sbostic   register ftnint index;
18357a9d5071Sbostic   register vlist *sp;
18367a9d5071Sbostic   register Namep np;
18377a9d5071Sbostic   register struct Dimblock *dp;
18387a9d5071Sbostic   register int i;
18397a9d5071Sbostic   register dvalue *vp;
18407a9d5071Sbostic   register ftnint size;
18417a9d5071Sbostic   ftnint sub[MAXDIM];
18427a9d5071Sbostic 
18437a9d5071Sbostic   sp = ap->subs;
18447a9d5071Sbostic   if (sp == NULL) return (0);
18457a9d5071Sbostic 
18467a9d5071Sbostic   np = ap->var;
18477a9d5071Sbostic   dp = np->vdim;
18487a9d5071Sbostic 
18497a9d5071Sbostic   if (dp == NULL)
18507a9d5071Sbostic     fatal(badvar);
18517a9d5071Sbostic 
18527a9d5071Sbostic   i = 0;
18537a9d5071Sbostic   while (sp != NULL)
18547a9d5071Sbostic     {
18557a9d5071Sbostic       vp = (dvalue *) evalvexpr(sp->val);
18567a9d5071Sbostic 
18577a9d5071Sbostic       if (vp->status == NORMAL)
18587a9d5071Sbostic 	sub[i++] = vp->value;
18597a9d5071Sbostic       else if ((MININT + MAXINT == -1) && vp->status == MINLESS1)
18607a9d5071Sbostic 	sub[i++] = MININT;
18617a9d5071Sbostic       else
18627a9d5071Sbostic 	{
18637a9d5071Sbostic 	  frvexpr((vexpr *) vp);
18647a9d5071Sbostic 	  return (-1);
18657a9d5071Sbostic 	}
18667a9d5071Sbostic 
18677a9d5071Sbostic       frvexpr((vexpr *) vp);
18687a9d5071Sbostic       sp = sp->next;
18697a9d5071Sbostic     }
18707a9d5071Sbostic 
18717a9d5071Sbostic   index = sub[--i];
18727a9d5071Sbostic   while (i-- > 0)
18737a9d5071Sbostic     {
1874ee554660Sbostic       size = dp->dims[i].dimsize->constblock.constant.ci;
18757a9d5071Sbostic       index = sub[i] + index * size;
18767a9d5071Sbostic     }
18777a9d5071Sbostic 
1878ee554660Sbostic   index -= dp->baseoffset->constblock.constant.ci;
18797a9d5071Sbostic 
1880ee554660Sbostic   if (index < 0 || index >= dp->nelt->constblock.constant.ci)
18817a9d5071Sbostic     {
18827a9d5071Sbostic       err(boundserror);
18837a9d5071Sbostic       return (-1);
18847a9d5071Sbostic     }
18857a9d5071Sbostic 
18867a9d5071Sbostic   return (index);
18877a9d5071Sbostic }
18887a9d5071Sbostic 
18897a9d5071Sbostic 
18907a9d5071Sbostic 
savedata(lvals,rvals)18917a9d5071Sbostic savedata(lvals, rvals)
18927a9d5071Sbostic elist *lvals;
18937a9d5071Sbostic vallist *rvals;
18947a9d5071Sbostic {
18957a9d5071Sbostic   static char *toomany = "more data values than data items";
18967a9d5071Sbostic 
18977a9d5071Sbostic   register elist *top;
18987a9d5071Sbostic 
18997a9d5071Sbostic   dataerror = NO;
19007a9d5071Sbostic   badvalue = NO;
19017a9d5071Sbostic 
19027a9d5071Sbostic   lvals = revelist(lvals);
19037a9d5071Sbostic   grvals = revrvals(rvals);
19047a9d5071Sbostic 
19057a9d5071Sbostic   refrig(lvals);
19067a9d5071Sbostic 
19077a9d5071Sbostic   if (!dataerror)
19087a9d5071Sbostic     outdata(lvals);
19097a9d5071Sbostic 
19107a9d5071Sbostic   frelist(lvals);
19117a9d5071Sbostic 
19127a9d5071Sbostic   while (grvals != NULL && dataerror == NO)
19137a9d5071Sbostic     {
19147a9d5071Sbostic       if (grvals->status != NORMAL)
19157a9d5071Sbostic 	dataerror = YES;
19167a9d5071Sbostic       else if (grvals->repl <= 0)
19177a9d5071Sbostic         grvals = grvals->next;
19187a9d5071Sbostic       else
19197a9d5071Sbostic 	{
19207a9d5071Sbostic 	  err(toomany);
19217a9d5071Sbostic 	  dataerror = YES;
19227a9d5071Sbostic 	}
19237a9d5071Sbostic     }
19247a9d5071Sbostic 
19257a9d5071Sbostic   frvallist(grvals);
19267a9d5071Sbostic 
19277a9d5071Sbostic   return;
19287a9d5071Sbostic }
19297a9d5071Sbostic 
19307a9d5071Sbostic 
19317a9d5071Sbostic 
setdfiles(np)19327a9d5071Sbostic setdfiles(np)
19337a9d5071Sbostic register Namep np;
19347a9d5071Sbostic {
19357a9d5071Sbostic   register struct Extsym *cp;
19367a9d5071Sbostic   register struct Equivblock *ep;
19377a9d5071Sbostic   register int stg;
19387a9d5071Sbostic   register int type;
19397a9d5071Sbostic   register ftnint typelen;
19407a9d5071Sbostic   register ftnint nelt;
19417a9d5071Sbostic   register ftnint varsize;
19427a9d5071Sbostic 
19437a9d5071Sbostic   stg = np->vstg;
19447a9d5071Sbostic 
19457a9d5071Sbostic   if (stg == STGBSS || stg == STGINIT)
19467a9d5071Sbostic     {
19477a9d5071Sbostic       datafile = vdatafile;
19487a9d5071Sbostic       chkfile = vchkfile;
19497a9d5071Sbostic       if (np->init == YES)
19507a9d5071Sbostic 	base = np->initoffset;
19517a9d5071Sbostic       else
19527a9d5071Sbostic 	{
19537a9d5071Sbostic 	  np->init = YES;
19547a9d5071Sbostic 	  np->initoffset = base = vdatahwm;
19557a9d5071Sbostic 	  if (np->vdim != NULL)
1956ee554660Sbostic 	    nelt = np->vdim->nelt->constblock.constant.ci;
19577a9d5071Sbostic 	  else
19587a9d5071Sbostic 	    nelt = 1;
19597a9d5071Sbostic 	  type = np->vtype;
19607a9d5071Sbostic 	  if (type == TYCHAR)
1961ee554660Sbostic 	    typelen = np->vleng->constblock.constant.ci;
19627a9d5071Sbostic 	  else if (type == TYLOGICAL)
19637a9d5071Sbostic 	    typelen = typesize[tylogical];
19647a9d5071Sbostic 	  else
19657a9d5071Sbostic 	    typelen = typesize[type];
19667a9d5071Sbostic 	  varsize = nelt * typelen;
19677a9d5071Sbostic 	  vdatahwm += varsize;
19687a9d5071Sbostic 	}
19697a9d5071Sbostic     }
19707a9d5071Sbostic   else if (stg == STGEQUIV)
19717a9d5071Sbostic     {
19727a9d5071Sbostic       datafile = vdatafile;
19737a9d5071Sbostic       chkfile = vchkfile;
19747a9d5071Sbostic       ep = &eqvclass[np->vardesc.varno];
19757a9d5071Sbostic       if (ep->init == YES)
19767a9d5071Sbostic 	base = ep->initoffset;
19777a9d5071Sbostic       else
19787a9d5071Sbostic 	{
19797a9d5071Sbostic 	  ep->init = YES;
19807a9d5071Sbostic 	  ep->initoffset = base = vdatahwm;
19817a9d5071Sbostic 	  vdatahwm += ep->eqvleng;
19827a9d5071Sbostic 	}
19837a9d5071Sbostic       base += np->voffset;
19847a9d5071Sbostic     }
19857a9d5071Sbostic   else if (stg == STGCOMMON)
19867a9d5071Sbostic     {
19877a9d5071Sbostic       datafile = cdatafile;
19887a9d5071Sbostic       chkfile = cchkfile;
19897a9d5071Sbostic       cp = &extsymtab[np->vardesc.varno];
19907a9d5071Sbostic       if (cp->init == YES)
19917a9d5071Sbostic 	base = cp->initoffset;
19927a9d5071Sbostic       else
19937a9d5071Sbostic 	{
19947a9d5071Sbostic 	  cp->init = YES;
19957a9d5071Sbostic 	  cp->initoffset = base = cdatahwm;
19967a9d5071Sbostic 	  cdatahwm += cp->maxleng;
19977a9d5071Sbostic 	}
19987a9d5071Sbostic       base += np->voffset;
19997a9d5071Sbostic     }
20007a9d5071Sbostic 
20017a9d5071Sbostic   return;
20027a9d5071Sbostic }
20037a9d5071Sbostic 
20047a9d5071Sbostic 
20057a9d5071Sbostic 
wrtdata(offset,repl,len,constant)2006ee554660Sbostic wrtdata(offset, repl, len, constant)
20077a9d5071Sbostic long offset;
20087a9d5071Sbostic ftnint repl;
20097a9d5071Sbostic ftnint len;
2010ee554660Sbostic char *constant;
20117a9d5071Sbostic {
20127a9d5071Sbostic   static char *badoffset = "bad offset in wrtdata";
20137a9d5071Sbostic   static char *toomuch = "too much data";
20147a9d5071Sbostic   static char *readerror = "read error on tmp file";
20157a9d5071Sbostic   static char *writeerror = "write error on tmp file";
20167a9d5071Sbostic   static char *seekerror = "seek error on tmp file";
20177a9d5071Sbostic 
20187a9d5071Sbostic   register ftnint k;
20197a9d5071Sbostic   long lastbyte;
20207a9d5071Sbostic   int bitpos;
20217a9d5071Sbostic   long chkoff;
20227a9d5071Sbostic   long lastoff;
20237a9d5071Sbostic   long chklen;
20247a9d5071Sbostic   long pos;
20257a9d5071Sbostic   int n;
20267a9d5071Sbostic   ftnint nbytes;
20277a9d5071Sbostic   int mask;
20287a9d5071Sbostic   register int i;
20297a9d5071Sbostic   char overlap;
20307a9d5071Sbostic   char allzero;
20317a9d5071Sbostic   char buff[BUFSIZ];
20327a9d5071Sbostic 
20337a9d5071Sbostic   if (offset < 0)
20347a9d5071Sbostic     fatal(badoffset);
20357a9d5071Sbostic 
20367a9d5071Sbostic   overlap = NO;
20377a9d5071Sbostic 
20387a9d5071Sbostic   k = repl * len;
20397a9d5071Sbostic   lastbyte = offset + k - 1;
20407a9d5071Sbostic   if (lastbyte < 0)
20417a9d5071Sbostic     {
20427a9d5071Sbostic       err(toomuch);
20437a9d5071Sbostic       dataerror = YES;
20447a9d5071Sbostic       return;
20457a9d5071Sbostic     }
20467a9d5071Sbostic 
20477a9d5071Sbostic   bitpos = offset % BYTESIZE;
20487a9d5071Sbostic   chkoff = offset/BYTESIZE;
20497a9d5071Sbostic   lastoff = lastbyte/BYTESIZE;
20507a9d5071Sbostic   chklen = lastoff - chkoff + 1;
20517a9d5071Sbostic 
20527a9d5071Sbostic   pos = lseek(chkfile, chkoff, 0);
20537a9d5071Sbostic   if (pos == -1)
20547a9d5071Sbostic     {
20557a9d5071Sbostic       err(seekerror);
20567a9d5071Sbostic       done(1);
20577a9d5071Sbostic     }
20587a9d5071Sbostic 
20597a9d5071Sbostic   while (k > 0)
20607a9d5071Sbostic     {
20617a9d5071Sbostic       if (chklen <= BUFSIZ)
20627a9d5071Sbostic 	n = chklen;
20637a9d5071Sbostic       else
20647a9d5071Sbostic 	{
20657a9d5071Sbostic 	  n = BUFSIZ;
20667a9d5071Sbostic 	  chklen -= BUFSIZ;
20677a9d5071Sbostic 	}
20687a9d5071Sbostic 
20697a9d5071Sbostic       nbytes = read(chkfile, buff, n);
20707a9d5071Sbostic       if (nbytes < 0)
20717a9d5071Sbostic 	{
20727a9d5071Sbostic 	  err(readerror);
20737a9d5071Sbostic 	  done(1);
20747a9d5071Sbostic 	}
20757a9d5071Sbostic 
20767a9d5071Sbostic       if (nbytes == 0)
20777a9d5071Sbostic 	buff[0] = '\0';
20787a9d5071Sbostic 
20797a9d5071Sbostic       if (nbytes < n)
20807a9d5071Sbostic 	buff[ n-1 ] = '\0';
20817a9d5071Sbostic 
20827a9d5071Sbostic       i = 0;
20837a9d5071Sbostic 
20847a9d5071Sbostic       if (bitpos > 0)
20857a9d5071Sbostic 	{
20867a9d5071Sbostic 	  while (k > 0 && bitpos < BYTESIZE)
20877a9d5071Sbostic 	    {
20887a9d5071Sbostic 	      mask = 1 << bitpos;
20897a9d5071Sbostic 
20907a9d5071Sbostic 	      if (mask & buff[0])
20917a9d5071Sbostic 		overlap = YES;
20927a9d5071Sbostic 	      else
20937a9d5071Sbostic 		buff[0] |= mask;
20947a9d5071Sbostic 
20957a9d5071Sbostic 	      k--;
20967a9d5071Sbostic 	      bitpos++;
20977a9d5071Sbostic 	    }
20987a9d5071Sbostic 
20997a9d5071Sbostic 	  if (bitpos == BYTESIZE)
21007a9d5071Sbostic 	    {
21017a9d5071Sbostic 	      bitpos = 0;
21027a9d5071Sbostic 	      i++;
21037a9d5071Sbostic 	    }
21047a9d5071Sbostic 	}
21057a9d5071Sbostic 
21067a9d5071Sbostic       while (i < nbytes && overlap == NO)
21077a9d5071Sbostic 	{
21087a9d5071Sbostic 	  if (buff[i] == 0 && k >= BYTESIZE)
21097a9d5071Sbostic 	    {
21107a9d5071Sbostic 	      buff[i++] = MAXBYTE;
21117a9d5071Sbostic 	      k -= BYTESIZE;
21127a9d5071Sbostic 	    }
21137a9d5071Sbostic 	  else if (k < BYTESIZE)
21147a9d5071Sbostic 	    {
21157a9d5071Sbostic 	      while (k-- > 0)
21167a9d5071Sbostic 		{
21177a9d5071Sbostic 		  mask = 1 << k;
21187a9d5071Sbostic 		  if (mask & buff[i])
21197a9d5071Sbostic 		    overlap = YES;
21207a9d5071Sbostic 		  else
21217a9d5071Sbostic 		    buff[i] |= mask;
21227a9d5071Sbostic 		}
21237a9d5071Sbostic 	      i++;
21247a9d5071Sbostic 	    }
21257a9d5071Sbostic 	  else
21267a9d5071Sbostic 	    {
21277a9d5071Sbostic 	      overlap = YES;
21287a9d5071Sbostic 	      buff[i++] = MAXBYTE;
21297a9d5071Sbostic 	      k -= BYTESIZE;
21307a9d5071Sbostic 	    }
21317a9d5071Sbostic 	}
21327a9d5071Sbostic 
21337a9d5071Sbostic       while (i < n)
21347a9d5071Sbostic 	{
21357a9d5071Sbostic 	  if (k >= BYTESIZE)
21367a9d5071Sbostic 	    {
21377a9d5071Sbostic 	      buff[i++] = MAXBYTE;
21387a9d5071Sbostic 	      k -= BYTESIZE;
21397a9d5071Sbostic 	    }
21407a9d5071Sbostic 	  else
21417a9d5071Sbostic 	    {
21427a9d5071Sbostic 	      while (k-- > 0)
21437a9d5071Sbostic 		{
21447a9d5071Sbostic 		  mask = 1 << k;
21457a9d5071Sbostic 		  buff[i] |= mask;
21467a9d5071Sbostic 		}
21477a9d5071Sbostic 	      i++;
21487a9d5071Sbostic 	    }
21497a9d5071Sbostic 	}
21507a9d5071Sbostic 
21517a9d5071Sbostic       pos = lseek(chkfile, -nbytes, 1);
21527a9d5071Sbostic       if (pos == -1)
21537a9d5071Sbostic 	{
21547a9d5071Sbostic 	  err(seekerror);
21557a9d5071Sbostic 	  done(1);
21567a9d5071Sbostic 	}
21577a9d5071Sbostic 
21587a9d5071Sbostic       nbytes = write(chkfile, buff, n);
21597a9d5071Sbostic       if (nbytes != n)
21607a9d5071Sbostic 	{
21617a9d5071Sbostic 	  err(writeerror);
21627a9d5071Sbostic 	  done(1);
21637a9d5071Sbostic 	}
21647a9d5071Sbostic     }
21657a9d5071Sbostic 
21667a9d5071Sbostic   if (overlap == NO)
21677a9d5071Sbostic     {
21687a9d5071Sbostic       allzero = YES;
21697a9d5071Sbostic       k = len;
21707a9d5071Sbostic 
21717a9d5071Sbostic       while (k > 0 && allzero != NO)
2172ee554660Sbostic 	if (constant[--k] != 0) allzero = NO;
21737a9d5071Sbostic 
21747a9d5071Sbostic       if (allzero == YES)
21757a9d5071Sbostic 	return;
21767a9d5071Sbostic     }
21777a9d5071Sbostic 
21787a9d5071Sbostic   pos = lseek(datafile, offset, 0);
21797a9d5071Sbostic   if (pos == -1)
21807a9d5071Sbostic     {
21817a9d5071Sbostic       err(seekerror);
21827a9d5071Sbostic       done(1);
21837a9d5071Sbostic     }
21847a9d5071Sbostic 
21857a9d5071Sbostic   k = repl;
21867a9d5071Sbostic   while (k-- > 0)
21877a9d5071Sbostic     {
2188ee554660Sbostic       nbytes = write(datafile, constant, len);
21897a9d5071Sbostic       if (nbytes != len)
21907a9d5071Sbostic 	{
21917a9d5071Sbostic 	  err(writeerror);
21927a9d5071Sbostic 	  done(1);
21937a9d5071Sbostic 	}
21947a9d5071Sbostic     }
21957a9d5071Sbostic 
21967a9d5071Sbostic   if (overlap) overlapflag = YES;
21977a9d5071Sbostic 
21987a9d5071Sbostic   return;
21997a9d5071Sbostic }
22007a9d5071Sbostic 
22017a9d5071Sbostic 
22027a9d5071Sbostic 
22037a9d5071Sbostic Constp
getdatum()22047a9d5071Sbostic getdatum()
22057a9d5071Sbostic {
22067a9d5071Sbostic   static char *toofew = "more data items than data values";
22077a9d5071Sbostic 
22087a9d5071Sbostic   register vallist *t;
22097a9d5071Sbostic 
22107a9d5071Sbostic   while (grvals != NULL)
22117a9d5071Sbostic     {
22127a9d5071Sbostic       if (grvals->status != NORMAL)
22137a9d5071Sbostic 	{
22147a9d5071Sbostic 	  dataerror = YES;
22157a9d5071Sbostic 	  return (NULL);
22167a9d5071Sbostic 	}
22177a9d5071Sbostic       else if (grvals->repl > 0)
22187a9d5071Sbostic 	{
22197a9d5071Sbostic 	  grvals->repl--;
22207a9d5071Sbostic 	  return (grvals->value);
22217a9d5071Sbostic 	}
22227a9d5071Sbostic       else
22237a9d5071Sbostic 	{
22247a9d5071Sbostic 	  badvalue = 0;
22257a9d5071Sbostic 	  frexpr ((tagptr) grvals->value);
22267a9d5071Sbostic 	  t = grvals;
22277a9d5071Sbostic 	  grvals = t->next;
22287a9d5071Sbostic 	  free((char *) t);
22297a9d5071Sbostic 	}
22307a9d5071Sbostic     }
22317a9d5071Sbostic 
22327a9d5071Sbostic   err(toofew);
22337a9d5071Sbostic   dataerror = YES;
22347a9d5071Sbostic   return (NULL);
22357a9d5071Sbostic }
22367a9d5071Sbostic 
22377a9d5071Sbostic 
22387a9d5071Sbostic 
outdata(lvals)22397a9d5071Sbostic outdata(lvals)
22407a9d5071Sbostic elist *lvals;
22417a9d5071Sbostic {
22427a9d5071Sbostic   register elist *top;
22437a9d5071Sbostic 
22447a9d5071Sbostic   top = lvals;
22457a9d5071Sbostic 
22467a9d5071Sbostic   while (top != NULL && dataerror == NO)
22477a9d5071Sbostic     {
22487a9d5071Sbostic       if (top->elt->tag == SIMPLE)
22497a9d5071Sbostic 	outaelt((aelt *) top->elt);
22507a9d5071Sbostic       else
22517a9d5071Sbostic 	outdolist((dolist *) top->elt);
22527a9d5071Sbostic 
22537a9d5071Sbostic       top = top->next;
22547a9d5071Sbostic     }
22557a9d5071Sbostic 
22567a9d5071Sbostic   return;
22577a9d5071Sbostic }
22587a9d5071Sbostic 
22597a9d5071Sbostic 
22607a9d5071Sbostic 
outaelt(ap)22617a9d5071Sbostic outaelt(ap)
22627a9d5071Sbostic aelt *ap;
22637a9d5071Sbostic {
22647a9d5071Sbostic   static char *toofew = "more data items than data values";
22657a9d5071Sbostic   static char *boundserror = "substring expression out of bounds";
22667a9d5071Sbostic   static char *order = "substring expressions out of order";
22677a9d5071Sbostic 
22687a9d5071Sbostic   register Namep np;
22697a9d5071Sbostic   register long soffset;
22707a9d5071Sbostic   register dvalue *lwb;
22717a9d5071Sbostic   register dvalue *upb;
2272ee554660Sbostic   register Constp constant;
22737a9d5071Sbostic   register int k;
22747a9d5071Sbostic   register vallist *t;
22757a9d5071Sbostic   register int type;
22767a9d5071Sbostic   register ftnint typelen;
22777a9d5071Sbostic   register ftnint repl;
22787a9d5071Sbostic 
22797a9d5071Sbostic   extern char *packbytes();
22807a9d5071Sbostic 
22817a9d5071Sbostic   np = ap->var;
22827a9d5071Sbostic   setdfiles(np);
22837a9d5071Sbostic 
22847a9d5071Sbostic   type = np->vtype;
22857a9d5071Sbostic 
22867a9d5071Sbostic   if (type == TYCHAR)
2287ee554660Sbostic     typelen = np->vleng->constblock.constant.ci;
22887a9d5071Sbostic   else if (type == TYLOGICAL)
22897a9d5071Sbostic     typelen = typesize[tylogical];
22907a9d5071Sbostic   else
22917a9d5071Sbostic     typelen = typesize[type];
22927a9d5071Sbostic 
22937a9d5071Sbostic   if (ap->subs != NULL || np->vdim == NULL)
22947a9d5071Sbostic     {
22957a9d5071Sbostic       soffset = indexer(ap);
22967a9d5071Sbostic       if (soffset == -1)
22977a9d5071Sbostic 	{
22987a9d5071Sbostic 	  dataerror = YES;
22997a9d5071Sbostic 	  return;
23007a9d5071Sbostic 	}
23017a9d5071Sbostic 
23027a9d5071Sbostic       soffset = soffset * typelen;
23037a9d5071Sbostic 
23047a9d5071Sbostic       if (ap->range != NULL)
23057a9d5071Sbostic 	{
23067a9d5071Sbostic 	  lwb = (dvalue *) evalvexpr(ap->range->low);
23077a9d5071Sbostic 	  upb = (dvalue *) evalvexpr(ap->range->high);
23087a9d5071Sbostic 	  if (lwb->status == ERRVAL || upb->status == ERRVAL)
23097a9d5071Sbostic 	    {
23107a9d5071Sbostic 	      frvexpr((vexpr *) lwb);
23117a9d5071Sbostic 	      frvexpr((vexpr *) upb);
23127a9d5071Sbostic 	      dataerror = YES;
23137a9d5071Sbostic 	      return;
23147a9d5071Sbostic 	    }
23157a9d5071Sbostic 
23167a9d5071Sbostic 	  if (lwb->status != NORMAL ||
23177a9d5071Sbostic 	      lwb->value < 1 ||
23187a9d5071Sbostic 	      lwb->value > typelen ||
23197a9d5071Sbostic 	      upb->status != NORMAL ||
23207a9d5071Sbostic 	      upb->value < 1 ||
23217a9d5071Sbostic 	      upb->value > typelen)
23227a9d5071Sbostic 	    {
23237a9d5071Sbostic 	      err(boundserror);
23247a9d5071Sbostic 	      frvexpr((vexpr *) lwb);
23257a9d5071Sbostic 	      frvexpr((vexpr *) upb);
23267a9d5071Sbostic 	      dataerror = YES;
23277a9d5071Sbostic 	      return;
23287a9d5071Sbostic 	    }
23297a9d5071Sbostic 
23307a9d5071Sbostic 	  if (lwb->value > upb->value)
23317a9d5071Sbostic 	    {
23327a9d5071Sbostic 	      err(order);
23337a9d5071Sbostic 	      frvexpr((vexpr *) lwb);
23347a9d5071Sbostic 	      frvexpr((vexpr *) upb);
23357a9d5071Sbostic 	      dataerror = YES;
23367a9d5071Sbostic 	      return;
23377a9d5071Sbostic 	    }
23387a9d5071Sbostic 
23397a9d5071Sbostic 	  soffset = soffset + lwb->value - 1;
23407a9d5071Sbostic 	  typelen = upb->value - lwb->value + 1;
23417a9d5071Sbostic 	  frvexpr((vexpr *) lwb);
23427a9d5071Sbostic 	  frvexpr((vexpr *) upb);
23437a9d5071Sbostic 	}
23447a9d5071Sbostic 
2345ee554660Sbostic       constant = getdatum();
2346ee554660Sbostic       if (constant == NULL || !ISCONST(constant))
23477a9d5071Sbostic 	return;
23487a9d5071Sbostic 
2349ee554660Sbostic       constant = (Constp) convconst(type, typelen, constant);
2350ee554660Sbostic       if (constant == NULL || !ISCONST(constant))
23517a9d5071Sbostic 	{
2352ee554660Sbostic 	  frexpr((tagptr) constant);
23537a9d5071Sbostic 	  return;
23547a9d5071Sbostic 	}
23557a9d5071Sbostic 
23567a9d5071Sbostic       if (type == TYCHAR)
2357ee554660Sbostic 	wrtdata(base + soffset, 1, typelen, constant->constant.ccp);
23587a9d5071Sbostic       else
2359ee554660Sbostic 	wrtdata(base + soffset, 1, typelen, packbytes(constant));
23607a9d5071Sbostic 
2361ee554660Sbostic       frexpr((tagptr) constant);
23627a9d5071Sbostic     }
23637a9d5071Sbostic   else
23647a9d5071Sbostic     {
23657a9d5071Sbostic       soffset = 0;
2366ee554660Sbostic       k = np->vdim->nelt->constblock.constant.ci;
23677a9d5071Sbostic       while (k > 0 && dataerror == NO)
23687a9d5071Sbostic 	{
23697a9d5071Sbostic 	  if (grvals == NULL)
23707a9d5071Sbostic 	    {
23717a9d5071Sbostic 	      err(toofew);
23727a9d5071Sbostic 	      dataerror = YES;
23737a9d5071Sbostic 	    }
23747a9d5071Sbostic 	  else if (grvals->status != NORMAL)
23757a9d5071Sbostic 	    dataerror = YES;
23767a9d5071Sbostic 	  else if (grvals-> repl <= 0)
23777a9d5071Sbostic 	    {
23787a9d5071Sbostic 	      badvalue = 0;
23797a9d5071Sbostic 	      frexpr((tagptr) grvals->value);
23807a9d5071Sbostic 	      t = grvals;
23817a9d5071Sbostic 	      grvals = t->next;
23827a9d5071Sbostic 	      free((char *) t);
23837a9d5071Sbostic 	    }
23847a9d5071Sbostic 	  else
23857a9d5071Sbostic 	    {
2386ee554660Sbostic 	      constant = grvals->value;
2387ee554660Sbostic 	      if (constant == NULL || !ISCONST(constant))
23887a9d5071Sbostic 		{
23897a9d5071Sbostic 		  dataerror = YES;
23907a9d5071Sbostic 		}
23917a9d5071Sbostic 	      else
23927a9d5071Sbostic 		{
2393ee554660Sbostic 		  constant = (Constp) convconst(type, typelen, constant);
2394ee554660Sbostic 		  if (constant == NULL || !ISCONST(constant))
23957a9d5071Sbostic 		    {
23967a9d5071Sbostic 		      dataerror = YES;
2397ee554660Sbostic 		      frexpr((tagptr) constant);
23987a9d5071Sbostic 		    }
23997a9d5071Sbostic 		  else
24007a9d5071Sbostic 		    {
24017a9d5071Sbostic 		      if (k > grvals->repl)
24027a9d5071Sbostic 			repl = grvals->repl;
24037a9d5071Sbostic 		      else
24047a9d5071Sbostic 			repl = k;
24057a9d5071Sbostic 
24067a9d5071Sbostic 		      grvals->repl -= repl;
24077a9d5071Sbostic 		      k -= repl;
24087a9d5071Sbostic 
24097a9d5071Sbostic 		      if (type == TYCHAR)
2410ee554660Sbostic 			wrtdata(base+soffset, repl, typelen,
2411ee554660Sbostic 			    constant->constant.ccp);
24127a9d5071Sbostic 		      else
2413ee554660Sbostic 			wrtdata(base+soffset, repl, typelen,
2414ee554660Sbostic 			    packbytes(constant));
24157a9d5071Sbostic 
24167a9d5071Sbostic 		      soffset = soffset + repl * typelen;
24177a9d5071Sbostic 
2418ee554660Sbostic 		      frexpr((tagptr) constant);
24197a9d5071Sbostic 		    }
24207a9d5071Sbostic 		}
24217a9d5071Sbostic 	    }
24227a9d5071Sbostic 	}
24237a9d5071Sbostic     }
24247a9d5071Sbostic 
24257a9d5071Sbostic   return;
24267a9d5071Sbostic }
24277a9d5071Sbostic 
24287a9d5071Sbostic 
24297a9d5071Sbostic 
outdolist(dp)24307a9d5071Sbostic outdolist(dp)
24317a9d5071Sbostic dolist *dp;
24327a9d5071Sbostic {
24337a9d5071Sbostic   static char *zerostep = "zero step in implied-DO";
24347a9d5071Sbostic   static char *order = "zero iteration count in implied-DO";
24357a9d5071Sbostic 
24367a9d5071Sbostic   register dvalue *e1, *e2, *e3;
24377a9d5071Sbostic   register int direction;
24387a9d5071Sbostic   register dvalue *dv;
24397a9d5071Sbostic   register int done;
24407a9d5071Sbostic   register int addin;
24417a9d5071Sbostic   register int ts;
24427a9d5071Sbostic   register ftnint tv;
24437a9d5071Sbostic 
24447a9d5071Sbostic   e1 = (dvalue *) evalvexpr(dp->init);
24457a9d5071Sbostic   e2 = (dvalue *) evalvexpr(dp->limit);
24467a9d5071Sbostic   e3 = (dvalue *) evalvexpr(dp->step);
24477a9d5071Sbostic 
24487a9d5071Sbostic   if (e1->status == ERRVAL ||
24497a9d5071Sbostic       e2->status == ERRVAL ||
24507a9d5071Sbostic       e3->status == ERRVAL)
24517a9d5071Sbostic     {
24527a9d5071Sbostic       dataerror = YES;
24537a9d5071Sbostic       goto ret;
24547a9d5071Sbostic     }
24557a9d5071Sbostic 
24567a9d5071Sbostic   if (e1->status == NORMAL)
24577a9d5071Sbostic     {
24587a9d5071Sbostic       if (e2->status == NORMAL)
24597a9d5071Sbostic 	{
24607a9d5071Sbostic 	  if (e1->value < e2->value)
24617a9d5071Sbostic 	    direction = 1;
24627a9d5071Sbostic 	  else if (e1->value > e2->value)
24637a9d5071Sbostic 	    direction = -1;
24647a9d5071Sbostic 	  else
24657a9d5071Sbostic 	    direction = 0;
24667a9d5071Sbostic 	}
24677a9d5071Sbostic       else if (e2->status == MAXPLUS1)
24687a9d5071Sbostic 	direction = 1;
24697a9d5071Sbostic       else
24707a9d5071Sbostic 	direction = -1;
24717a9d5071Sbostic     }
24727a9d5071Sbostic   else if (e1->status == MAXPLUS1)
24737a9d5071Sbostic     {
24747a9d5071Sbostic       if (e2->status == MAXPLUS1)
24757a9d5071Sbostic 	direction = 0;
24767a9d5071Sbostic       else
24777a9d5071Sbostic 	direction = -1;
24787a9d5071Sbostic     }
24797a9d5071Sbostic   else
24807a9d5071Sbostic     {
24817a9d5071Sbostic       if (e2->status == MINLESS1)
24827a9d5071Sbostic 	direction = 0;
24837a9d5071Sbostic       else
24847a9d5071Sbostic 	direction = 1;
24857a9d5071Sbostic     }
24867a9d5071Sbostic 
24877a9d5071Sbostic   if (e3->status == NORMAL && e3->value == 0)
24887a9d5071Sbostic     {
24897a9d5071Sbostic       err(zerostep);
24907a9d5071Sbostic       dataerror = YES;
24917a9d5071Sbostic       goto ret;
24927a9d5071Sbostic     }
24937a9d5071Sbostic   else if (e3->status == MAXPLUS1 ||
24947a9d5071Sbostic 	   (e3->status == NORMAL && e3->value > 0))
24957a9d5071Sbostic     {
24967a9d5071Sbostic       if (direction == -1)
24977a9d5071Sbostic 	{
24987a9d5071Sbostic 	  warn(order);
24997a9d5071Sbostic 	  goto ret;
25007a9d5071Sbostic 	}
25017a9d5071Sbostic     }
25027a9d5071Sbostic   else
25037a9d5071Sbostic     {
25047a9d5071Sbostic       if (direction == 1)
25057a9d5071Sbostic 	{
25067a9d5071Sbostic 	  warn(order);
25077a9d5071Sbostic 	  goto ret;
25087a9d5071Sbostic 	}
25097a9d5071Sbostic     }
25107a9d5071Sbostic 
25117a9d5071Sbostic   dv = (dvalue *) dp->dovar;
25127a9d5071Sbostic   dv->status = e1->status;
25137a9d5071Sbostic   dv->value = e1->value;
25147a9d5071Sbostic 
25157a9d5071Sbostic   done = NO;
25167a9d5071Sbostic   while (done == NO && dataerror == NO)
25177a9d5071Sbostic     {
25187a9d5071Sbostic       outdata(dp->elts);
25197a9d5071Sbostic 
25207a9d5071Sbostic       if (e3->status == NORMAL && dv->status == NORMAL)
25217a9d5071Sbostic 	{
25227a9d5071Sbostic 	  addints(e3->value, dv->value);
25237a9d5071Sbostic 	  dv->status = rstatus;
25247a9d5071Sbostic 	  dv->value = rvalue;
25257a9d5071Sbostic 	}
25267a9d5071Sbostic       else
25277a9d5071Sbostic 	{
25287a9d5071Sbostic 	  if (e3->status != NORMAL)
25297a9d5071Sbostic 	    {
25307a9d5071Sbostic 	      if (e3->status == MAXPLUS1)
25317a9d5071Sbostic 		addin = MAXPLUS1;
25327a9d5071Sbostic 	      else
25337a9d5071Sbostic 		addin = MINLESS1;
25347a9d5071Sbostic 	      ts = dv->status;
25357a9d5071Sbostic 	      tv = dv->value;
25367a9d5071Sbostic 	    }
25377a9d5071Sbostic 	  else
25387a9d5071Sbostic 	    {
25397a9d5071Sbostic 	      if (dv->status == MAXPLUS1)
25407a9d5071Sbostic 		addin = MAXPLUS1;
25417a9d5071Sbostic 	      else
25427a9d5071Sbostic 		addin = MINLESS1;
25437a9d5071Sbostic 	      ts = e3->status;
25447a9d5071Sbostic 	      tv = e3->value;
25457a9d5071Sbostic 	    }
25467a9d5071Sbostic 
25477a9d5071Sbostic 	  if (addin == MAXPLUS1)
25487a9d5071Sbostic 	    {
25497a9d5071Sbostic 	      if (ts == MAXPLUS1 || (ts == NORMAL && tv > 0))
25507a9d5071Sbostic 		dv->status = ERRVAL;
25517a9d5071Sbostic 	      else if (ts == NORMAL && tv == 0)
25527a9d5071Sbostic 		dv->status = MAXPLUS1;
25537a9d5071Sbostic 	      else if (ts == NORMAL)
25547a9d5071Sbostic 		{
25557a9d5071Sbostic 		  dv->status = NORMAL;
25567a9d5071Sbostic 		  dv->value = tv + MAXINT;
25577a9d5071Sbostic 		  dv->value++;
25587a9d5071Sbostic 		}
25597a9d5071Sbostic 	      else
25607a9d5071Sbostic 		{
25617a9d5071Sbostic 		  dv->status = NORMAL;
25627a9d5071Sbostic 		  dv->value = 0;
25637a9d5071Sbostic 		}
25647a9d5071Sbostic 	    }
25657a9d5071Sbostic 	  else
25667a9d5071Sbostic 	    {
25677a9d5071Sbostic 	      if (ts == MINLESS1 || (ts == NORMAL && tv < 0))
25687a9d5071Sbostic 		dv->status = ERRVAL;
25697a9d5071Sbostic 	      else if (ts == NORMAL && tv == 0)
25707a9d5071Sbostic 		dv->status = MINLESS1;
25717a9d5071Sbostic 	      else if (ts == NORMAL)
25727a9d5071Sbostic 		{
25737a9d5071Sbostic 		  dv->status = NORMAL;
25747a9d5071Sbostic 		  dv->value = tv - MAXINT;
25757a9d5071Sbostic 		  dv->value--;
25767a9d5071Sbostic 		}
25777a9d5071Sbostic 	      else
25787a9d5071Sbostic 		{
25797a9d5071Sbostic 		  dv->status = NORMAL;
25807a9d5071Sbostic 		  dv->value = 0;
25817a9d5071Sbostic 		}
25827a9d5071Sbostic 	    }
25837a9d5071Sbostic 	}
25847a9d5071Sbostic 
25857a9d5071Sbostic       if (dv->status == ERRVAL)
25867a9d5071Sbostic 	done = YES;
25877a9d5071Sbostic       else if (direction > 0)
25887a9d5071Sbostic 	{
25897a9d5071Sbostic 	  if (e2->status == NORMAL)
25907a9d5071Sbostic 	    {
25917a9d5071Sbostic 	      if (dv->status == MAXPLUS1 ||
25927a9d5071Sbostic 		  (dv->status == NORMAL && dv->value > e2->value))
25937a9d5071Sbostic 		done = YES;
25947a9d5071Sbostic 	    }
25957a9d5071Sbostic 	}
25967a9d5071Sbostic       else if (direction < 0)
25977a9d5071Sbostic 	{
25987a9d5071Sbostic 	  if (e2->status == NORMAL)
25997a9d5071Sbostic 	    {
26007a9d5071Sbostic 	      if (dv->status == MINLESS1 ||
26017a9d5071Sbostic 		  (dv->status == NORMAL && dv->value < e2->value))
26027a9d5071Sbostic 		done = YES;
26037a9d5071Sbostic 	    }
26047a9d5071Sbostic 	}
26057a9d5071Sbostic       else
26067a9d5071Sbostic 	done = YES;
26077a9d5071Sbostic     }
26087a9d5071Sbostic 
26097a9d5071Sbostic ret:
26107a9d5071Sbostic   frvexpr((vexpr *) e1);
26117a9d5071Sbostic   frvexpr((vexpr *) e2);
26127a9d5071Sbostic   frvexpr((vexpr *) e3);
26137a9d5071Sbostic   return;
26147a9d5071Sbostic }
2615