1*47955Sbostic /*-
2*47955Sbostic * Copyright (c) 1980 The Regents of the University of California.
3*47955Sbostic * All rights reserved.
4*47955Sbostic *
5*47955Sbostic * %sccs.include.proprietary.c%
622803Smckusick */
722803Smckusick
822803Smckusick #ifndef lint
9*47955Sbostic static char sccsid[] = "@(#)data.c 5.3 (Berkeley) 04/12/91";
10*47955Sbostic #endif /* not lint */
1122803Smckusick
1222803Smckusick /*
1322803Smckusick * data.c
1422803Smckusick *
1522803Smckusick * Routines for handling DATA statements, f77 compiler, 4.2 BSD.
1622803Smckusick *
1722803Smckusick * University of Utah CS Dept modification history:
1822803Smckusick *
1922803Smckusick * Revision 3.1 84/10/13 01:09:50 donn
2022803Smckusick * Installed Jerry Berkman's version; added UofU comment header.
2122803Smckusick *
2222803Smckusick */
2322803Smckusick
2422803Smckusick #include "defs.h"
2522803Smckusick #include "data.h"
2622803Smckusick
2722803Smckusick
2822803Smckusick /* global variables */
2922803Smckusick
3022803Smckusick flag overlapflag;
3122803Smckusick
3222803Smckusick
3322803Smckusick
3422803Smckusick /* local variables */
3522803Smckusick
3622803Smckusick LOCAL char rstatus;
3722803Smckusick LOCAL ftnint rvalue;
3822803Smckusick LOCAL dovars *dvlist;
3922803Smckusick LOCAL int dataerror;
4022803Smckusick LOCAL vallist *grvals;
4122803Smckusick LOCAL int datafile;
4222803Smckusick LOCAL int chkfile;
4322803Smckusick LOCAL long base;
4422803Smckusick
4522803Smckusick
4622803Smckusick
4722803Smckusick /* Copied from expr.c */
4822803Smckusick
letter(c)4922803Smckusick LOCAL letter(c)
5022803Smckusick register int c;
5122803Smckusick {
5222803Smckusick if( isupper(c) )
5322803Smckusick c = tolower(c);
5422803Smckusick return(c - 'a');
5522803Smckusick }
5622803Smckusick
5722803Smckusick
5822803Smckusick
5922803Smckusick vexpr *
cpdvalue(dp)6022803Smckusick cpdvalue(dp)
6122803Smckusick vexpr *dp;
6222803Smckusick {
6322803Smckusick register dvalue *p;
6422803Smckusick
6522803Smckusick if (dp->tag != DVALUE)
6622803Smckusick badtag("cpdvalue", dp->tag);
6722803Smckusick
6822803Smckusick p = ALLOC(Dvalue);
6922803Smckusick p->tag = DVALUE;
7022803Smckusick p->status = dp->dvalue.status;
7122803Smckusick p->value = dp->dvalue.value;
7222803Smckusick
7322803Smckusick return ((vexpr *) p);
7422803Smckusick }
7522803Smckusick
7622803Smckusick
7722803Smckusick
frvexpr(vp)7822803Smckusick frvexpr(vp)
7922803Smckusick register vexpr *vp;
8022803Smckusick {
8122803Smckusick if (vp != NULL)
8222803Smckusick {
8322803Smckusick if (vp->tag == DNAME)
8422803Smckusick free(vp->dname.repr);
8522803Smckusick else if (vp->tag == DEXPR)
8622803Smckusick {
8722803Smckusick frvexpr(vp->dexpr.left);
8822803Smckusick frvexpr(vp->dexpr.right);
8922803Smckusick }
9022803Smckusick
9122803Smckusick free((char *) vp);
9222803Smckusick }
9322803Smckusick
9422803Smckusick return;
9522803Smckusick }
9622803Smckusick
9722803Smckusick
9822803Smckusick
frvlist(vp)9922803Smckusick frvlist(vp)
10022803Smckusick register vlist *vp;
10122803Smckusick {
10222803Smckusick register vlist *t;
10322803Smckusick
10422803Smckusick while (vp)
10522803Smckusick {
10622803Smckusick t = vp->next;
10722803Smckusick frvexpr(vp->val);
10822803Smckusick free((char *) vp);
10922803Smckusick vp = t;
11022803Smckusick }
11122803Smckusick
11222803Smckusick return;
11322803Smckusick }
11422803Smckusick
11522803Smckusick
11622803Smckusick
frelist(ep)11722803Smckusick frelist(ep)
11822803Smckusick elist *ep;
11922803Smckusick {
12022803Smckusick register elist *p;
12122803Smckusick register elist *t;
12222803Smckusick register aelt *ap;
12322803Smckusick register dolist *dp;
12422803Smckusick
12522803Smckusick p = ep;
12622803Smckusick
12722803Smckusick while (p != NULL)
12822803Smckusick {
12922803Smckusick if (p->elt->tag == SIMPLE)
13022803Smckusick {
13122803Smckusick ap = (aelt *) p->elt;
13222803Smckusick frvlist(ap->subs);
13322803Smckusick if (ap->range != NULL)
13422803Smckusick {
13522803Smckusick frvexpr(ap->range->low);
13622803Smckusick frvexpr(ap->range->high);
13722803Smckusick free((char *) ap->range);
13822803Smckusick }
13922803Smckusick free((char *) ap);
14022803Smckusick }
14122803Smckusick else
14222803Smckusick {
14322803Smckusick dp = (dolist *) p->elt;
14422803Smckusick frvexpr(dp->dovar);
14522803Smckusick frvexpr(dp->init);
14622803Smckusick frvexpr(dp->limit);
14722803Smckusick frvexpr(dp->step);
14822803Smckusick frelist(dp->elts);
14922803Smckusick free((char *) dp);
15022803Smckusick }
15122803Smckusick
15222803Smckusick t = p;
15322803Smckusick p = p->next;
15422803Smckusick free((char *) t);
15522803Smckusick }
15622803Smckusick
15722803Smckusick return;
15822803Smckusick }
15922803Smckusick
16022803Smckusick
16122803Smckusick
frvallist(vp)16222803Smckusick frvallist(vp)
16322803Smckusick vallist *vp;
16422803Smckusick {
16522803Smckusick register vallist *p;
16622803Smckusick register vallist *t;
16722803Smckusick
16822803Smckusick p = vp;
16922803Smckusick while (p != NULL)
17022803Smckusick {
17122803Smckusick frexpr((tagptr) p->value);
17222803Smckusick t = p;
17322803Smckusick p = p->next;
17422803Smckusick free((char *) t);
17522803Smckusick }
17622803Smckusick
17722803Smckusick return;
17822803Smckusick }
17922803Smckusick
18022803Smckusick
18122803Smckusick
revelist(ep)18222803Smckusick elist *revelist(ep)
18322803Smckusick register elist *ep;
18422803Smckusick {
18522803Smckusick register elist *next;
18622803Smckusick register elist *t;
18722803Smckusick
18822803Smckusick if (ep != NULL)
18922803Smckusick {
19022803Smckusick next = ep->next;
19122803Smckusick ep->next = NULL;
19222803Smckusick
19322803Smckusick while (next)
19422803Smckusick {
19522803Smckusick t = next->next;
19622803Smckusick next->next = ep;
19722803Smckusick ep = next;
19822803Smckusick next = t;
19922803Smckusick }
20022803Smckusick }
20122803Smckusick
20222803Smckusick return (ep);
20322803Smckusick }
20422803Smckusick
20522803Smckusick
20622803Smckusick
revvlist(vp)20722803Smckusick vlist *revvlist(vp)
20822803Smckusick vlist *vp;
20922803Smckusick {
21022803Smckusick register vlist *p;
21122803Smckusick register vlist *next;
21222803Smckusick register vlist *t;
21322803Smckusick
21422803Smckusick if (vp == NULL)
21522803Smckusick p = NULL;
21622803Smckusick else
21722803Smckusick {
21822803Smckusick p = vp;
21922803Smckusick next = p->next;
22022803Smckusick p->next = NULL;
22122803Smckusick
22222803Smckusick while (next)
22322803Smckusick {
22422803Smckusick t = next->next;
22522803Smckusick next->next = p;
22622803Smckusick p = next;
22722803Smckusick next = t;
22822803Smckusick }
22922803Smckusick }
23022803Smckusick
23122803Smckusick return (p);
23222803Smckusick }
23322803Smckusick
23422803Smckusick
23522803Smckusick
23622803Smckusick vallist *
revrvals(vp)23722803Smckusick revrvals(vp)
23822803Smckusick vallist *vp;
23922803Smckusick {
24022803Smckusick register vallist *p;
24122803Smckusick register vallist *next;
24222803Smckusick register vallist *t;
24322803Smckusick
24422803Smckusick if (vp == NULL)
24522803Smckusick p = NULL;
24622803Smckusick else
24722803Smckusick {
24822803Smckusick p = vp;
24922803Smckusick next = p->next;
25022803Smckusick p->next = NULL;
25122803Smckusick while (next)
25222803Smckusick {
25322803Smckusick t = next->next;
25422803Smckusick next->next = p;
25522803Smckusick p = next;
25622803Smckusick next = t;
25722803Smckusick }
25822803Smckusick }
25922803Smckusick
26022803Smckusick return (p);
26122803Smckusick }
26222803Smckusick
26322803Smckusick
26422803Smckusick
prepvexpr(tail,head)26522803Smckusick vlist *prepvexpr(tail, head)
26622803Smckusick vlist *tail;
26722803Smckusick vexpr *head;
26822803Smckusick {
26922803Smckusick register vlist *p;
27022803Smckusick
27122803Smckusick p = ALLOC(Vlist);
27222803Smckusick p->next = tail;
27322803Smckusick p->val = head;
27422803Smckusick
27522803Smckusick return (p);
27622803Smckusick }
27722803Smckusick
27822803Smckusick
27922803Smckusick
preplval(tail,head)28022803Smckusick elist *preplval(tail, head)
28122803Smckusick elist *tail;
28222803Smckusick delt* head;
28322803Smckusick {
28422803Smckusick register elist *p;
28522803Smckusick p = ALLOC(Elist);
28622803Smckusick p->next = tail;
28722803Smckusick p->elt = head;
28822803Smckusick
28922803Smckusick return (p);
29022803Smckusick }
29122803Smckusick
29222803Smckusick
29322803Smckusick
mkdlval(name,subs,range)29422803Smckusick delt *mkdlval(name, subs, range)
29522803Smckusick vexpr *name;
29622803Smckusick vlist *subs;
29722803Smckusick rpair *range;
29822803Smckusick {
29922803Smckusick register aelt *p;
30022803Smckusick
30122803Smckusick p = ALLOC(Aelt);
30222803Smckusick p->tag = SIMPLE;
30322803Smckusick p->var = mkname(name->dname.len, name->dname.repr);
30422803Smckusick p->subs = subs;
30522803Smckusick p->range = range;
30622803Smckusick
30722803Smckusick return ((delt *) p);
30822803Smckusick }
30922803Smckusick
31022803Smckusick
31122803Smckusick
mkdatado(lvals,dovar,params)31222803Smckusick delt *mkdatado(lvals, dovar, params)
31322803Smckusick elist *lvals;
31422803Smckusick vexpr *dovar;
31522803Smckusick vlist *params;
31622803Smckusick {
31722803Smckusick static char *toofew = "missing loop parameters";
31822803Smckusick static char *toomany = "too many loop parameters";
31922803Smckusick
32022803Smckusick register dolist *p;
32122803Smckusick register vlist *vp;
32222803Smckusick register int pcnt;
32322803Smckusick register dvalue *one;
32422803Smckusick
32522803Smckusick p = ALLOC(DoList);
32622803Smckusick p->tag = NESTED;
32722803Smckusick p->elts = revelist(lvals);
32822803Smckusick p->dovar = dovar;
32922803Smckusick
33022803Smckusick vp = params;
33122803Smckusick pcnt = 0;
33222803Smckusick while (vp)
33322803Smckusick {
33422803Smckusick pcnt++;
33522803Smckusick vp = vp->next;
33622803Smckusick }
33722803Smckusick
33822803Smckusick if (pcnt != 2 && pcnt != 3)
33922803Smckusick {
34022803Smckusick if (pcnt < 2)
34122803Smckusick err(toofew);
34222803Smckusick else
34322803Smckusick err(toomany);
34422803Smckusick
34522803Smckusick p->init = (vexpr *) ALLOC(Derror);
34622803Smckusick p->init->tag = DERROR;
34722803Smckusick
34822803Smckusick p->limit = (vexpr *) ALLOC(Derror);
34922803Smckusick p->limit->tag = DERROR;
35022803Smckusick
35122803Smckusick p->step = (vexpr *) ALLOC(Derror);
35222803Smckusick p->step->tag = DERROR;
35322803Smckusick }
35422803Smckusick else
35522803Smckusick {
35622803Smckusick vp = params;
35722803Smckusick
35822803Smckusick if (pcnt == 2)
35922803Smckusick {
36022803Smckusick one = ALLOC(Dvalue);
36122803Smckusick one->tag = DVALUE;
36222803Smckusick one->status = NORMAL;
36322803Smckusick one->value = 1;
36422803Smckusick p->step = (vexpr *) one;
36522803Smckusick }
36622803Smckusick else
36722803Smckusick {
36822803Smckusick p->step = vp->val;
36922803Smckusick vp->val = NULL;
37022803Smckusick vp = vp->next;
37122803Smckusick }
37222803Smckusick
37322803Smckusick p->limit = vp->val;
37422803Smckusick vp->val = NULL;
37522803Smckusick vp = vp->next;
37622803Smckusick
37722803Smckusick p->init = vp->val;
37822803Smckusick vp->val = NULL;
37922803Smckusick }
38022803Smckusick
38122803Smckusick frvlist(params);
38222803Smckusick return ((delt *) p);
38322803Smckusick }
38422803Smckusick
38522803Smckusick
38622803Smckusick
mkdrange(lb,ub)38722803Smckusick rpair *mkdrange(lb, ub)
38822803Smckusick vexpr *lb, *ub;
38922803Smckusick {
39022803Smckusick register rpair *p;
39122803Smckusick
39222803Smckusick p = ALLOC(Rpair);
39322803Smckusick p->low = lb;
39422803Smckusick p->high = ub;
39522803Smckusick
39622803Smckusick return (p);
39722803Smckusick }
39822803Smckusick
39922803Smckusick
40022803Smckusick
mkdrval(repl,val)40122803Smckusick vallist *mkdrval(repl, val)
40222803Smckusick vexpr *repl;
40322803Smckusick expptr val;
40422803Smckusick {
40522803Smckusick static char *badtag = "bad tag in mkdrval";
40622803Smckusick static char *negrepl = "negative replicator";
40722803Smckusick static char *zerorepl = "zero replicator";
40822803Smckusick static char *toobig = "replicator too large";
40922803Smckusick static char *nonconst = "%s is not a constant";
41022803Smckusick
41122803Smckusick register vexpr *vp;
41222803Smckusick register vallist *p;
41322803Smckusick register int status;
41422803Smckusick register ftnint value;
41522803Smckusick register int copied;
41622803Smckusick
41722803Smckusick copied = 0;
41822803Smckusick
41922803Smckusick if (repl->tag == DNAME)
42022803Smckusick {
42122803Smckusick vp = evaldname(repl);
42222803Smckusick copied = 1;
42322803Smckusick }
42422803Smckusick else
42522803Smckusick vp = repl;
42622803Smckusick
42722803Smckusick p = ALLOC(ValList);
42822803Smckusick p->next = NULL;
42922803Smckusick p->value = (Constp) val;
43022803Smckusick
43122803Smckusick if (vp->tag == DVALUE)
43222803Smckusick {
43322803Smckusick status = vp->dvalue.status;
43422803Smckusick value = vp->dvalue.value;
43522803Smckusick
43622803Smckusick if ((status == NORMAL && value < 0) || status == MINLESS1)
43722803Smckusick {
43822803Smckusick err(negrepl);
43922803Smckusick p->status = ERRVAL;
44022803Smckusick }
44122803Smckusick else if (status == NORMAL)
44222803Smckusick {
44322803Smckusick if (value == 0)
44422803Smckusick warn(zerorepl);
44522803Smckusick p->status = NORMAL;
44622803Smckusick p->repl = value;
44722803Smckusick }
44822803Smckusick else if (status == MAXPLUS1)
44922803Smckusick {
45022803Smckusick err(toobig);
45122803Smckusick p->status = ERRVAL;
45222803Smckusick }
45322803Smckusick else
45422803Smckusick p->status = ERRVAL;
45522803Smckusick }
45622803Smckusick else if (vp->tag == DNAME)
45722803Smckusick {
45822803Smckusick errnm(nonconst, vp->dname.len, vp->dname.repr);
45922803Smckusick p->status = ERRVAL;
46022803Smckusick }
46122803Smckusick else if (vp->tag == DERROR)
46222803Smckusick p->status = ERRVAL;
46322803Smckusick else
46422803Smckusick fatal(badtag);
46522803Smckusick
46622803Smckusick if (copied) frvexpr(vp);
46722803Smckusick return (p);
46822803Smckusick }
46922803Smckusick
47022803Smckusick
47122803Smckusick
47222803Smckusick /* Evicon returns the value of the integer constant */
47322803Smckusick /* pointed to by token. */
47422803Smckusick
evicon(len,token)47522803Smckusick vexpr *evicon(len, token)
47622803Smckusick register int len;
47722803Smckusick register char *token;
47822803Smckusick {
47922803Smckusick static char *badconst = "bad integer constant";
48022803Smckusick static char *overflow = "integer constant too large";
48122803Smckusick
48222803Smckusick register int i;
48322803Smckusick register ftnint val;
48422803Smckusick register int digit;
48522803Smckusick register dvalue *p;
48622803Smckusick
48722803Smckusick if (len <= 0)
48822803Smckusick fatal(badconst);
48922803Smckusick
49022803Smckusick p = ALLOC(Dvalue);
49122803Smckusick p->tag = DVALUE;
49222803Smckusick
49322803Smckusick i = 0;
49422803Smckusick val = 0;
49522803Smckusick while (i < len)
49622803Smckusick {
49722803Smckusick if (val > MAXINT/10)
49822803Smckusick {
49922803Smckusick err(overflow);
50022803Smckusick p->status = ERRVAL;
50122803Smckusick goto ret;
50222803Smckusick }
50322803Smckusick val = 10*val;
50422803Smckusick digit = token[i++];
50522803Smckusick if (!isdigit(digit))
50622803Smckusick fatal(badconst);
50722803Smckusick digit = digit - '0';
50822803Smckusick if (MAXINT - val >= digit)
50922803Smckusick val = val + digit;
51022803Smckusick else
51122803Smckusick if (i == len && MAXINT - val + 1 == digit)
51222803Smckusick {
51322803Smckusick p->status = MAXPLUS1;
51422803Smckusick goto ret;
51522803Smckusick }
51622803Smckusick else
51722803Smckusick {
51822803Smckusick err(overflow);
51922803Smckusick p->status = ERRVAL;
52022803Smckusick goto ret;
52122803Smckusick }
52222803Smckusick }
52322803Smckusick
52422803Smckusick p->status = NORMAL;
52522803Smckusick p->value = val;
52622803Smckusick
52722803Smckusick ret:
52822803Smckusick return ((vexpr *) p);
52922803Smckusick }
53022803Smckusick
53122803Smckusick
53222803Smckusick
53322803Smckusick /* Ivaltoicon converts a dvalue into a constant block. */
53422803Smckusick
ivaltoicon(vp)53522803Smckusick expptr ivaltoicon(vp)
53622803Smckusick register vexpr *vp;
53722803Smckusick {
53822803Smckusick static char *badtag = "bad tag in ivaltoicon";
53922803Smckusick static char *overflow = "integer constant too large";
54022803Smckusick
54122803Smckusick register int vs;
54222803Smckusick register expptr p;
54322803Smckusick
54422803Smckusick if (vp->tag == DERROR)
54522803Smckusick return(errnode());
54622803Smckusick else if (vp->tag != DVALUE)
54722803Smckusick fatal(badtag);
54822803Smckusick
54922803Smckusick vs = vp->dvalue.status;
55022803Smckusick if (vs == NORMAL)
55122803Smckusick p = mkintcon(vp->dvalue.value);
55222803Smckusick else if ((MAXINT + MININT == -1) && vs == MINLESS1)
55322803Smckusick p = mkintcon(MININT);
55422803Smckusick else if (vs == MAXPLUS1 || vs == MINLESS1)
55522803Smckusick {
55622803Smckusick err(overflow);
55722803Smckusick p = errnode();
55822803Smckusick }
55922803Smckusick else
56022803Smckusick p = errnode();
56122803Smckusick
56222803Smckusick return (p);
56322803Smckusick }
56422803Smckusick
56522803Smckusick
56622803Smckusick
56722803Smckusick /* Mkdname stores an identifier as a dname */
56822803Smckusick
mkdname(len,str)56922803Smckusick vexpr *mkdname(len, str)
57022803Smckusick int len;
57122803Smckusick register char *str;
57222803Smckusick {
57322803Smckusick register dname *p;
57422803Smckusick register int i;
57522803Smckusick register char *s;
57622803Smckusick
57722803Smckusick s = (char *) ckalloc(len + 1);
57822803Smckusick i = len;
57922803Smckusick s[i] = '\0';
58022803Smckusick
58122803Smckusick while (--i >= 0)
58222803Smckusick s[i] = str[i];
58322803Smckusick
58422803Smckusick p = ALLOC(Dname);
58522803Smckusick p->tag = DNAME;
58622803Smckusick p->len = len;
58722803Smckusick p->repr = s;
58822803Smckusick
58922803Smckusick return ((vexpr *) p);
59022803Smckusick }
59122803Smckusick
59222803Smckusick
59322803Smckusick
59422803Smckusick /* Getname gets the symbol table information associated with */
59522803Smckusick /* a name. Getname differs from mkname in that it will not */
59622803Smckusick /* add the name to the symbol table if it is not already */
59722803Smckusick /* present. */
59822803Smckusick
getname(l,s)59922803Smckusick Namep getname(l, s)
60022803Smckusick int l;
60122803Smckusick register char *s;
60222803Smckusick {
60322803Smckusick struct Hashentry *hp;
60422803Smckusick int hash;
60522803Smckusick register Namep q;
60622803Smckusick register int i;
60722803Smckusick char n[VL];
60822803Smckusick
60922803Smckusick hash = 0;
61022803Smckusick for (i = 0; i < l && *s != '\0'; ++i)
61122803Smckusick {
61222803Smckusick hash += *s;
61322803Smckusick n[i] = *s++;
61422803Smckusick }
61522803Smckusick
61622803Smckusick while (i < VL)
61722803Smckusick n[i++] = ' ';
61822803Smckusick
61922803Smckusick hash %= maxhash;
62022803Smckusick hp = hashtab + hash;
62122803Smckusick
62222803Smckusick while (q = hp->varp)
62322803Smckusick if (hash == hp->hashval
62422803Smckusick && eqn(VL, n, q->varname))
62522803Smckusick goto ret;
62622803Smckusick else if (++hp >= lasthash)
62722803Smckusick hp = hashtab;
62822803Smckusick
62922803Smckusick ret:
63022803Smckusick return (q);
63122803Smckusick }
63222803Smckusick
63322803Smckusick
63422803Smckusick
63522803Smckusick /* Evparam returns the value of the constant named by name. */
63622803Smckusick
evparam(np)63722803Smckusick expptr evparam(np)
63822803Smckusick register vexpr *np;
63922803Smckusick {
64022803Smckusick static char *badtag = "bad tag in evparam";
64122803Smckusick static char *undefined = "%s is undefined";
64222803Smckusick static char *nonconst = "%s is not constant";
64322803Smckusick
64422803Smckusick register struct Paramblock *tp;
64522803Smckusick register expptr p;
64622803Smckusick register int len;
64722803Smckusick register char *repr;
64822803Smckusick
64922803Smckusick if (np->tag != DNAME)
65022803Smckusick fatal(badtag);
65122803Smckusick
65222803Smckusick len = np->dname.len;
65322803Smckusick repr = np->dname.repr;
65422803Smckusick
65522803Smckusick tp = (struct Paramblock *) getname(len, repr);
65622803Smckusick
65722803Smckusick if (tp == NULL)
65822803Smckusick {
65922803Smckusick errnm(undefined, len, repr);
66022803Smckusick p = errnode();
66122803Smckusick }
66222803Smckusick else if (tp->vclass != CLPARAM || !ISCONST(tp->paramval))
66322803Smckusick {
66422803Smckusick if (tp->paramval->tag != TERROR)
66522803Smckusick errnm(nonconst, len, repr);
66622803Smckusick p = errnode();
66722803Smckusick }
66822803Smckusick else
66922803Smckusick p = (expptr) cpexpr(tp->paramval);
67022803Smckusick
67122803Smckusick return (p);
67222803Smckusick }
67322803Smckusick
67422803Smckusick
67522803Smckusick
evaldname(dp)67622803Smckusick vexpr *evaldname(dp)
67722803Smckusick vexpr *dp;
67822803Smckusick {
67922803Smckusick static char *undefined = "%s is undefined";
68022803Smckusick static char *nonconst = "%s is not a constant";
68122803Smckusick static char *nonint = "%s is not an integer";
68222803Smckusick
68322803Smckusick register dvalue *p;
68422803Smckusick register struct Paramblock *tp;
68522803Smckusick register int len;
68622803Smckusick register char *repr;
68722803Smckusick
68822803Smckusick p = ALLOC(Dvalue);
68922803Smckusick p->tag = DVALUE;
69022803Smckusick
69122803Smckusick len = dp->dname.len;
69222803Smckusick repr = dp->dname.repr;
69322803Smckusick
69422803Smckusick tp = (struct Paramblock *) getname(len, repr);
69522803Smckusick
69622803Smckusick if (tp == NULL)
69722803Smckusick {
69822803Smckusick errnm(undefined, len, repr);
69922803Smckusick p->status = ERRVAL;
70022803Smckusick }
70122803Smckusick else if (tp->vclass != CLPARAM || !ISCONST(tp->paramval))
70222803Smckusick {
70322803Smckusick if (tp->paramval->tag != TERROR)
70422803Smckusick errnm(nonconst, len, repr);
70522803Smckusick p->status = ERRVAL;
70622803Smckusick }
70722803Smckusick else if (!ISINT(tp->paramval->constblock.vtype))
70822803Smckusick {
70922803Smckusick errnm(nonint, len, repr);
71022803Smckusick p->status = ERRVAL;
71122803Smckusick }
71222803Smckusick else
71322803Smckusick {
71422803Smckusick if ((MAXINT + MININT == -1)
71533256Sbostic && tp->paramval->constblock.constant.ci == MININT)
71622803Smckusick p->status = MINLESS1;
71722803Smckusick else
71822803Smckusick {
71922803Smckusick p->status = NORMAL;
72033256Sbostic p->value = tp->paramval->constblock.constant.ci;
72122803Smckusick }
72222803Smckusick }
72322803Smckusick
72422803Smckusick return ((vexpr *) p);
72522803Smckusick }
72622803Smckusick
72722803Smckusick
72822803Smckusick
mkdexpr(op,l,r)72922803Smckusick vexpr *mkdexpr(op, l, r)
73022803Smckusick register int op;
73122803Smckusick register vexpr *l;
73222803Smckusick register vexpr *r;
73322803Smckusick {
73422803Smckusick static char *badop = "bad operator in mkdexpr";
73522803Smckusick
73622803Smckusick register vexpr *p;
73722803Smckusick
73822803Smckusick switch (op)
73922803Smckusick {
74022803Smckusick default:
74122803Smckusick fatal(badop);
74222803Smckusick
74322803Smckusick case OPNEG:
74422803Smckusick case OPPLUS:
74522803Smckusick case OPMINUS:
74622803Smckusick case OPSTAR:
74722803Smckusick case OPSLASH:
74822803Smckusick case OPPOWER:
74922803Smckusick break;
75022803Smckusick }
75122803Smckusick
75222803Smckusick if ((l != NULL && l->tag == DERROR) || r->tag == DERROR)
75322803Smckusick {
75422803Smckusick frvexpr(l);
75522803Smckusick frvexpr(r);
75622803Smckusick p = (vexpr *) ALLOC(Derror);
75722803Smckusick p->tag = DERROR;
75822803Smckusick }
75922803Smckusick else if (op == OPNEG && r->tag == DVALUE)
76022803Smckusick {
76122803Smckusick p = negival(r);
76222803Smckusick frvexpr(r);
76322803Smckusick }
76422803Smckusick else if (op != OPNEG && l->tag == DVALUE && r->tag == DVALUE)
76522803Smckusick {
76622803Smckusick switch (op)
76722803Smckusick {
76822803Smckusick case OPPLUS:
76922803Smckusick p = addivals(l, r);
77022803Smckusick break;
77122803Smckusick
77222803Smckusick case OPMINUS:
77322803Smckusick p = subivals(l, r);
77422803Smckusick break;
77522803Smckusick
77622803Smckusick case OPSTAR:
77722803Smckusick p = mulivals(l, r);
77822803Smckusick break;
77922803Smckusick
78022803Smckusick case OPSLASH:
78122803Smckusick p = divivals(l, r);
78222803Smckusick break;
78322803Smckusick
78422803Smckusick case OPPOWER:
78522803Smckusick p = powivals(l, r);
78622803Smckusick break;
78722803Smckusick }
78822803Smckusick
78922803Smckusick frvexpr(l);
79022803Smckusick frvexpr(r);
79122803Smckusick }
79222803Smckusick else
79322803Smckusick {
79422803Smckusick p = (vexpr *) ALLOC(Dexpr);
79522803Smckusick p->tag = DEXPR;
79622803Smckusick p->dexpr.opcode = op;
79722803Smckusick p->dexpr.left = l;
79822803Smckusick p->dexpr.right = r;
79922803Smckusick }
80022803Smckusick
80122803Smckusick return (p);
80222803Smckusick }
80322803Smckusick
80422803Smckusick
80522803Smckusick
addivals(l,r)80622803Smckusick vexpr *addivals(l, r)
80722803Smckusick vexpr *l;
80822803Smckusick vexpr *r;
80922803Smckusick {
81022803Smckusick static char *badtag = "bad tag in addivals";
81122803Smckusick static char *overflow = "integer value too large";
81222803Smckusick
81322803Smckusick register int ls, rs;
81422803Smckusick register ftnint lv, rv;
81522803Smckusick register dvalue *p;
81622803Smckusick register ftnint k;
81722803Smckusick
81822803Smckusick if (l->tag != DVALUE || r->tag != DVALUE)
81922803Smckusick fatal(badtag);
82022803Smckusick
82122803Smckusick ls = l->dvalue.status;
82222803Smckusick lv = l->dvalue.value;
82322803Smckusick rs = r->dvalue.status;
82422803Smckusick rv = r->dvalue.value;
82522803Smckusick
82622803Smckusick p = ALLOC(Dvalue);
82722803Smckusick p->tag = DVALUE;
82822803Smckusick
82922803Smckusick if (ls == ERRVAL || rs == ERRVAL)
83022803Smckusick p->status = ERRVAL;
83122803Smckusick
83222803Smckusick else if (ls == NORMAL && rs == NORMAL)
83322803Smckusick {
83422803Smckusick addints(lv, rv);
83522803Smckusick if (rstatus == ERRVAL)
83622803Smckusick err(overflow);
83722803Smckusick p->status = rstatus;
83822803Smckusick p->value = rvalue;
83922803Smckusick }
84022803Smckusick
84122803Smckusick else
84222803Smckusick {
84322803Smckusick if (rs == MAXPLUS1 || rs == MINLESS1)
84422803Smckusick {
84522803Smckusick rs = ls;
84622803Smckusick rv = lv;
84722803Smckusick ls = r->dvalue.status;
84822803Smckusick }
84922803Smckusick
85022803Smckusick if (rs == NORMAL && rv == 0)
85122803Smckusick p->status = ls;
85222803Smckusick else if (ls == MAXPLUS1)
85322803Smckusick {
85422803Smckusick if (rs == NORMAL && rv < 0)
85522803Smckusick {
85622803Smckusick p->status = NORMAL;
85722803Smckusick k = MAXINT + rv;
85822803Smckusick p->value = k + 1;
85922803Smckusick }
86022803Smckusick else if (rs == MINLESS1)
86122803Smckusick {
86222803Smckusick p->status = NORMAL;
86322803Smckusick p->value = 0;
86422803Smckusick }
86522803Smckusick else
86622803Smckusick {
86722803Smckusick err(overflow);
86822803Smckusick p->status = ERRVAL;
86922803Smckusick }
87022803Smckusick }
87122803Smckusick else
87222803Smckusick {
87322803Smckusick if (rs == NORMAL && rv > 0)
87422803Smckusick {
87522803Smckusick p->status = NORMAL;
87622803Smckusick k = ( -MAXINT ) + rv;
87722803Smckusick p->value = k - 1;
87822803Smckusick }
87922803Smckusick else if (rs == MAXPLUS1)
88022803Smckusick {
88122803Smckusick p->status = NORMAL;
88222803Smckusick p->value = 0;
88322803Smckusick }
88422803Smckusick else
88522803Smckusick {
88622803Smckusick err(overflow);
88722803Smckusick p->status = ERRVAL;
88822803Smckusick }
88922803Smckusick }
89022803Smckusick }
89122803Smckusick
89222803Smckusick return ((vexpr *) p);
89322803Smckusick }
89422803Smckusick
89522803Smckusick
89622803Smckusick
negival(vp)89722803Smckusick vexpr *negival(vp)
89822803Smckusick vexpr *vp;
89922803Smckusick {
90022803Smckusick static char *badtag = "bad tag in negival";
90122803Smckusick
90222803Smckusick register int vs;
90322803Smckusick register dvalue *p;
90422803Smckusick
90522803Smckusick if (vp->tag != DVALUE)
90622803Smckusick fatal(badtag);
90722803Smckusick
90822803Smckusick vs = vp->dvalue.status;
90922803Smckusick
91022803Smckusick p = ALLOC(Dvalue);
91122803Smckusick p->tag = DVALUE;
91222803Smckusick
91322803Smckusick if (vs == ERRVAL)
91422803Smckusick p->status = ERRVAL;
91522803Smckusick else if (vs == NORMAL)
91622803Smckusick {
91722803Smckusick p->status = NORMAL;
91822803Smckusick p->value = -(vp->dvalue.value);
91922803Smckusick }
92022803Smckusick else if (vs == MAXPLUS1)
92122803Smckusick p->status = MINLESS1;
92222803Smckusick else
92322803Smckusick p->status = MAXPLUS1;
92422803Smckusick
92522803Smckusick return ((vexpr *) p);
92622803Smckusick }
92722803Smckusick
92822803Smckusick
92922803Smckusick
subivals(l,r)93022803Smckusick vexpr *subivals(l, r)
93122803Smckusick vexpr *l;
93222803Smckusick vexpr *r;
93322803Smckusick {
93422803Smckusick static char *badtag = "bad tag in subivals";
93522803Smckusick
93622803Smckusick register vexpr *p;
93722803Smckusick register vexpr *t;
93822803Smckusick
93922803Smckusick if (l->tag != DVALUE || r->tag != DVALUE)
94022803Smckusick fatal(badtag);
94122803Smckusick
94222803Smckusick t = negival(r);
94322803Smckusick p = addivals(l, t);
94422803Smckusick frvexpr(t);
94522803Smckusick
94622803Smckusick return (p);
94722803Smckusick }
94822803Smckusick
94922803Smckusick
95022803Smckusick
mulivals(l,r)95122803Smckusick vexpr *mulivals(l, r)
95222803Smckusick vexpr *l;
95322803Smckusick vexpr *r;
95422803Smckusick {
95522803Smckusick static char *badtag = "bad tag in mulivals";
95622803Smckusick static char *overflow = "integer value too large";
95722803Smckusick
95822803Smckusick register int ls, rs;
95922803Smckusick register ftnint lv, rv;
96022803Smckusick register dvalue *p;
96122803Smckusick
96222803Smckusick if (l->tag != DVALUE || r->tag != DVALUE)
96322803Smckusick fatal(badtag);
96422803Smckusick
96522803Smckusick ls = l->dvalue.status;
96622803Smckusick lv = l->dvalue.value;
96722803Smckusick rs = r->dvalue.status;
96822803Smckusick rv = r->dvalue.value;
96922803Smckusick
97022803Smckusick p = ALLOC(Dvalue);
97122803Smckusick p->tag = DVALUE;
97222803Smckusick
97322803Smckusick if (ls == ERRVAL || rs == ERRVAL)
97422803Smckusick p->status = ERRVAL;
97522803Smckusick
97622803Smckusick else if (ls == NORMAL && rs == NORMAL)
97722803Smckusick {
97822803Smckusick mulints(lv, rv);
97922803Smckusick if (rstatus == ERRVAL)
98022803Smckusick err(overflow);
98122803Smckusick p->status = rstatus;
98222803Smckusick p->value = rvalue;
98322803Smckusick }
98422803Smckusick else
98522803Smckusick {
98622803Smckusick if (rs == MAXPLUS1 || rs == MINLESS1)
98722803Smckusick {
98822803Smckusick rs = ls;
98922803Smckusick rv = lv;
99022803Smckusick ls = r->dvalue.status;
99122803Smckusick }
99222803Smckusick
99322803Smckusick if (rs == NORMAL && rv == 0)
99422803Smckusick {
99522803Smckusick p->status = NORMAL;
99622803Smckusick p->value = 0;
99722803Smckusick }
99822803Smckusick else if (rs == NORMAL && rv == 1)
99922803Smckusick p->status = ls;
100022803Smckusick else if (rs == NORMAL && rv == -1)
100122803Smckusick if (ls == MAXPLUS1)
100222803Smckusick p->status = MINLESS1;
100322803Smckusick else
100422803Smckusick p->status = MAXPLUS1;
100522803Smckusick else
100622803Smckusick {
100722803Smckusick err(overflow);
100822803Smckusick p->status = ERRVAL;
100922803Smckusick }
101022803Smckusick }
101122803Smckusick
101222803Smckusick return ((vexpr *) p);
101322803Smckusick }
101422803Smckusick
101522803Smckusick
101622803Smckusick
divivals(l,r)101722803Smckusick vexpr *divivals(l, r)
101822803Smckusick vexpr *l;
101922803Smckusick vexpr *r;
102022803Smckusick {
102122803Smckusick static char *badtag = "bad tag in divivals";
102222803Smckusick static char *zerodivide = "division by zero";
102322803Smckusick
102422803Smckusick register int ls, rs;
102522803Smckusick register ftnint lv, rv;
102622803Smckusick register dvalue *p;
102722803Smckusick register ftnint k;
102822803Smckusick register int sign;
102922803Smckusick
103022803Smckusick if (l->tag != DVALUE && r->tag != DVALUE)
103122803Smckusick fatal(badtag);
103222803Smckusick
103322803Smckusick ls = l->dvalue.status;
103422803Smckusick lv = l->dvalue.value;
103522803Smckusick rs = r->dvalue.status;
103622803Smckusick rv = r->dvalue.value;
103722803Smckusick
103822803Smckusick p = ALLOC(Dvalue);
103922803Smckusick p->tag = DVALUE;
104022803Smckusick
104122803Smckusick if (ls == ERRVAL || rs == ERRVAL)
104222803Smckusick p->status = ERRVAL;
104322803Smckusick else if (rs == NORMAL)
104422803Smckusick {
104522803Smckusick if (rv == 0)
104622803Smckusick {
104722803Smckusick err(zerodivide);
104822803Smckusick p->status = ERRVAL;
104922803Smckusick }
105022803Smckusick else if (ls == NORMAL)
105122803Smckusick {
105222803Smckusick p->status = NORMAL;
105322803Smckusick p->value = lv / rv;
105422803Smckusick }
105522803Smckusick else if (rv == 1)
105622803Smckusick p->status = ls;
105722803Smckusick else if (rv == -1)
105822803Smckusick if (ls == MAXPLUS1)
105922803Smckusick p->status = MINLESS1;
106022803Smckusick else
106122803Smckusick p->status = MAXPLUS1;
106222803Smckusick else
106322803Smckusick {
106422803Smckusick p->status = NORMAL;
106522803Smckusick
106622803Smckusick if (ls == MAXPLUS1)
106722803Smckusick sign = 1;
106822803Smckusick else
106922803Smckusick sign = -1;
107022803Smckusick
107122803Smckusick if (rv < 0)
107222803Smckusick {
107322803Smckusick rv = -rv;
107422803Smckusick sign = -sign;
107522803Smckusick }
107622803Smckusick
107722803Smckusick k = MAXINT - rv;
107822803Smckusick p->value = sign * ((k + 1)/rv + 1);
107922803Smckusick }
108022803Smckusick }
108122803Smckusick else
108222803Smckusick {
108322803Smckusick p->status = NORMAL;
108422803Smckusick if (ls == NORMAL)
108522803Smckusick p->value = 0;
108622803Smckusick else if ((ls == MAXPLUS1 && rs == MAXPLUS1)
108722803Smckusick || (ls == MINLESS1 && rs == MINLESS1))
108822803Smckusick p->value = 1;
108922803Smckusick else
109022803Smckusick p->value = -1;
109122803Smckusick }
109222803Smckusick
109322803Smckusick return ((vexpr *) p);
109422803Smckusick }
109522803Smckusick
109622803Smckusick
109722803Smckusick
powivals(l,r)109822803Smckusick vexpr *powivals(l, r)
109922803Smckusick vexpr *l;
110022803Smckusick vexpr *r;
110122803Smckusick {
110222803Smckusick static char *badtag = "bad tag in powivals";
110322803Smckusick static char *zerozero = "zero raised to the zero-th power";
110422803Smckusick static char *zeroneg = "zero raised to a negative power";
110522803Smckusick static char *overflow = "integer value too large";
110622803Smckusick
110722803Smckusick register int ls, rs;
110822803Smckusick register ftnint lv, rv;
110922803Smckusick register dvalue *p;
111022803Smckusick
111122803Smckusick if (l->tag != DVALUE || r->tag != DVALUE)
111222803Smckusick fatal(badtag);
111322803Smckusick
111422803Smckusick ls = l->dvalue.status;
111522803Smckusick lv = l->dvalue.value;
111622803Smckusick rs = r->dvalue.status;
111722803Smckusick rv = r->dvalue.value;
111822803Smckusick
111922803Smckusick p = ALLOC(Dvalue);
112022803Smckusick p->tag = DVALUE;
112122803Smckusick
112222803Smckusick if (ls == ERRVAL || rs == ERRVAL)
112322803Smckusick p->status = ERRVAL;
112422803Smckusick
112522803Smckusick else if (ls == NORMAL)
112622803Smckusick {
112722803Smckusick if (lv == 1)
112822803Smckusick {
112922803Smckusick p->status = NORMAL;
113022803Smckusick p->value = 1;
113122803Smckusick }
113222803Smckusick else if (lv == 0)
113322803Smckusick {
113422803Smckusick if (rs == MAXPLUS1 || (rs == NORMAL && rv > 0))
113522803Smckusick {
113622803Smckusick p->status = NORMAL;
113722803Smckusick p->value = 0;
113822803Smckusick }
113922803Smckusick else if (rs == NORMAL && rv == 0)
114022803Smckusick {
114122803Smckusick warn(zerozero);
114222803Smckusick p->status = NORMAL;
114322803Smckusick p->value = 1;
114422803Smckusick }
114522803Smckusick else
114622803Smckusick {
114722803Smckusick err(zeroneg);
114822803Smckusick p->status = ERRVAL;
114922803Smckusick }
115022803Smckusick }
115122803Smckusick else if (lv == -1)
115222803Smckusick {
115322803Smckusick p->status = NORMAL;
115422803Smckusick if (rs == NORMAL)
115522803Smckusick {
115622803Smckusick if (rv < 0) rv = -rv;
115722803Smckusick if (rv % 2 == 0)
115822803Smckusick p->value = 1;
115922803Smckusick else
116022803Smckusick p->value = -1;
116122803Smckusick }
116222803Smckusick else
116322803Smckusick # if (MAXINT % 2 == 1)
116422803Smckusick p->value = 1;
116522803Smckusick # else
116622803Smckusick p->value = -1;
116722803Smckusick # endif
116822803Smckusick }
116922803Smckusick else
117022803Smckusick {
117122803Smckusick if (rs == NORMAL && rv > 0)
117222803Smckusick {
117322803Smckusick rstatus = NORMAL;
117422803Smckusick rvalue = lv;
117522803Smckusick while (--rv && rstatus == NORMAL)
117622803Smckusick mulints(rvalue, lv);
117722803Smckusick if (rv == 0 && rstatus != ERRVAL)
117822803Smckusick {
117922803Smckusick p->status = rstatus;
118022803Smckusick p->value = rvalue;
118122803Smckusick }
118222803Smckusick else
118322803Smckusick {
118422803Smckusick err(overflow);
118522803Smckusick p->status = ERRVAL;
118622803Smckusick }
118722803Smckusick }
118822803Smckusick else if (rs == MAXPLUS1)
118922803Smckusick {
119022803Smckusick err(overflow);
119122803Smckusick p->status = ERRVAL;
119222803Smckusick }
119322803Smckusick else if (rs == NORMAL && rv == 0)
119422803Smckusick {
119522803Smckusick p->status = NORMAL;
119622803Smckusick p->value = 1;
119722803Smckusick }
119822803Smckusick else
119922803Smckusick {
120022803Smckusick p->status = NORMAL;
120122803Smckusick p->value = 0;
120222803Smckusick }
120322803Smckusick }
120422803Smckusick }
120522803Smckusick
120622803Smckusick else
120722803Smckusick {
120822803Smckusick if (rs == MAXPLUS1 || (rs == NORMAL && rv > 1))
120922803Smckusick {
121022803Smckusick err(overflow);
121122803Smckusick p->status = ERRVAL;
121222803Smckusick }
121322803Smckusick else if (rs == NORMAL && rv == 1)
121422803Smckusick p->status = ls;
121522803Smckusick else if (rs == NORMAL && rv == 0)
121622803Smckusick {
121722803Smckusick p->status = NORMAL;
121822803Smckusick p->value = 1;
121922803Smckusick }
122022803Smckusick else
122122803Smckusick {
122222803Smckusick p->status = NORMAL;
122322803Smckusick p->value = 0;
122422803Smckusick }
122522803Smckusick }
122622803Smckusick
122722803Smckusick return ((vexpr *) p);
122822803Smckusick }
122922803Smckusick
123022803Smckusick
123122803Smckusick
123222803Smckusick /* Addints adds two integer values. */
123322803Smckusick
addints(i,j)123422803Smckusick addints(i, j)
123522803Smckusick register ftnint i, j;
123622803Smckusick {
123722803Smckusick register ftnint margin;
123822803Smckusick
123922803Smckusick if (i == 0)
124022803Smckusick {
124122803Smckusick rstatus = NORMAL;
124222803Smckusick rvalue = j;
124322803Smckusick }
124422803Smckusick else if (i > 0)
124522803Smckusick {
124622803Smckusick margin = MAXINT - i;
124722803Smckusick if (j <= margin)
124822803Smckusick {
124922803Smckusick rstatus = NORMAL;
125022803Smckusick rvalue = i + j;
125122803Smckusick }
125222803Smckusick else if (j == margin + 1)
125322803Smckusick rstatus = MAXPLUS1;
125422803Smckusick else
125522803Smckusick rstatus = ERRVAL;
125622803Smckusick }
125722803Smckusick else
125822803Smckusick {
125922803Smckusick margin = ( -MAXINT ) - i;
126022803Smckusick if (j >= margin)
126122803Smckusick {
126222803Smckusick rstatus = NORMAL;
126322803Smckusick rvalue = i + j;
126422803Smckusick }
126522803Smckusick else if (j == margin - 1)
126622803Smckusick rstatus = MINLESS1;
126722803Smckusick else
126822803Smckusick rstatus = ERRVAL;
126922803Smckusick }
127022803Smckusick
127122803Smckusick return;
127222803Smckusick }
127322803Smckusick
127422803Smckusick
127522803Smckusick
127622803Smckusick /* Mulints multiplies two integer values */
127722803Smckusick
mulints(i,j)127822803Smckusick mulints(i, j)
127922803Smckusick register ftnint i, j;
128022803Smckusick {
128122803Smckusick register ftnint sign;
128222803Smckusick register ftnint margin;
128322803Smckusick
128422803Smckusick if (i == 0 || j == 0)
128522803Smckusick {
128622803Smckusick rstatus = NORMAL;
128722803Smckusick rvalue = 0;
128822803Smckusick }
128922803Smckusick else
129022803Smckusick {
129122803Smckusick if ((i > 0 && j > 0) || (i < 0 && j < 0))
129222803Smckusick sign = 1;
129322803Smckusick else
129422803Smckusick sign = -1;
129522803Smckusick
129622803Smckusick if (i < 0) i = -i;
129722803Smckusick if (j < 0) j = -j;
129822803Smckusick
129922803Smckusick margin = MAXINT - i;
130022803Smckusick margin = (margin + 1) / i;
130122803Smckusick
130222803Smckusick if (j <= margin)
130322803Smckusick {
130422803Smckusick rstatus = NORMAL;
130522803Smckusick rvalue = i * j * sign;
130622803Smckusick }
130722803Smckusick else if (j - 1 == margin)
130822803Smckusick {
130922803Smckusick margin = i*margin - 1;
131022803Smckusick if (margin == MAXINT - i)
131122803Smckusick if (sign > 0)
131222803Smckusick rstatus = MAXPLUS1;
131322803Smckusick else
131422803Smckusick rstatus = MINLESS1;
131522803Smckusick else
131622803Smckusick {
131722803Smckusick rstatus = NORMAL;
131822803Smckusick rvalue = i * j * sign;
131922803Smckusick }
132022803Smckusick }
132122803Smckusick else
132222803Smckusick rstatus = ERRVAL;
132322803Smckusick }
132422803Smckusick
132522803Smckusick return;
132622803Smckusick }
132722803Smckusick
132822803Smckusick
132922803Smckusick
133022803Smckusick vexpr *
evalvexpr(ep)133122803Smckusick evalvexpr(ep)
133222803Smckusick vexpr *ep;
133322803Smckusick {
133422803Smckusick register vexpr *p;
133522803Smckusick register vexpr *l, *r;
133622803Smckusick
133722803Smckusick switch (ep->tag)
133822803Smckusick {
133922803Smckusick case DVALUE:
134022803Smckusick p = cpdvalue(ep);
134122803Smckusick break;
134222803Smckusick
134322803Smckusick case DVAR:
134422803Smckusick p = cpdvalue((vexpr *) ep->dvar.valp);
134522803Smckusick break;
134622803Smckusick
134722803Smckusick case DNAME:
134822803Smckusick p = evaldname(ep);
134922803Smckusick break;
135022803Smckusick
135122803Smckusick case DEXPR:
135222803Smckusick if (ep->dexpr.left == NULL)
135322803Smckusick l = NULL;
135422803Smckusick else
135522803Smckusick l = evalvexpr(ep->dexpr.left);
135622803Smckusick
135722803Smckusick if (ep->dexpr.right == NULL)
135822803Smckusick r = NULL;
135922803Smckusick else
136022803Smckusick r = evalvexpr(ep->dexpr.right);
136122803Smckusick
136222803Smckusick switch (ep->dexpr.opcode)
136322803Smckusick {
136422803Smckusick case OPNEG:
136522803Smckusick p = negival(r);
136622803Smckusick break;
136722803Smckusick
136822803Smckusick case OPPLUS:
136922803Smckusick p = addivals(l, r);
137022803Smckusick break;
137122803Smckusick
137222803Smckusick case OPMINUS:
137322803Smckusick p = subivals(l, r);
137422803Smckusick break;
137522803Smckusick
137622803Smckusick case OPSTAR:
137722803Smckusick p = mulivals(l, r);
137822803Smckusick break;
137922803Smckusick
138022803Smckusick case OPSLASH:
138122803Smckusick p = divivals(l, r);
138222803Smckusick break;
138322803Smckusick
138422803Smckusick case OPPOWER:
138522803Smckusick p = powivals(l, r);
138622803Smckusick break;
138722803Smckusick }
138822803Smckusick
138922803Smckusick frvexpr(l);
139022803Smckusick frvexpr(r);
139122803Smckusick break;
139222803Smckusick
139322803Smckusick case DERROR:
139422803Smckusick p = (vexpr *) ALLOC(Dvalue);
139522803Smckusick p->tag = DVALUE;
139622803Smckusick p->dvalue.status = ERRVAL;
139722803Smckusick break;
139822803Smckusick }
139922803Smckusick
140022803Smckusick return (p);
140122803Smckusick }
140222803Smckusick
140322803Smckusick
140422803Smckusick
140522803Smckusick vexpr *
refrigdname(vp)140622803Smckusick refrigdname(vp)
140722803Smckusick vexpr *vp;
140822803Smckusick {
140922803Smckusick register vexpr *p;
141022803Smckusick register int len;
141122803Smckusick register char *repr;
141222803Smckusick register int found;
141322803Smckusick register dovars *dvp;
141422803Smckusick
141522803Smckusick len = vp->dname.len;
141622803Smckusick repr = vp->dname.repr;
141722803Smckusick
141822803Smckusick found = NO;
141922803Smckusick dvp = dvlist;
142022803Smckusick while (found == NO && dvp != NULL)
142122803Smckusick {
142222803Smckusick if (len == dvp->len && eqn(len, repr, dvp->repr))
142322803Smckusick found = YES;
142422803Smckusick else
142522803Smckusick dvp = dvp->next;
142622803Smckusick }
142722803Smckusick
142822803Smckusick if (found == YES)
142922803Smckusick {
143022803Smckusick p = (vexpr *) ALLOC(Dvar);
143122803Smckusick p->tag = DVAR;
143222803Smckusick p->dvar.valp = dvp->valp;
143322803Smckusick }
143422803Smckusick else
143522803Smckusick {
143622803Smckusick p = evaldname(vp);
143722803Smckusick if (p->dvalue.status == ERRVAL)
143822803Smckusick dataerror = YES;
143922803Smckusick }
144022803Smckusick
144122803Smckusick return (p);
144222803Smckusick }
144322803Smckusick
144422803Smckusick
144522803Smckusick
refrigvexpr(vpp)144622803Smckusick refrigvexpr(vpp)
144722803Smckusick vexpr **vpp;
144822803Smckusick {
144922803Smckusick register vexpr *vp;
145022803Smckusick
145122803Smckusick vp = *vpp;
145222803Smckusick
145322803Smckusick switch (vp->tag)
145422803Smckusick {
145522803Smckusick case DVALUE:
145622803Smckusick case DVAR:
145722803Smckusick case DERROR:
145822803Smckusick break;
145922803Smckusick
146022803Smckusick case DEXPR:
146122803Smckusick refrigvexpr( &(vp->dexpr.left) );
146222803Smckusick refrigvexpr( &(vp->dexpr.right) );
146322803Smckusick break;
146422803Smckusick
146522803Smckusick case DNAME:
146622803Smckusick *(vpp) = refrigdname(vp);
146722803Smckusick frvexpr(vp);
146822803Smckusick break;
146922803Smckusick }
147022803Smckusick
147122803Smckusick return;
147222803Smckusick }
147322803Smckusick
147422803Smckusick
147522803Smckusick
147622803Smckusick int
chkvar(np,sname)147722803Smckusick chkvar(np, sname)
147822803Smckusick Namep np;
147922803Smckusick char *sname;
148022803Smckusick {
148122803Smckusick static char *nonvar = "%s is not a variable";
148222803Smckusick static char *arginit = "attempt to initialize a dummy argument: %s";
148322803Smckusick static char *autoinit = "attempt to initialize an automatic variable: %s";
148422803Smckusick static char *badclass = "bad class in chkvar";
148522803Smckusick
148622803Smckusick register int status;
148722803Smckusick register struct Dimblock *dp;
148822803Smckusick register int i;
148922803Smckusick
149022803Smckusick status = YES;
149122803Smckusick
149222803Smckusick if (np->vclass == CLUNKNOWN
149322803Smckusick || (np->vclass == CLVAR && !np->vdcldone))
149422803Smckusick vardcl(np);
149522803Smckusick
149622803Smckusick if (np->vstg == STGARG)
149722803Smckusick {
149822803Smckusick errstr(arginit, sname);
149922803Smckusick dataerror = YES;
150022803Smckusick status = NO;
150122803Smckusick }
150222803Smckusick else if (np->vclass != CLVAR)
150322803Smckusick {
150422803Smckusick errstr(nonvar, sname);
150522803Smckusick dataerror = YES;
150622803Smckusick status = NO;
150722803Smckusick }
150822803Smckusick else if (np->vstg == STGAUTO)
150922803Smckusick {
151022803Smckusick errstr(autoinit, sname);
151122803Smckusick dataerror = YES;
151222803Smckusick status = NO;
151322803Smckusick }
151422803Smckusick else if (np->vstg != STGBSS && np->vstg != STGINIT
151522803Smckusick && np->vstg != STGCOMMON && np->vstg != STGEQUIV)
151622803Smckusick {
151722803Smckusick fatal(badclass);
151822803Smckusick }
151922803Smckusick else
152022803Smckusick {
152122803Smckusick switch (np->vtype)
152222803Smckusick {
152322803Smckusick case TYERROR:
152422803Smckusick status = NO;
152522803Smckusick dataerror = YES;
152622803Smckusick break;
152722803Smckusick
152822803Smckusick case TYSHORT:
152922803Smckusick case TYLONG:
153022803Smckusick case TYREAL:
153122803Smckusick case TYDREAL:
153222803Smckusick case TYCOMPLEX:
153322803Smckusick case TYDCOMPLEX:
153422803Smckusick case TYLOGICAL:
153522803Smckusick case TYCHAR:
153622803Smckusick dp = np->vdim;
153722803Smckusick if (dp != NULL)
153822803Smckusick {
153922803Smckusick if (dp->nelt == NULL || !ISICON(dp->nelt))
154022803Smckusick {
154122803Smckusick status = NO;
154222803Smckusick dataerror = YES;
154322803Smckusick }
154422803Smckusick }
154522803Smckusick break;
154622803Smckusick
154722803Smckusick default:
154822803Smckusick badtype("chkvar", np->vtype);
154922803Smckusick }
155022803Smckusick }
155122803Smckusick
155222803Smckusick return (status);
155322803Smckusick }
155422803Smckusick
155522803Smckusick
155622803Smckusick
refrigsubs(ap,sname)155722803Smckusick refrigsubs(ap, sname)
155822803Smckusick aelt *ap;
155922803Smckusick char *sname;
156022803Smckusick {
156122803Smckusick static char *nonarray = "subscripts on a simple variable: %s";
156222803Smckusick static char *toofew = "not enough subscripts on %s";
156322803Smckusick static char *toomany = "too many subscripts on %s";
156422803Smckusick
156522803Smckusick register vlist *subp;
156622803Smckusick register int nsubs;
156722803Smckusick register Namep np;
156822803Smckusick register struct Dimblock *dp;
156922803Smckusick register int i;
157022803Smckusick
157122803Smckusick np = ap->var;
157222803Smckusick dp = np->vdim;
157322803Smckusick
157422803Smckusick if (ap->subs != NULL)
157522803Smckusick {
157622803Smckusick if (np->vdim == NULL)
157722803Smckusick {
157822803Smckusick errstr(nonarray, sname);
157922803Smckusick dataerror = YES;
158022803Smckusick }
158122803Smckusick else
158222803Smckusick {
158322803Smckusick nsubs = 0;
158422803Smckusick subp = ap->subs;
158522803Smckusick while (subp != NULL)
158622803Smckusick {
158722803Smckusick nsubs++;
158822803Smckusick refrigvexpr( &(subp->val) );
158922803Smckusick subp = subp->next;
159022803Smckusick }
159122803Smckusick
159222803Smckusick if (dp->ndim != nsubs)
159322803Smckusick {
159422803Smckusick if (np->vdim->ndim > nsubs)
159522803Smckusick errstr(toofew, sname);
159622803Smckusick else
159722803Smckusick errstr(toomany, sname);
159822803Smckusick dataerror = YES;
159922803Smckusick }
160022803Smckusick else if (dp->baseoffset == NULL || !ISICON(dp->baseoffset))
160122803Smckusick dataerror = YES;
160222803Smckusick else
160322803Smckusick {
160422803Smckusick i = dp->ndim;
160522803Smckusick while (i-- > 0)
160622803Smckusick {
160722803Smckusick if (dp->dims[i].dimsize == NULL
160822803Smckusick || !ISICON(dp->dims[i].dimsize))
160922803Smckusick dataerror = YES;
161022803Smckusick }
161122803Smckusick }
161222803Smckusick }
161322803Smckusick }
161422803Smckusick
161522803Smckusick return;
161622803Smckusick }
161722803Smckusick
161822803Smckusick
161922803Smckusick
refrigrange(ap,sname)162022803Smckusick refrigrange(ap, sname)
162122803Smckusick aelt *ap;
162222803Smckusick char *sname;
162322803Smckusick {
162422803Smckusick static char *nonstr = "substring of a noncharacter variable: %s";
162522803Smckusick static char *array = "substring applied to an array: %s";
162622803Smckusick
162722803Smckusick register Namep np;
162822803Smckusick register dvalue *t;
162922803Smckusick register rpair *rp;
163022803Smckusick
163122803Smckusick if (ap->range != NULL)
163222803Smckusick {
163322803Smckusick np = ap->var;
163422803Smckusick if (np->vtype != TYCHAR)
163522803Smckusick {
163622803Smckusick errstr(nonstr, sname);
163722803Smckusick dataerror = YES;
163822803Smckusick }
163922803Smckusick else if (ap->subs == NULL && np->vdim != NULL)
164022803Smckusick {
164122803Smckusick errstr(array, sname);
164222803Smckusick dataerror = YES;
164322803Smckusick }
164422803Smckusick else
164522803Smckusick {
164622803Smckusick rp = ap->range;
164722803Smckusick
164822803Smckusick if (rp->low != NULL)
164922803Smckusick refrigvexpr( &(rp->low) );
165022803Smckusick else
165122803Smckusick {
165222803Smckusick t = ALLOC(Dvalue);
165322803Smckusick t->tag = DVALUE;
165422803Smckusick t->status = NORMAL;
165522803Smckusick t->value = 1;
165622803Smckusick rp->low = (vexpr *) t;
165722803Smckusick }
165822803Smckusick
165922803Smckusick if (rp->high != NULL)
166022803Smckusick refrigvexpr( &(rp->high) );
166122803Smckusick else
166222803Smckusick {
166322803Smckusick if (!ISICON(np->vleng))
166422803Smckusick {
166522803Smckusick rp->high = (vexpr *) ALLOC(Derror);
166622803Smckusick rp->high->tag = DERROR;
166722803Smckusick }
166822803Smckusick else
166922803Smckusick {
167022803Smckusick t = ALLOC(Dvalue);
167122803Smckusick t->tag = DVALUE;
167222803Smckusick t->status = NORMAL;
167333256Sbostic t->value = np->vleng->constblock.constant.ci;
167422803Smckusick rp->high = (vexpr *) t;
167522803Smckusick }
167622803Smckusick }
167722803Smckusick }
167822803Smckusick }
167922803Smckusick
168022803Smckusick return;
168122803Smckusick }
168222803Smckusick
168322803Smckusick
168422803Smckusick
refrigaelt(ap)168522803Smckusick refrigaelt(ap)
168622803Smckusick aelt *ap;
168722803Smckusick {
168822803Smckusick register Namep np;
168922803Smckusick register char *bp, *sp;
169022803Smckusick register int len;
169122803Smckusick char buff[VL+1];
169222803Smckusick
169322803Smckusick np = ap->var;
169422803Smckusick
169522803Smckusick len = 0;
169622803Smckusick bp = buff;
169722803Smckusick sp = np->varname;
169822803Smckusick while (len < VL && *sp != ' ' && *sp != '\0')
169922803Smckusick {
170022803Smckusick *bp++ = *sp++;
170122803Smckusick len++;
170222803Smckusick }
170322803Smckusick *bp = '\0';
170422803Smckusick
170522803Smckusick if (chkvar(np, buff))
170622803Smckusick {
170722803Smckusick refrigsubs(ap, buff);
170822803Smckusick refrigrange(ap, buff);
170922803Smckusick }
171022803Smckusick
171122803Smckusick return;
171222803Smckusick }
171322803Smckusick
171422803Smckusick
171522803Smckusick
refrigdo(dp)171622803Smckusick refrigdo(dp)
171722803Smckusick dolist *dp;
171822803Smckusick {
171922803Smckusick static char *duplicates = "implied DO variable %s redefined";
172022803Smckusick static char *nonvar = "%s is not a variable";
172122803Smckusick static char *nonint = "%s is not integer";
172222803Smckusick
172322803Smckusick register int len;
172422803Smckusick register char *repr;
172522803Smckusick register int found;
172622803Smckusick register dovars *dvp;
172722803Smckusick register Namep np;
172822803Smckusick register dovars *t;
172922803Smckusick
173022803Smckusick refrigvexpr( &(dp->init) );
173122803Smckusick refrigvexpr( &(dp->limit) );
173222803Smckusick refrigvexpr( &(dp->step) );
173322803Smckusick
173422803Smckusick len = dp->dovar->dname.len;
173522803Smckusick repr = dp->dovar->dname.repr;
173622803Smckusick
173722803Smckusick found = NO;
173822803Smckusick dvp = dvlist;
173922803Smckusick while (found == NO && dvp != NULL)
174022803Smckusick if (len == dvp->len && eqn(len, repr, dvp->repr))
174122803Smckusick found = YES;
174222803Smckusick else
174322803Smckusick dvp = dvp->next;
174422803Smckusick
174522803Smckusick if (found == YES)
174622803Smckusick {
174722803Smckusick errnm(duplicates, len, repr);
174822803Smckusick dataerror = YES;
174922803Smckusick }
175022803Smckusick else
175122803Smckusick {
175222803Smckusick np = getname(len, repr);
175322803Smckusick if (np == NULL)
175422803Smckusick {
175522803Smckusick if (!ISINT(impltype[letter(*repr)]))
175622803Smckusick warnnm(nonint, len, repr);
175722803Smckusick }
175822803Smckusick else
175922803Smckusick {
176022803Smckusick if (np->vclass == CLUNKNOWN)
176122803Smckusick vardcl(np);
176222803Smckusick if (np->vclass != CLVAR)
176322803Smckusick warnnm(nonvar, len, repr);
176422803Smckusick else if (!ISINT(np->vtype))
176522803Smckusick warnnm(nonint, len, repr);
176622803Smckusick }
176722803Smckusick }
176822803Smckusick
176922803Smckusick t = ALLOC(DoVars);
177022803Smckusick t->next = dvlist;
177122803Smckusick t->len = len;
177222803Smckusick t->repr = repr;
177322803Smckusick t->valp = ALLOC(Dvalue);
177422803Smckusick t->valp->tag = DVALUE;
177522803Smckusick dp->dovar = (vexpr *) t->valp;
177622803Smckusick
177722803Smckusick dvlist = t;
177822803Smckusick
177922803Smckusick refriglvals(dp->elts);
178022803Smckusick
178122803Smckusick dvlist = t->next;
178222803Smckusick free((char *) t);
178322803Smckusick
178422803Smckusick return;
178522803Smckusick }
178622803Smckusick
178722803Smckusick
178822803Smckusick
refriglvals(lvals)178922803Smckusick refriglvals(lvals)
179022803Smckusick elist *lvals;
179122803Smckusick {
179222803Smckusick register elist *top;
179322803Smckusick
179422803Smckusick top = lvals;
179522803Smckusick
179622803Smckusick while (top != NULL)
179722803Smckusick {
179822803Smckusick if (top->elt->tag == SIMPLE)
179922803Smckusick refrigaelt((aelt *) top->elt);
180022803Smckusick else
180122803Smckusick refrigdo((dolist *) top->elt);
180222803Smckusick
180322803Smckusick top = top->next;
180422803Smckusick }
180522803Smckusick
180622803Smckusick return;
180722803Smckusick }
180822803Smckusick
180922803Smckusick
181022803Smckusick
181122803Smckusick /* Refrig freezes name/value bindings in the DATA name list */
181222803Smckusick
181322803Smckusick
refrig(lvals)181422803Smckusick refrig(lvals)
181522803Smckusick elist *lvals;
181622803Smckusick {
181722803Smckusick dvlist = NULL;
181822803Smckusick refriglvals(lvals);
181922803Smckusick return;
182022803Smckusick }
182122803Smckusick
182222803Smckusick
182322803Smckusick
182422803Smckusick ftnint
indexer(ap)182522803Smckusick indexer(ap)
182622803Smckusick aelt *ap;
182722803Smckusick {
182822803Smckusick static char *badvar = "bad variable in indexer";
182922803Smckusick static char *boundserror = "subscript out of bounds";
183022803Smckusick
183122803Smckusick register ftnint index;
183222803Smckusick register vlist *sp;
183322803Smckusick register Namep np;
183422803Smckusick register struct Dimblock *dp;
183522803Smckusick register int i;
183622803Smckusick register dvalue *vp;
183722803Smckusick register ftnint size;
183822803Smckusick ftnint sub[MAXDIM];
183922803Smckusick
184022803Smckusick sp = ap->subs;
184122803Smckusick if (sp == NULL) return (0);
184222803Smckusick
184322803Smckusick np = ap->var;
184422803Smckusick dp = np->vdim;
184522803Smckusick
184622803Smckusick if (dp == NULL)
184722803Smckusick fatal(badvar);
184822803Smckusick
184922803Smckusick i = 0;
185022803Smckusick while (sp != NULL)
185122803Smckusick {
185222803Smckusick vp = (dvalue *) evalvexpr(sp->val);
185322803Smckusick
185422803Smckusick if (vp->status == NORMAL)
185522803Smckusick sub[i++] = vp->value;
185622803Smckusick else if ((MININT + MAXINT == -1) && vp->status == MINLESS1)
185722803Smckusick sub[i++] = MININT;
185822803Smckusick else
185922803Smckusick {
186022803Smckusick frvexpr((vexpr *) vp);
186122803Smckusick return (-1);
186222803Smckusick }
186322803Smckusick
186422803Smckusick frvexpr((vexpr *) vp);
186522803Smckusick sp = sp->next;
186622803Smckusick }
186722803Smckusick
186822803Smckusick index = sub[--i];
186922803Smckusick while (i-- > 0)
187022803Smckusick {
187133256Sbostic size = dp->dims[i].dimsize->constblock.constant.ci;
187222803Smckusick index = sub[i] + index * size;
187322803Smckusick }
187422803Smckusick
187533256Sbostic index -= dp->baseoffset->constblock.constant.ci;
187622803Smckusick
187733256Sbostic if (index < 0 || index >= dp->nelt->constblock.constant.ci)
187822803Smckusick {
187922803Smckusick err(boundserror);
188022803Smckusick return (-1);
188122803Smckusick }
188222803Smckusick
188322803Smckusick return (index);
188422803Smckusick }
188522803Smckusick
188622803Smckusick
188722803Smckusick
savedata(lvals,rvals)188822803Smckusick savedata(lvals, rvals)
188922803Smckusick elist *lvals;
189022803Smckusick vallist *rvals;
189122803Smckusick {
189222803Smckusick static char *toomany = "more data values than data items";
189322803Smckusick
189422803Smckusick register elist *top;
189522803Smckusick
189622803Smckusick dataerror = NO;
189722803Smckusick badvalue = NO;
189822803Smckusick
189922803Smckusick lvals = revelist(lvals);
190022803Smckusick grvals = revrvals(rvals);
190122803Smckusick
190222803Smckusick refrig(lvals);
190322803Smckusick
190422803Smckusick if (!dataerror)
190522803Smckusick outdata(lvals);
190622803Smckusick
190722803Smckusick frelist(lvals);
190822803Smckusick
190922803Smckusick while (grvals != NULL && dataerror == NO)
191022803Smckusick {
191122803Smckusick if (grvals->status != NORMAL)
191222803Smckusick dataerror = YES;
191322803Smckusick else if (grvals->repl <= 0)
191422803Smckusick grvals = grvals->next;
191522803Smckusick else
191622803Smckusick {
191722803Smckusick err(toomany);
191822803Smckusick dataerror = YES;
191922803Smckusick }
192022803Smckusick }
192122803Smckusick
192222803Smckusick frvallist(grvals);
192322803Smckusick
192422803Smckusick return;
192522803Smckusick }
192622803Smckusick
192722803Smckusick
192822803Smckusick
setdfiles(np)192922803Smckusick setdfiles(np)
193022803Smckusick register Namep np;
193122803Smckusick {
193222803Smckusick register struct Extsym *cp;
193322803Smckusick register struct Equivblock *ep;
193422803Smckusick register int stg;
193522803Smckusick register int type;
193622803Smckusick register ftnint typelen;
193722803Smckusick register ftnint nelt;
193822803Smckusick register ftnint varsize;
193922803Smckusick
194022803Smckusick stg = np->vstg;
194122803Smckusick
194222803Smckusick if (stg == STGBSS || stg == STGINIT)
194322803Smckusick {
194422803Smckusick datafile = vdatafile;
194522803Smckusick chkfile = vchkfile;
194622803Smckusick if (np->init == YES)
194722803Smckusick base = np->initoffset;
194822803Smckusick else
194922803Smckusick {
195022803Smckusick np->init = YES;
195122803Smckusick np->initoffset = base = vdatahwm;
195222803Smckusick if (np->vdim != NULL)
195333256Sbostic nelt = np->vdim->nelt->constblock.constant.ci;
195422803Smckusick else
195522803Smckusick nelt = 1;
195622803Smckusick type = np->vtype;
195722803Smckusick if (type == TYCHAR)
195833256Sbostic typelen = np->vleng->constblock.constant.ci;
195922803Smckusick else if (type == TYLOGICAL)
196022803Smckusick typelen = typesize[tylogical];
196122803Smckusick else
196222803Smckusick typelen = typesize[type];
196322803Smckusick varsize = nelt * typelen;
196422803Smckusick vdatahwm += varsize;
196522803Smckusick }
196622803Smckusick }
196722803Smckusick else if (stg == STGEQUIV)
196822803Smckusick {
196922803Smckusick datafile = vdatafile;
197022803Smckusick chkfile = vchkfile;
197122803Smckusick ep = &eqvclass[np->vardesc.varno];
197222803Smckusick if (ep->init == YES)
197322803Smckusick base = ep->initoffset;
197422803Smckusick else
197522803Smckusick {
197622803Smckusick ep->init = YES;
197722803Smckusick ep->initoffset = base = vdatahwm;
197822803Smckusick vdatahwm += ep->eqvleng;
197922803Smckusick }
198022803Smckusick base += np->voffset;
198122803Smckusick }
198222803Smckusick else if (stg == STGCOMMON)
198322803Smckusick {
198422803Smckusick datafile = cdatafile;
198522803Smckusick chkfile = cchkfile;
198622803Smckusick cp = &extsymtab[np->vardesc.varno];
198722803Smckusick if (cp->init == YES)
198822803Smckusick base = cp->initoffset;
198922803Smckusick else
199022803Smckusick {
199122803Smckusick cp->init = YES;
199222803Smckusick cp->initoffset = base = cdatahwm;
199322803Smckusick cdatahwm += cp->maxleng;
199422803Smckusick }
199522803Smckusick base += np->voffset;
199622803Smckusick }
199722803Smckusick
199822803Smckusick return;
199922803Smckusick }
200022803Smckusick
200122803Smckusick
200222803Smckusick
wrtdata(offset,repl,len,constant)200333256Sbostic wrtdata(offset, repl, len, constant)
200422803Smckusick long offset;
200522803Smckusick ftnint repl;
200622803Smckusick ftnint len;
200733256Sbostic char *constant;
200822803Smckusick {
200922803Smckusick static char *badoffset = "bad offset in wrtdata";
201022803Smckusick static char *toomuch = "too much data";
201122803Smckusick static char *readerror = "read error on tmp file";
201222803Smckusick static char *writeerror = "write error on tmp file";
201322803Smckusick static char *seekerror = "seek error on tmp file";
201422803Smckusick
201522803Smckusick register ftnint k;
201622803Smckusick long lastbyte;
201722803Smckusick int bitpos;
201822803Smckusick long chkoff;
201922803Smckusick long lastoff;
202022803Smckusick long chklen;
202122803Smckusick long pos;
202222803Smckusick int n;
202322803Smckusick ftnint nbytes;
202422803Smckusick int mask;
202522803Smckusick register int i;
202622803Smckusick char overlap;
202722803Smckusick char allzero;
202822803Smckusick char buff[BUFSIZ];
202922803Smckusick
203022803Smckusick if (offset < 0)
203122803Smckusick fatal(badoffset);
203222803Smckusick
203322803Smckusick overlap = NO;
203422803Smckusick
203522803Smckusick k = repl * len;
203622803Smckusick lastbyte = offset + k - 1;
203722803Smckusick if (lastbyte < 0)
203822803Smckusick {
203922803Smckusick err(toomuch);
204022803Smckusick dataerror = YES;
204122803Smckusick return;
204222803Smckusick }
204322803Smckusick
204422803Smckusick bitpos = offset % BYTESIZE;
204522803Smckusick chkoff = offset/BYTESIZE;
204622803Smckusick lastoff = lastbyte/BYTESIZE;
204722803Smckusick chklen = lastoff - chkoff + 1;
204822803Smckusick
204922803Smckusick pos = lseek(chkfile, chkoff, 0);
205022803Smckusick if (pos == -1)
205122803Smckusick {
205222803Smckusick err(seekerror);
205322803Smckusick done(1);
205422803Smckusick }
205522803Smckusick
205622803Smckusick while (k > 0)
205722803Smckusick {
205822803Smckusick if (chklen <= BUFSIZ)
205922803Smckusick n = chklen;
206022803Smckusick else
206122803Smckusick {
206222803Smckusick n = BUFSIZ;
206322803Smckusick chklen -= BUFSIZ;
206422803Smckusick }
206522803Smckusick
206622803Smckusick nbytes = read(chkfile, buff, n);
206722803Smckusick if (nbytes < 0)
206822803Smckusick {
206922803Smckusick err(readerror);
207022803Smckusick done(1);
207122803Smckusick }
207222803Smckusick
207322803Smckusick if (nbytes == 0)
207422803Smckusick buff[0] = '\0';
207522803Smckusick
207622803Smckusick if (nbytes < n)
207722803Smckusick buff[ n-1 ] = '\0';
207822803Smckusick
207922803Smckusick i = 0;
208022803Smckusick
208122803Smckusick if (bitpos > 0)
208222803Smckusick {
208322803Smckusick while (k > 0 && bitpos < BYTESIZE)
208422803Smckusick {
208522803Smckusick mask = 1 << bitpos;
208622803Smckusick
208722803Smckusick if (mask & buff[0])
208822803Smckusick overlap = YES;
208922803Smckusick else
209022803Smckusick buff[0] |= mask;
209122803Smckusick
209222803Smckusick k--;
209322803Smckusick bitpos++;
209422803Smckusick }
209522803Smckusick
209622803Smckusick if (bitpos == BYTESIZE)
209722803Smckusick {
209822803Smckusick bitpos = 0;
209922803Smckusick i++;
210022803Smckusick }
210122803Smckusick }
210222803Smckusick
210322803Smckusick while (i < nbytes && overlap == NO)
210422803Smckusick {
210522803Smckusick if (buff[i] == 0 && k >= BYTESIZE)
210622803Smckusick {
210722803Smckusick buff[i++] = MAXBYTE;
210822803Smckusick k -= BYTESIZE;
210922803Smckusick }
211022803Smckusick else if (k < BYTESIZE)
211122803Smckusick {
211222803Smckusick while (k-- > 0)
211322803Smckusick {
211422803Smckusick mask = 1 << k;
211522803Smckusick if (mask & buff[i])
211622803Smckusick overlap = YES;
211722803Smckusick else
211822803Smckusick buff[i] |= mask;
211922803Smckusick }
212022803Smckusick i++;
212122803Smckusick }
212222803Smckusick else
212322803Smckusick {
212422803Smckusick overlap = YES;
212522803Smckusick buff[i++] = MAXBYTE;
212622803Smckusick k -= BYTESIZE;
212722803Smckusick }
212822803Smckusick }
212922803Smckusick
213022803Smckusick while (i < n)
213122803Smckusick {
213222803Smckusick if (k >= BYTESIZE)
213322803Smckusick {
213422803Smckusick buff[i++] = MAXBYTE;
213522803Smckusick k -= BYTESIZE;
213622803Smckusick }
213722803Smckusick else
213822803Smckusick {
213922803Smckusick while (k-- > 0)
214022803Smckusick {
214122803Smckusick mask = 1 << k;
214222803Smckusick buff[i] |= mask;
214322803Smckusick }
214422803Smckusick i++;
214522803Smckusick }
214622803Smckusick }
214722803Smckusick
214822803Smckusick pos = lseek(chkfile, -nbytes, 1);
214922803Smckusick if (pos == -1)
215022803Smckusick {
215122803Smckusick err(seekerror);
215222803Smckusick done(1);
215322803Smckusick }
215422803Smckusick
215522803Smckusick nbytes = write(chkfile, buff, n);
215622803Smckusick if (nbytes != n)
215722803Smckusick {
215822803Smckusick err(writeerror);
215922803Smckusick done(1);
216022803Smckusick }
216122803Smckusick }
216222803Smckusick
216322803Smckusick if (overlap == NO)
216422803Smckusick {
216522803Smckusick allzero = YES;
216622803Smckusick k = len;
216722803Smckusick
216822803Smckusick while (k > 0 && allzero != NO)
216933256Sbostic if (constant[--k] != 0) allzero = NO;
217022803Smckusick
217122803Smckusick if (allzero == YES)
217222803Smckusick return;
217322803Smckusick }
217422803Smckusick
217522803Smckusick pos = lseek(datafile, offset, 0);
217622803Smckusick if (pos == -1)
217722803Smckusick {
217822803Smckusick err(seekerror);
217922803Smckusick done(1);
218022803Smckusick }
218122803Smckusick
218222803Smckusick k = repl;
218322803Smckusick while (k-- > 0)
218422803Smckusick {
218533256Sbostic nbytes = write(datafile, constant, len);
218622803Smckusick if (nbytes != len)
218722803Smckusick {
218822803Smckusick err(writeerror);
218922803Smckusick done(1);
219022803Smckusick }
219122803Smckusick }
219222803Smckusick
219322803Smckusick if (overlap) overlapflag = YES;
219422803Smckusick
219522803Smckusick return;
219622803Smckusick }
219722803Smckusick
219822803Smckusick
219922803Smckusick
220022803Smckusick Constp
getdatum()220122803Smckusick getdatum()
220222803Smckusick {
220322803Smckusick static char *toofew = "more data items than data values";
220422803Smckusick
220522803Smckusick register vallist *t;
220622803Smckusick
220722803Smckusick while (grvals != NULL)
220822803Smckusick {
220922803Smckusick if (grvals->status != NORMAL)
221022803Smckusick {
221122803Smckusick dataerror = YES;
221222803Smckusick return (NULL);
221322803Smckusick }
221422803Smckusick else if (grvals->repl > 0)
221522803Smckusick {
221622803Smckusick grvals->repl--;
221722803Smckusick return (grvals->value);
221822803Smckusick }
221922803Smckusick else
222022803Smckusick {
222122803Smckusick badvalue = 0;
222222803Smckusick frexpr ((tagptr) grvals->value);
222322803Smckusick t = grvals;
222422803Smckusick grvals = t->next;
222522803Smckusick free((char *) t);
222622803Smckusick }
222722803Smckusick }
222822803Smckusick
222922803Smckusick err(toofew);
223022803Smckusick dataerror = YES;
223122803Smckusick return (NULL);
223222803Smckusick }
223322803Smckusick
223422803Smckusick
223522803Smckusick
outdata(lvals)223622803Smckusick outdata(lvals)
223722803Smckusick elist *lvals;
223822803Smckusick {
223922803Smckusick register elist *top;
224022803Smckusick
224122803Smckusick top = lvals;
224222803Smckusick
224322803Smckusick while (top != NULL && dataerror == NO)
224422803Smckusick {
224522803Smckusick if (top->elt->tag == SIMPLE)
224622803Smckusick outaelt((aelt *) top->elt);
224722803Smckusick else
224822803Smckusick outdolist((dolist *) top->elt);
224922803Smckusick
225022803Smckusick top = top->next;
225122803Smckusick }
225222803Smckusick
225322803Smckusick return;
225422803Smckusick }
225522803Smckusick
225622803Smckusick
225722803Smckusick
outaelt(ap)225822803Smckusick outaelt(ap)
225922803Smckusick aelt *ap;
226022803Smckusick {
226122803Smckusick static char *toofew = "more data items than data values";
226222803Smckusick static char *boundserror = "substring expression out of bounds";
226322803Smckusick static char *order = "substring expressions out of order";
226422803Smckusick
226522803Smckusick register Namep np;
226622803Smckusick register long soffset;
226722803Smckusick register dvalue *lwb;
226822803Smckusick register dvalue *upb;
226933256Sbostic register Constp constant;
227022803Smckusick register int k;
227122803Smckusick register vallist *t;
227222803Smckusick register int type;
227322803Smckusick register ftnint typelen;
227422803Smckusick register ftnint repl;
227522803Smckusick
227622803Smckusick extern char *packbytes();
227722803Smckusick
227822803Smckusick np = ap->var;
227922803Smckusick setdfiles(np);
228022803Smckusick
228122803Smckusick type = np->vtype;
228222803Smckusick
228322803Smckusick if (type == TYCHAR)
228433256Sbostic typelen = np->vleng->constblock.constant.ci;
228522803Smckusick else if (type == TYLOGICAL)
228622803Smckusick typelen = typesize[tylogical];
228722803Smckusick else
228822803Smckusick typelen = typesize[type];
228922803Smckusick
229022803Smckusick if (ap->subs != NULL || np->vdim == NULL)
229122803Smckusick {
229222803Smckusick soffset = indexer(ap);
229322803Smckusick if (soffset == -1)
229422803Smckusick {
229522803Smckusick dataerror = YES;
229622803Smckusick return;
229722803Smckusick }
229822803Smckusick
229922803Smckusick soffset = soffset * typelen;
230022803Smckusick
230122803Smckusick if (ap->range != NULL)
230222803Smckusick {
230322803Smckusick lwb = (dvalue *) evalvexpr(ap->range->low);
230422803Smckusick upb = (dvalue *) evalvexpr(ap->range->high);
230522803Smckusick if (lwb->status == ERRVAL || upb->status == ERRVAL)
230622803Smckusick {
230722803Smckusick frvexpr((vexpr *) lwb);
230822803Smckusick frvexpr((vexpr *) upb);
230922803Smckusick dataerror = YES;
231022803Smckusick return;
231122803Smckusick }
231222803Smckusick
231322803Smckusick if (lwb->status != NORMAL ||
231422803Smckusick lwb->value < 1 ||
231522803Smckusick lwb->value > typelen ||
231622803Smckusick upb->status != NORMAL ||
231722803Smckusick upb->value < 1 ||
231822803Smckusick upb->value > typelen)
231922803Smckusick {
232022803Smckusick err(boundserror);
232122803Smckusick frvexpr((vexpr *) lwb);
232222803Smckusick frvexpr((vexpr *) upb);
232322803Smckusick dataerror = YES;
232422803Smckusick return;
232522803Smckusick }
232622803Smckusick
232722803Smckusick if (lwb->value > upb->value)
232822803Smckusick {
232922803Smckusick err(order);
233022803Smckusick frvexpr((vexpr *) lwb);
233122803Smckusick frvexpr((vexpr *) upb);
233222803Smckusick dataerror = YES;
233322803Smckusick return;
233422803Smckusick }
233522803Smckusick
233622803Smckusick soffset = soffset + lwb->value - 1;
233722803Smckusick typelen = upb->value - lwb->value + 1;
233822803Smckusick frvexpr((vexpr *) lwb);
233922803Smckusick frvexpr((vexpr *) upb);
234022803Smckusick }
234122803Smckusick
234233256Sbostic constant = getdatum();
234333256Sbostic if (constant == NULL || !ISCONST(constant))
234422803Smckusick return;
234522803Smckusick
234633256Sbostic constant = (Constp) convconst(type, typelen, constant);
234733256Sbostic if (constant == NULL || !ISCONST(constant))
234822803Smckusick {
234933256Sbostic frexpr((tagptr) constant);
235022803Smckusick return;
235122803Smckusick }
235222803Smckusick
235322803Smckusick if (type == TYCHAR)
235433256Sbostic wrtdata(base + soffset, 1, typelen, constant->constant.ccp);
235522803Smckusick else
235633256Sbostic wrtdata(base + soffset, 1, typelen, packbytes(constant));
235722803Smckusick
235833256Sbostic frexpr((tagptr) constant);
235922803Smckusick }
236022803Smckusick else
236122803Smckusick {
236222803Smckusick soffset = 0;
236333256Sbostic k = np->vdim->nelt->constblock.constant.ci;
236422803Smckusick while (k > 0 && dataerror == NO)
236522803Smckusick {
236622803Smckusick if (grvals == NULL)
236722803Smckusick {
236822803Smckusick err(toofew);
236922803Smckusick dataerror = YES;
237022803Smckusick }
237122803Smckusick else if (grvals->status != NORMAL)
237222803Smckusick dataerror = YES;
237322803Smckusick else if (grvals-> repl <= 0)
237422803Smckusick {
237522803Smckusick badvalue = 0;
237622803Smckusick frexpr((tagptr) grvals->value);
237722803Smckusick t = grvals;
237822803Smckusick grvals = t->next;
237922803Smckusick free((char *) t);
238022803Smckusick }
238122803Smckusick else
238222803Smckusick {
238333256Sbostic constant = grvals->value;
238433256Sbostic if (constant == NULL || !ISCONST(constant))
238522803Smckusick {
238622803Smckusick dataerror = YES;
238722803Smckusick }
238822803Smckusick else
238922803Smckusick {
239033256Sbostic constant = (Constp) convconst(type, typelen, constant);
239133256Sbostic if (constant == NULL || !ISCONST(constant))
239222803Smckusick {
239322803Smckusick dataerror = YES;
239433256Sbostic frexpr((tagptr) constant);
239522803Smckusick }
239622803Smckusick else
239722803Smckusick {
239822803Smckusick if (k > grvals->repl)
239922803Smckusick repl = grvals->repl;
240022803Smckusick else
240122803Smckusick repl = k;
240222803Smckusick
240322803Smckusick grvals->repl -= repl;
240422803Smckusick k -= repl;
240522803Smckusick
240622803Smckusick if (type == TYCHAR)
240733256Sbostic wrtdata(base+soffset, repl, typelen, constant->constant.ccp);
240822803Smckusick else
240933256Sbostic wrtdata(base+soffset, repl, typelen, packbytes(constant));
241022803Smckusick
241122803Smckusick soffset = soffset + repl * typelen;
241222803Smckusick
241333256Sbostic frexpr((tagptr) constant);
241422803Smckusick }
241522803Smckusick }
241622803Smckusick }
241722803Smckusick }
241822803Smckusick }
241922803Smckusick
242022803Smckusick return;
242122803Smckusick }
242222803Smckusick
242322803Smckusick
242422803Smckusick
outdolist(dp)242522803Smckusick outdolist(dp)
242622803Smckusick dolist *dp;
242722803Smckusick {
242822803Smckusick static char *zerostep = "zero step in implied-DO";
242922803Smckusick static char *order = "zero iteration count in implied-DO";
243022803Smckusick
243122803Smckusick register dvalue *e1, *e2, *e3;
243222803Smckusick register int direction;
243322803Smckusick register dvalue *dv;
243422803Smckusick register int done;
243522803Smckusick register int addin;
243622803Smckusick register int ts;
243722803Smckusick register ftnint tv;
243822803Smckusick
243922803Smckusick e1 = (dvalue *) evalvexpr(dp->init);
244022803Smckusick e2 = (dvalue *) evalvexpr(dp->limit);
244122803Smckusick e3 = (dvalue *) evalvexpr(dp->step);
244222803Smckusick
244322803Smckusick if (e1->status == ERRVAL ||
244422803Smckusick e2->status == ERRVAL ||
244522803Smckusick e3->status == ERRVAL)
244622803Smckusick {
244722803Smckusick dataerror = YES;
244822803Smckusick goto ret;
244922803Smckusick }
245022803Smckusick
245122803Smckusick if (e1->status == NORMAL)
245222803Smckusick {
245322803Smckusick if (e2->status == NORMAL)
245422803Smckusick {
245522803Smckusick if (e1->value < e2->value)
245622803Smckusick direction = 1;
245722803Smckusick else if (e1->value > e2->value)
245822803Smckusick direction = -1;
245922803Smckusick else
246022803Smckusick direction = 0;
246122803Smckusick }
246222803Smckusick else if (e2->status == MAXPLUS1)
246322803Smckusick direction = 1;
246422803Smckusick else
246522803Smckusick direction = -1;
246622803Smckusick }
246722803Smckusick else if (e1->status == MAXPLUS1)
246822803Smckusick {
246922803Smckusick if (e2->status == MAXPLUS1)
247022803Smckusick direction = 0;
247122803Smckusick else
247222803Smckusick direction = -1;
247322803Smckusick }
247422803Smckusick else
247522803Smckusick {
247622803Smckusick if (e2->status == MINLESS1)
247722803Smckusick direction = 0;
247822803Smckusick else
247922803Smckusick direction = 1;
248022803Smckusick }
248122803Smckusick
248222803Smckusick if (e3->status == NORMAL && e3->value == 0)
248322803Smckusick {
248422803Smckusick err(zerostep);
248522803Smckusick dataerror = YES;
248622803Smckusick goto ret;
248722803Smckusick }
248822803Smckusick else if (e3->status == MAXPLUS1 ||
248922803Smckusick (e3->status == NORMAL && e3->value > 0))
249022803Smckusick {
249122803Smckusick if (direction == -1)
249222803Smckusick {
249322803Smckusick warn(order);
249422803Smckusick goto ret;
249522803Smckusick }
249622803Smckusick }
249722803Smckusick else
249822803Smckusick {
249922803Smckusick if (direction == 1)
250022803Smckusick {
250122803Smckusick warn(order);
250222803Smckusick goto ret;
250322803Smckusick }
250422803Smckusick }
250522803Smckusick
250622803Smckusick dv = (dvalue *) dp->dovar;
250722803Smckusick dv->status = e1->status;
250822803Smckusick dv->value = e1->value;
250922803Smckusick
251022803Smckusick done = NO;
251122803Smckusick while (done == NO && dataerror == NO)
251222803Smckusick {
251322803Smckusick outdata(dp->elts);
251422803Smckusick
251522803Smckusick if (e3->status == NORMAL && dv->status == NORMAL)
251622803Smckusick {
251722803Smckusick addints(e3->value, dv->value);
251822803Smckusick dv->status = rstatus;
251922803Smckusick dv->value = rvalue;
252022803Smckusick }
252122803Smckusick else
252222803Smckusick {
252322803Smckusick if (e3->status != NORMAL)
252422803Smckusick {
252522803Smckusick if (e3->status == MAXPLUS1)
252622803Smckusick addin = MAXPLUS1;
252722803Smckusick else
252822803Smckusick addin = MINLESS1;
252922803Smckusick ts = dv->status;
253022803Smckusick tv = dv->value;
253122803Smckusick }
253222803Smckusick else
253322803Smckusick {
253422803Smckusick if (dv->status == MAXPLUS1)
253522803Smckusick addin = MAXPLUS1;
253622803Smckusick else
253722803Smckusick addin = MINLESS1;
253822803Smckusick ts = e3->status;
253922803Smckusick tv = e3->value;
254022803Smckusick }
254122803Smckusick
254222803Smckusick if (addin == MAXPLUS1)
254322803Smckusick {
254422803Smckusick if (ts == MAXPLUS1 || (ts == NORMAL && tv > 0))
254522803Smckusick dv->status = ERRVAL;
254622803Smckusick else if (ts == NORMAL && tv == 0)
254722803Smckusick dv->status = MAXPLUS1;
254822803Smckusick else if (ts == NORMAL)
254922803Smckusick {
255022803Smckusick dv->status = NORMAL;
255122803Smckusick dv->value = tv + MAXINT;
255222803Smckusick dv->value++;
255322803Smckusick }
255422803Smckusick else
255522803Smckusick {
255622803Smckusick dv->status = NORMAL;
255722803Smckusick dv->value = 0;
255822803Smckusick }
255922803Smckusick }
256022803Smckusick else
256122803Smckusick {
256222803Smckusick if (ts == MINLESS1 || (ts == NORMAL && tv < 0))
256322803Smckusick dv->status = ERRVAL;
256422803Smckusick else if (ts == NORMAL && tv == 0)
256522803Smckusick dv->status = MINLESS1;
256622803Smckusick else if (ts == NORMAL)
256722803Smckusick {
256822803Smckusick dv->status = NORMAL;
256922803Smckusick dv->value = tv - MAXINT;
257022803Smckusick dv->value--;
257122803Smckusick }
257222803Smckusick else
257322803Smckusick {
257422803Smckusick dv->status = NORMAL;
257522803Smckusick dv->value = 0;
257622803Smckusick }
257722803Smckusick }
257822803Smckusick }
257922803Smckusick
258022803Smckusick if (dv->status == ERRVAL)
258122803Smckusick done = YES;
258222803Smckusick else if (direction > 0)
258322803Smckusick {
258422803Smckusick if (e2->status == NORMAL)
258522803Smckusick {
258622803Smckusick if (dv->status == MAXPLUS1 ||
258722803Smckusick (dv->status == NORMAL && dv->value > e2->value))
258822803Smckusick done = YES;
258922803Smckusick }
259022803Smckusick }
259122803Smckusick else if (direction < 0)
259222803Smckusick {
259322803Smckusick if (e2->status == NORMAL)
259422803Smckusick {
259522803Smckusick if (dv->status == MINLESS1 ||
259622803Smckusick (dv->status == NORMAL && dv->value < e2->value))
259722803Smckusick done = YES;
259822803Smckusick }
259922803Smckusick }
260022803Smckusick else
260122803Smckusick done = YES;
260222803Smckusick }
260322803Smckusick
260422803Smckusick ret:
260522803Smckusick frvexpr((vexpr *) e1);
260622803Smckusick frvexpr((vexpr *) e2);
260722803Smckusick frvexpr((vexpr *) e3);
260822803Smckusick return;
260922803Smckusick }
2610