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