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