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