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