1*43205Sbostic /* 2*43205Sbostic * Copyright (c) 1980 Regents of the University of California. 3*43205Sbostic * All rights reserved. The Berkeley software License Agreement 4*43205Sbostic * specifies the terms and conditions for redistribution. 5*43205Sbostic */ 6*43205Sbostic 7*43205Sbostic #ifndef lint 8*43205Sbostic static char sccsid[] = "@(#)data.c 5.1 (Berkeley) 6/7/85"; 9*43205Sbostic #endif not lint 10*43205Sbostic 11*43205Sbostic /* 12*43205Sbostic * data.c 13*43205Sbostic * 14*43205Sbostic * Routines for handling DATA statements, f77 compiler, 4.2 BSD. 15*43205Sbostic * 16*43205Sbostic * University of Utah CS Dept modification history: 17*43205Sbostic * 18*43205Sbostic * Revision 3.1 84/10/13 01:09:50 donn 19*43205Sbostic * Installed Jerry Berkman's version; added UofU comment header. 20*43205Sbostic * 21*43205Sbostic */ 22*43205Sbostic 23*43205Sbostic #include "defs.h" 24*43205Sbostic #include "data.h" 25*43205Sbostic 26*43205Sbostic 27*43205Sbostic /* global variables */ 28*43205Sbostic 29*43205Sbostic flag overlapflag; 30*43205Sbostic 31*43205Sbostic 32*43205Sbostic 33*43205Sbostic /* local variables */ 34*43205Sbostic 35*43205Sbostic LOCAL char rstatus; 36*43205Sbostic LOCAL ftnint rvalue; 37*43205Sbostic LOCAL dovars *dvlist; 38*43205Sbostic LOCAL int dataerror; 39*43205Sbostic LOCAL vallist *grvals; 40*43205Sbostic LOCAL int datafile; 41*43205Sbostic LOCAL int chkfile; 42*43205Sbostic LOCAL long base; 43*43205Sbostic 44*43205Sbostic 45*43205Sbostic 46*43205Sbostic /* Copied from expr.c */ 47*43205Sbostic 48*43205Sbostic LOCAL letter(c) 49*43205Sbostic register int c; 50*43205Sbostic { 51*43205Sbostic if( isupper(c) ) 52*43205Sbostic c = tolower(c); 53*43205Sbostic return(c - 'a'); 54*43205Sbostic } 55*43205Sbostic 56*43205Sbostic 57*43205Sbostic 58*43205Sbostic vexpr * 59*43205Sbostic cpdvalue(dp) 60*43205Sbostic vexpr *dp; 61*43205Sbostic { 62*43205Sbostic register dvalue *p; 63*43205Sbostic 64*43205Sbostic if (dp->tag != DVALUE) 65*43205Sbostic badtag("cpdvalue", dp->tag); 66*43205Sbostic 67*43205Sbostic p = ALLOC(Dvalue); 68*43205Sbostic p->tag = DVALUE; 69*43205Sbostic p->status = dp->dvalue.status; 70*43205Sbostic p->value = dp->dvalue.value; 71*43205Sbostic 72*43205Sbostic return ((vexpr *) p); 73*43205Sbostic } 74*43205Sbostic 75*43205Sbostic 76*43205Sbostic 77*43205Sbostic frvexpr(vp) 78*43205Sbostic register vexpr *vp; 79*43205Sbostic { 80*43205Sbostic if (vp != NULL) 81*43205Sbostic { 82*43205Sbostic if (vp->tag == DNAME) 83*43205Sbostic free(vp->dname.repr); 84*43205Sbostic else if (vp->tag == DEXPR) 85*43205Sbostic { 86*43205Sbostic frvexpr(vp->dexpr.left); 87*43205Sbostic frvexpr(vp->dexpr.right); 88*43205Sbostic } 89*43205Sbostic 90*43205Sbostic free((char *) vp); 91*43205Sbostic } 92*43205Sbostic 93*43205Sbostic return; 94*43205Sbostic } 95*43205Sbostic 96*43205Sbostic 97*43205Sbostic 98*43205Sbostic frvlist(vp) 99*43205Sbostic register vlist *vp; 100*43205Sbostic { 101*43205Sbostic register vlist *t; 102*43205Sbostic 103*43205Sbostic while (vp) 104*43205Sbostic { 105*43205Sbostic t = vp->next; 106*43205Sbostic frvexpr(vp->val); 107*43205Sbostic free((char *) vp); 108*43205Sbostic vp = t; 109*43205Sbostic } 110*43205Sbostic 111*43205Sbostic return; 112*43205Sbostic } 113*43205Sbostic 114*43205Sbostic 115*43205Sbostic 116*43205Sbostic frelist(ep) 117*43205Sbostic elist *ep; 118*43205Sbostic { 119*43205Sbostic register elist *p; 120*43205Sbostic register elist *t; 121*43205Sbostic register aelt *ap; 122*43205Sbostic register dolist *dp; 123*43205Sbostic 124*43205Sbostic p = ep; 125*43205Sbostic 126*43205Sbostic while (p != NULL) 127*43205Sbostic { 128*43205Sbostic if (p->elt->tag == SIMPLE) 129*43205Sbostic { 130*43205Sbostic ap = (aelt *) p->elt; 131*43205Sbostic frvlist(ap->subs); 132*43205Sbostic if (ap->range != NULL) 133*43205Sbostic { 134*43205Sbostic frvexpr(ap->range->low); 135*43205Sbostic frvexpr(ap->range->high); 136*43205Sbostic free((char *) ap->range); 137*43205Sbostic } 138*43205Sbostic free((char *) ap); 139*43205Sbostic } 140*43205Sbostic else 141*43205Sbostic { 142*43205Sbostic dp = (dolist *) p->elt; 143*43205Sbostic frvexpr(dp->dovar); 144*43205Sbostic frvexpr(dp->init); 145*43205Sbostic frvexpr(dp->limit); 146*43205Sbostic frvexpr(dp->step); 147*43205Sbostic frelist(dp->elts); 148*43205Sbostic free((char *) dp); 149*43205Sbostic } 150*43205Sbostic 151*43205Sbostic t = p; 152*43205Sbostic p = p->next; 153*43205Sbostic free((char *) t); 154*43205Sbostic } 155*43205Sbostic 156*43205Sbostic return; 157*43205Sbostic } 158*43205Sbostic 159*43205Sbostic 160*43205Sbostic 161*43205Sbostic frvallist(vp) 162*43205Sbostic vallist *vp; 163*43205Sbostic { 164*43205Sbostic register vallist *p; 165*43205Sbostic register vallist *t; 166*43205Sbostic 167*43205Sbostic p = vp; 168*43205Sbostic while (p != NULL) 169*43205Sbostic { 170*43205Sbostic frexpr((tagptr) p->value); 171*43205Sbostic t = p; 172*43205Sbostic p = p->next; 173*43205Sbostic free((char *) t); 174*43205Sbostic } 175*43205Sbostic 176*43205Sbostic return; 177*43205Sbostic } 178*43205Sbostic 179*43205Sbostic 180*43205Sbostic 181*43205Sbostic elist *revelist(ep) 182*43205Sbostic register elist *ep; 183*43205Sbostic { 184*43205Sbostic register elist *next; 185*43205Sbostic register elist *t; 186*43205Sbostic 187*43205Sbostic if (ep != NULL) 188*43205Sbostic { 189*43205Sbostic next = ep->next; 190*43205Sbostic ep->next = NULL; 191*43205Sbostic 192*43205Sbostic while (next) 193*43205Sbostic { 194*43205Sbostic t = next->next; 195*43205Sbostic next->next = ep; 196*43205Sbostic ep = next; 197*43205Sbostic next = t; 198*43205Sbostic } 199*43205Sbostic } 200*43205Sbostic 201*43205Sbostic return (ep); 202*43205Sbostic } 203*43205Sbostic 204*43205Sbostic 205*43205Sbostic 206*43205Sbostic vlist *revvlist(vp) 207*43205Sbostic vlist *vp; 208*43205Sbostic { 209*43205Sbostic register vlist *p; 210*43205Sbostic register vlist *next; 211*43205Sbostic register vlist *t; 212*43205Sbostic 213*43205Sbostic if (vp == NULL) 214*43205Sbostic p = NULL; 215*43205Sbostic else 216*43205Sbostic { 217*43205Sbostic p = vp; 218*43205Sbostic next = p->next; 219*43205Sbostic p->next = NULL; 220*43205Sbostic 221*43205Sbostic while (next) 222*43205Sbostic { 223*43205Sbostic t = next->next; 224*43205Sbostic next->next = p; 225*43205Sbostic p = next; 226*43205Sbostic next = t; 227*43205Sbostic } 228*43205Sbostic } 229*43205Sbostic 230*43205Sbostic return (p); 231*43205Sbostic } 232*43205Sbostic 233*43205Sbostic 234*43205Sbostic 235*43205Sbostic vallist * 236*43205Sbostic revrvals(vp) 237*43205Sbostic vallist *vp; 238*43205Sbostic { 239*43205Sbostic register vallist *p; 240*43205Sbostic register vallist *next; 241*43205Sbostic register vallist *t; 242*43205Sbostic 243*43205Sbostic if (vp == NULL) 244*43205Sbostic p = NULL; 245*43205Sbostic else 246*43205Sbostic { 247*43205Sbostic p = vp; 248*43205Sbostic next = p->next; 249*43205Sbostic p->next = NULL; 250*43205Sbostic while (next) 251*43205Sbostic { 252*43205Sbostic t = next->next; 253*43205Sbostic next->next = p; 254*43205Sbostic p = next; 255*43205Sbostic next = t; 256*43205Sbostic } 257*43205Sbostic } 258*43205Sbostic 259*43205Sbostic return (p); 260*43205Sbostic } 261*43205Sbostic 262*43205Sbostic 263*43205Sbostic 264*43205Sbostic vlist *prepvexpr(tail, head) 265*43205Sbostic vlist *tail; 266*43205Sbostic vexpr *head; 267*43205Sbostic { 268*43205Sbostic register vlist *p; 269*43205Sbostic 270*43205Sbostic p = ALLOC(Vlist); 271*43205Sbostic p->next = tail; 272*43205Sbostic p->val = head; 273*43205Sbostic 274*43205Sbostic return (p); 275*43205Sbostic } 276*43205Sbostic 277*43205Sbostic 278*43205Sbostic 279*43205Sbostic elist *preplval(tail, head) 280*43205Sbostic elist *tail; 281*43205Sbostic delt* head; 282*43205Sbostic { 283*43205Sbostic register elist *p; 284*43205Sbostic p = ALLOC(Elist); 285*43205Sbostic p->next = tail; 286*43205Sbostic p->elt = head; 287*43205Sbostic 288*43205Sbostic return (p); 289*43205Sbostic } 290*43205Sbostic 291*43205Sbostic 292*43205Sbostic 293*43205Sbostic delt *mkdlval(name, subs, range) 294*43205Sbostic vexpr *name; 295*43205Sbostic vlist *subs; 296*43205Sbostic rpair *range; 297*43205Sbostic { 298*43205Sbostic static char *iscomm =" improper initialization for variable in COMMON"; 299*43205Sbostic register aelt *p; 300*43205Sbostic 301*43205Sbostic p = ALLOC(Aelt); 302*43205Sbostic p->tag = SIMPLE; 303*43205Sbostic p->var = mkname(name->dname.len, name->dname.repr); 304*43205Sbostic if ((procclass != CLBLOCK) && (p->var->vstg == STGCOMMON)) 305*43205Sbostic warn(iscomm); 306*43205Sbostic p->subs = subs; 307*43205Sbostic p->range = range; 308*43205Sbostic 309*43205Sbostic return ((delt *) p); 310*43205Sbostic } 311*43205Sbostic 312*43205Sbostic 313*43205Sbostic 314*43205Sbostic delt *mkdatado(lvals, dovar, params) 315*43205Sbostic elist *lvals; 316*43205Sbostic vexpr *dovar; 317*43205Sbostic vlist *params; 318*43205Sbostic { 319*43205Sbostic static char *toofew = "missing loop parameters"; 320*43205Sbostic static char *toomany = "too many loop parameters"; 321*43205Sbostic 322*43205Sbostic register dolist *p; 323*43205Sbostic register vlist *vp; 324*43205Sbostic register int pcnt; 325*43205Sbostic register dvalue *one; 326*43205Sbostic 327*43205Sbostic p = ALLOC(DoList); 328*43205Sbostic p->tag = NESTED; 329*43205Sbostic p->elts = revelist(lvals); 330*43205Sbostic p->dovar = dovar; 331*43205Sbostic 332*43205Sbostic vp = params; 333*43205Sbostic pcnt = 0; 334*43205Sbostic while (vp) 335*43205Sbostic { 336*43205Sbostic pcnt++; 337*43205Sbostic vp = vp->next; 338*43205Sbostic } 339*43205Sbostic 340*43205Sbostic if (pcnt != 2 && pcnt != 3) 341*43205Sbostic { 342*43205Sbostic if (pcnt < 2) 343*43205Sbostic err(toofew); 344*43205Sbostic else 345*43205Sbostic err(toomany); 346*43205Sbostic 347*43205Sbostic p->init = (vexpr *) ALLOC(Derror); 348*43205Sbostic p->init->tag = DERROR; 349*43205Sbostic 350*43205Sbostic p->limit = (vexpr *) ALLOC(Derror); 351*43205Sbostic p->limit->tag = DERROR; 352*43205Sbostic 353*43205Sbostic p->step = (vexpr *) ALLOC(Derror); 354*43205Sbostic p->step->tag = DERROR; 355*43205Sbostic } 356*43205Sbostic else 357*43205Sbostic { 358*43205Sbostic vp = params; 359*43205Sbostic 360*43205Sbostic if (pcnt == 2) 361*43205Sbostic { 362*43205Sbostic one = ALLOC(Dvalue); 363*43205Sbostic one->tag = DVALUE; 364*43205Sbostic one->status = NORMAL; 365*43205Sbostic one->value = 1; 366*43205Sbostic p->step = (vexpr *) one; 367*43205Sbostic } 368*43205Sbostic else 369*43205Sbostic { 370*43205Sbostic p->step = vp->val; 371*43205Sbostic vp->val = NULL; 372*43205Sbostic vp = vp->next; 373*43205Sbostic } 374*43205Sbostic 375*43205Sbostic p->limit = vp->val; 376*43205Sbostic vp->val = NULL; 377*43205Sbostic vp = vp->next; 378*43205Sbostic 379*43205Sbostic p->init = vp->val; 380*43205Sbostic vp->val = NULL; 381*43205Sbostic } 382*43205Sbostic 383*43205Sbostic frvlist(params); 384*43205Sbostic return ((delt *) p); 385*43205Sbostic } 386*43205Sbostic 387*43205Sbostic 388*43205Sbostic 389*43205Sbostic rpair *mkdrange(lb, ub) 390*43205Sbostic vexpr *lb, *ub; 391*43205Sbostic { 392*43205Sbostic register rpair *p; 393*43205Sbostic 394*43205Sbostic p = ALLOC(Rpair); 395*43205Sbostic p->low = lb; 396*43205Sbostic p->high = ub; 397*43205Sbostic 398*43205Sbostic return (p); 399*43205Sbostic } 400*43205Sbostic 401*43205Sbostic 402*43205Sbostic 403*43205Sbostic vallist *mkdrval(repl, val) 404*43205Sbostic vexpr *repl; 405*43205Sbostic expptr val; 406*43205Sbostic { 407*43205Sbostic static char *badtag = "bad tag in mkdrval"; 408*43205Sbostic static char *negrepl = "negative replicator"; 409*43205Sbostic static char *zerorepl = "zero replicator"; 410*43205Sbostic static char *toobig = "replicator too large"; 411*43205Sbostic static char *nonconst = "%s is not a constant"; 412*43205Sbostic 413*43205Sbostic register vexpr *vp; 414*43205Sbostic register vallist *p; 415*43205Sbostic register int status; 416*43205Sbostic register ftnint value; 417*43205Sbostic register int copied; 418*43205Sbostic 419*43205Sbostic copied = 0; 420*43205Sbostic 421*43205Sbostic if (repl->tag == DNAME) 422*43205Sbostic { 423*43205Sbostic vp = evaldname(repl); 424*43205Sbostic copied = 1; 425*43205Sbostic } 426*43205Sbostic else 427*43205Sbostic vp = repl; 428*43205Sbostic 429*43205Sbostic p = ALLOC(ValList); 430*43205Sbostic p->next = NULL; 431*43205Sbostic p->value = (Constp) val; 432*43205Sbostic 433*43205Sbostic if (vp->tag == DVALUE) 434*43205Sbostic { 435*43205Sbostic status = vp->dvalue.status; 436*43205Sbostic value = vp->dvalue.value; 437*43205Sbostic 438*43205Sbostic if ((status == NORMAL && value < 0) || status == MINLESS1) 439*43205Sbostic { 440*43205Sbostic err(negrepl); 441*43205Sbostic p->status = ERRVAL; 442*43205Sbostic } 443*43205Sbostic else if (status == NORMAL) 444*43205Sbostic { 445*43205Sbostic if (value == 0) 446*43205Sbostic warn(zerorepl); 447*43205Sbostic p->status = NORMAL; 448*43205Sbostic p->repl = value; 449*43205Sbostic } 450*43205Sbostic else if (status == MAXPLUS1) 451*43205Sbostic { 452*43205Sbostic err(toobig); 453*43205Sbostic p->status = ERRVAL; 454*43205Sbostic } 455*43205Sbostic else 456*43205Sbostic p->status = ERRVAL; 457*43205Sbostic } 458*43205Sbostic else if (vp->tag == DNAME) 459*43205Sbostic { 460*43205Sbostic errnm(nonconst, vp->dname.len, vp->dname.repr); 461*43205Sbostic p->status = ERRVAL; 462*43205Sbostic } 463*43205Sbostic else if (vp->tag == DERROR) 464*43205Sbostic p->status = ERRVAL; 465*43205Sbostic else 466*43205Sbostic fatal(badtag); 467*43205Sbostic 468*43205Sbostic if (copied) frvexpr(vp); 469*43205Sbostic return (p); 470*43205Sbostic } 471*43205Sbostic 472*43205Sbostic 473*43205Sbostic 474*43205Sbostic /* Evicon returns the value of the integer constant */ 475*43205Sbostic /* pointed to by token. */ 476*43205Sbostic 477*43205Sbostic vexpr *evicon(len, token) 478*43205Sbostic register int len; 479*43205Sbostic register char *token; 480*43205Sbostic { 481*43205Sbostic static char *badconst = "bad integer constant"; 482*43205Sbostic static char *overflow = "integer constant too large"; 483*43205Sbostic 484*43205Sbostic register int i; 485*43205Sbostic register ftnint val; 486*43205Sbostic register int digit; 487*43205Sbostic register dvalue *p; 488*43205Sbostic 489*43205Sbostic if (len <= 0) 490*43205Sbostic fatal(badconst); 491*43205Sbostic 492*43205Sbostic p = ALLOC(Dvalue); 493*43205Sbostic p->tag = DVALUE; 494*43205Sbostic 495*43205Sbostic i = 0; 496*43205Sbostic val = 0; 497*43205Sbostic while (i < len) 498*43205Sbostic { 499*43205Sbostic if (val > MAXINT/10) 500*43205Sbostic { 501*43205Sbostic err(overflow); 502*43205Sbostic p->status = ERRVAL; 503*43205Sbostic goto ret; 504*43205Sbostic } 505*43205Sbostic val = 10*val; 506*43205Sbostic digit = token[i++]; 507*43205Sbostic if (!isdigit(digit)) 508*43205Sbostic fatal(badconst); 509*43205Sbostic digit = digit - '0'; 510*43205Sbostic if (MAXINT - val >= digit) 511*43205Sbostic val = val + digit; 512*43205Sbostic else 513*43205Sbostic if (i == len && MAXINT - val + 1 == digit) 514*43205Sbostic { 515*43205Sbostic p->status = MAXPLUS1; 516*43205Sbostic goto ret; 517*43205Sbostic } 518*43205Sbostic else 519*43205Sbostic { 520*43205Sbostic err(overflow); 521*43205Sbostic p->status = ERRVAL; 522*43205Sbostic goto ret; 523*43205Sbostic } 524*43205Sbostic } 525*43205Sbostic 526*43205Sbostic p->status = NORMAL; 527*43205Sbostic p->value = val; 528*43205Sbostic 529*43205Sbostic ret: 530*43205Sbostic return ((vexpr *) p); 531*43205Sbostic } 532*43205Sbostic 533*43205Sbostic 534*43205Sbostic 535*43205Sbostic /* Ivaltoicon converts a dvalue into a constant block. */ 536*43205Sbostic 537*43205Sbostic expptr ivaltoicon(vp) 538*43205Sbostic register vexpr *vp; 539*43205Sbostic { 540*43205Sbostic static char *badtag = "bad tag in ivaltoicon"; 541*43205Sbostic static char *overflow = "integer constant too large"; 542*43205Sbostic 543*43205Sbostic register int vs; 544*43205Sbostic register expptr p; 545*43205Sbostic 546*43205Sbostic if (vp->tag == DERROR) 547*43205Sbostic return(errnode()); 548*43205Sbostic else if (vp->tag != DVALUE) 549*43205Sbostic fatal(badtag); 550*43205Sbostic 551*43205Sbostic vs = vp->dvalue.status; 552*43205Sbostic if (vs == NORMAL) 553*43205Sbostic p = mkintcon(vp->dvalue.value); 554*43205Sbostic else if ((MAXINT + MININT == -1) && vs == MINLESS1) 555*43205Sbostic p = mkintcon(MININT); 556*43205Sbostic else if (vs == MAXPLUS1 || vs == MINLESS1) 557*43205Sbostic { 558*43205Sbostic err(overflow); 559*43205Sbostic p = errnode(); 560*43205Sbostic } 561*43205Sbostic else 562*43205Sbostic p = errnode(); 563*43205Sbostic 564*43205Sbostic return (p); 565*43205Sbostic } 566*43205Sbostic 567*43205Sbostic 568*43205Sbostic 569*43205Sbostic /* Mkdname stores an identifier as a dname */ 570*43205Sbostic 571*43205Sbostic vexpr *mkdname(len, str) 572*43205Sbostic int len; 573*43205Sbostic register char *str; 574*43205Sbostic { 575*43205Sbostic register dname *p; 576*43205Sbostic register int i; 577*43205Sbostic register char *s; 578*43205Sbostic 579*43205Sbostic s = (char *) ckalloc(len + 1); 580*43205Sbostic i = len; 581*43205Sbostic s[i] = '\0'; 582*43205Sbostic 583*43205Sbostic while (--i >= 0) 584*43205Sbostic s[i] = str[i]; 585*43205Sbostic 586*43205Sbostic p = ALLOC(Dname); 587*43205Sbostic p->tag = DNAME; 588*43205Sbostic p->len = len; 589*43205Sbostic p->repr = s; 590*43205Sbostic 591*43205Sbostic return ((vexpr *) p); 592*43205Sbostic } 593*43205Sbostic 594*43205Sbostic 595*43205Sbostic 596*43205Sbostic /* Getname gets the symbol table information associated with */ 597*43205Sbostic /* a name. Getname differs from mkname in that it will not */ 598*43205Sbostic /* add the name to the symbol table if it is not already */ 599*43205Sbostic /* present. */ 600*43205Sbostic 601*43205Sbostic Namep getname(l, s) 602*43205Sbostic int l; 603*43205Sbostic register char *s; 604*43205Sbostic { 605*43205Sbostic struct Hashentry *hp; 606*43205Sbostic int hash; 607*43205Sbostic register Namep q; 608*43205Sbostic register int i; 609*43205Sbostic char n[VL]; 610*43205Sbostic 611*43205Sbostic hash = 0; 612*43205Sbostic for (i = 0; i < l && *s != '\0'; ++i) 613*43205Sbostic { 614*43205Sbostic hash += *s; 615*43205Sbostic n[i] = *s++; 616*43205Sbostic } 617*43205Sbostic 618*43205Sbostic while (i < VL) 619*43205Sbostic n[i++] = ' '; 620*43205Sbostic 621*43205Sbostic hash %= maxhash; 622*43205Sbostic hp = hashtab + hash; 623*43205Sbostic 624*43205Sbostic while (q = hp->varp) 625*43205Sbostic if (hash == hp->hashval 626*43205Sbostic && eqn(VL, n, q->varname)) 627*43205Sbostic goto ret; 628*43205Sbostic else if (++hp >= lasthash) 629*43205Sbostic hp = hashtab; 630*43205Sbostic 631*43205Sbostic ret: 632*43205Sbostic return (q); 633*43205Sbostic } 634*43205Sbostic 635*43205Sbostic 636*43205Sbostic 637*43205Sbostic /* Evparam returns the value of the constant named by name. */ 638*43205Sbostic 639*43205Sbostic expptr evparam(np) 640*43205Sbostic register vexpr *np; 641*43205Sbostic { 642*43205Sbostic static char *badtag = "bad tag in evparam"; 643*43205Sbostic static char *undefined = "%s is undefined"; 644*43205Sbostic static char *nonconst = "%s is not constant"; 645*43205Sbostic 646*43205Sbostic register struct Paramblock *tp; 647*43205Sbostic register expptr p; 648*43205Sbostic register int len; 649*43205Sbostic register char *repr; 650*43205Sbostic 651*43205Sbostic if (np->tag != DNAME) 652*43205Sbostic fatal(badtag); 653*43205Sbostic 654*43205Sbostic len = np->dname.len; 655*43205Sbostic repr = np->dname.repr; 656*43205Sbostic 657*43205Sbostic tp = (struct Paramblock *) getname(len, repr); 658*43205Sbostic 659*43205Sbostic if (tp == NULL) 660*43205Sbostic { 661*43205Sbostic errnm(undefined, len, repr); 662*43205Sbostic p = errnode(); 663*43205Sbostic } 664*43205Sbostic else if (tp->vclass != CLPARAM || !ISCONST(tp->paramval)) 665*43205Sbostic { 666*43205Sbostic if (tp->paramval->tag != TERROR) 667*43205Sbostic errnm(nonconst, len, repr); 668*43205Sbostic p = errnode(); 669*43205Sbostic } 670*43205Sbostic else 671*43205Sbostic p = (expptr) cpexpr(tp->paramval); 672*43205Sbostic 673*43205Sbostic return (p); 674*43205Sbostic } 675*43205Sbostic 676*43205Sbostic 677*43205Sbostic 678*43205Sbostic vexpr *evaldname(dp) 679*43205Sbostic vexpr *dp; 680*43205Sbostic { 681*43205Sbostic static char *undefined = "%s is undefined"; 682*43205Sbostic static char *nonconst = "%s is not a constant"; 683*43205Sbostic static char *nonint = "%s is not an integer"; 684*43205Sbostic 685*43205Sbostic register dvalue *p; 686*43205Sbostic register struct Paramblock *tp; 687*43205Sbostic register int len; 688*43205Sbostic register char *repr; 689*43205Sbostic 690*43205Sbostic p = ALLOC(Dvalue); 691*43205Sbostic p->tag = DVALUE; 692*43205Sbostic 693*43205Sbostic len = dp->dname.len; 694*43205Sbostic repr = dp->dname.repr; 695*43205Sbostic 696*43205Sbostic tp = (struct Paramblock *) getname(len, repr); 697*43205Sbostic 698*43205Sbostic if (tp == NULL) 699*43205Sbostic { 700*43205Sbostic errnm(undefined, len, repr); 701*43205Sbostic p->status = ERRVAL; 702*43205Sbostic } 703*43205Sbostic else if (tp->vclass != CLPARAM || !ISCONST(tp->paramval)) 704*43205Sbostic { 705*43205Sbostic if (tp->paramval->tag != TERROR) 706*43205Sbostic errnm(nonconst, len, repr); 707*43205Sbostic p->status = ERRVAL; 708*43205Sbostic } 709*43205Sbostic else if (!ISINT(tp->paramval->constblock.vtype)) 710*43205Sbostic { 711*43205Sbostic errnm(nonint, len, repr); 712*43205Sbostic p->status = ERRVAL; 713*43205Sbostic } 714*43205Sbostic else 715*43205Sbostic { 716*43205Sbostic if ((MAXINT + MININT == -1) 717*43205Sbostic && tp->paramval->constblock.const.ci == MININT) 718*43205Sbostic p->status = MINLESS1; 719*43205Sbostic else 720*43205Sbostic { 721*43205Sbostic p->status = NORMAL; 722*43205Sbostic p->value = tp->paramval->constblock.const.ci; 723*43205Sbostic } 724*43205Sbostic } 725*43205Sbostic 726*43205Sbostic return ((vexpr *) p); 727*43205Sbostic } 728*43205Sbostic 729*43205Sbostic 730*43205Sbostic 731*43205Sbostic vexpr *mkdexpr(op, l, r) 732*43205Sbostic register int op; 733*43205Sbostic register vexpr *l; 734*43205Sbostic register vexpr *r; 735*43205Sbostic { 736*43205Sbostic static char *badop = "bad operator in mkdexpr"; 737*43205Sbostic 738*43205Sbostic register vexpr *p; 739*43205Sbostic 740*43205Sbostic switch (op) 741*43205Sbostic { 742*43205Sbostic default: 743*43205Sbostic fatal(badop); 744*43205Sbostic 745*43205Sbostic case OPNEG: 746*43205Sbostic case OPPLUS: 747*43205Sbostic case OPMINUS: 748*43205Sbostic case OPSTAR: 749*43205Sbostic case OPSLASH: 750*43205Sbostic case OPPOWER: 751*43205Sbostic break; 752*43205Sbostic } 753*43205Sbostic 754*43205Sbostic if ((l != NULL && l->tag == DERROR) || r->tag == DERROR) 755*43205Sbostic { 756*43205Sbostic frvexpr(l); 757*43205Sbostic frvexpr(r); 758*43205Sbostic p = (vexpr *) ALLOC(Derror); 759*43205Sbostic p->tag = DERROR; 760*43205Sbostic } 761*43205Sbostic else if (op == OPNEG && r->tag == DVALUE) 762*43205Sbostic { 763*43205Sbostic p = negival(r); 764*43205Sbostic frvexpr(r); 765*43205Sbostic } 766*43205Sbostic else if (op != OPNEG && l->tag == DVALUE && r->tag == DVALUE) 767*43205Sbostic { 768*43205Sbostic switch (op) 769*43205Sbostic { 770*43205Sbostic case OPPLUS: 771*43205Sbostic p = addivals(l, r); 772*43205Sbostic break; 773*43205Sbostic 774*43205Sbostic case OPMINUS: 775*43205Sbostic p = subivals(l, r); 776*43205Sbostic break; 777*43205Sbostic 778*43205Sbostic case OPSTAR: 779*43205Sbostic p = mulivals(l, r); 780*43205Sbostic break; 781*43205Sbostic 782*43205Sbostic case OPSLASH: 783*43205Sbostic p = divivals(l, r); 784*43205Sbostic break; 785*43205Sbostic 786*43205Sbostic case OPPOWER: 787*43205Sbostic p = powivals(l, r); 788*43205Sbostic break; 789*43205Sbostic } 790*43205Sbostic 791*43205Sbostic frvexpr(l); 792*43205Sbostic frvexpr(r); 793*43205Sbostic } 794*43205Sbostic else 795*43205Sbostic { 796*43205Sbostic p = (vexpr *) ALLOC(Dexpr); 797*43205Sbostic p->tag = DEXPR; 798*43205Sbostic p->dexpr.opcode = op; 799*43205Sbostic p->dexpr.left = l; 800*43205Sbostic p->dexpr.right = r; 801*43205Sbostic } 802*43205Sbostic 803*43205Sbostic return (p); 804*43205Sbostic } 805*43205Sbostic 806*43205Sbostic 807*43205Sbostic 808*43205Sbostic vexpr *addivals(l, r) 809*43205Sbostic vexpr *l; 810*43205Sbostic vexpr *r; 811*43205Sbostic { 812*43205Sbostic static char *badtag = "bad tag in addivals"; 813*43205Sbostic static char *overflow = "integer value too large"; 814*43205Sbostic 815*43205Sbostic register int ls, rs; 816*43205Sbostic register ftnint lv, rv; 817*43205Sbostic register dvalue *p; 818*43205Sbostic register ftnint k; 819*43205Sbostic 820*43205Sbostic if (l->tag != DVALUE || r->tag != DVALUE) 821*43205Sbostic fatal(badtag); 822*43205Sbostic 823*43205Sbostic ls = l->dvalue.status; 824*43205Sbostic lv = l->dvalue.value; 825*43205Sbostic rs = r->dvalue.status; 826*43205Sbostic rv = r->dvalue.value; 827*43205Sbostic 828*43205Sbostic p = ALLOC(Dvalue); 829*43205Sbostic p->tag = DVALUE; 830*43205Sbostic 831*43205Sbostic if (ls == ERRVAL || rs == ERRVAL) 832*43205Sbostic p->status = ERRVAL; 833*43205Sbostic 834*43205Sbostic else if (ls == NORMAL && rs == NORMAL) 835*43205Sbostic { 836*43205Sbostic addints(lv, rv); 837*43205Sbostic if (rstatus == ERRVAL) 838*43205Sbostic err(overflow); 839*43205Sbostic p->status = rstatus; 840*43205Sbostic p->value = rvalue; 841*43205Sbostic } 842*43205Sbostic 843*43205Sbostic else 844*43205Sbostic { 845*43205Sbostic if (rs == MAXPLUS1 || rs == MINLESS1) 846*43205Sbostic { 847*43205Sbostic rs = ls; 848*43205Sbostic rv = lv; 849*43205Sbostic ls = r->dvalue.status; 850*43205Sbostic } 851*43205Sbostic 852*43205Sbostic if (rs == NORMAL && rv == 0) 853*43205Sbostic p->status = ls; 854*43205Sbostic else if (ls == MAXPLUS1) 855*43205Sbostic { 856*43205Sbostic if (rs == NORMAL && rv < 0) 857*43205Sbostic { 858*43205Sbostic p->status = NORMAL; 859*43205Sbostic k = MAXINT + rv; 860*43205Sbostic p->value = k + 1; 861*43205Sbostic } 862*43205Sbostic else if (rs == MINLESS1) 863*43205Sbostic { 864*43205Sbostic p->status = NORMAL; 865*43205Sbostic p->value = 0; 866*43205Sbostic } 867*43205Sbostic else 868*43205Sbostic { 869*43205Sbostic err(overflow); 870*43205Sbostic p->status = ERRVAL; 871*43205Sbostic } 872*43205Sbostic } 873*43205Sbostic else 874*43205Sbostic { 875*43205Sbostic if (rs == NORMAL && rv > 0) 876*43205Sbostic { 877*43205Sbostic p->status = NORMAL; 878*43205Sbostic k = ( -MAXINT ) + rv; 879*43205Sbostic p->value = k - 1; 880*43205Sbostic } 881*43205Sbostic else if (rs == MAXPLUS1) 882*43205Sbostic { 883*43205Sbostic p->status = NORMAL; 884*43205Sbostic p->value = 0; 885*43205Sbostic } 886*43205Sbostic else 887*43205Sbostic { 888*43205Sbostic err(overflow); 889*43205Sbostic p->status = ERRVAL; 890*43205Sbostic } 891*43205Sbostic } 892*43205Sbostic } 893*43205Sbostic 894*43205Sbostic return ((vexpr *) p); 895*43205Sbostic } 896*43205Sbostic 897*43205Sbostic 898*43205Sbostic 899*43205Sbostic vexpr *negival(vp) 900*43205Sbostic vexpr *vp; 901*43205Sbostic { 902*43205Sbostic static char *badtag = "bad tag in negival"; 903*43205Sbostic 904*43205Sbostic register int vs; 905*43205Sbostic register dvalue *p; 906*43205Sbostic 907*43205Sbostic if (vp->tag != DVALUE) 908*43205Sbostic fatal(badtag); 909*43205Sbostic 910*43205Sbostic vs = vp->dvalue.status; 911*43205Sbostic 912*43205Sbostic p = ALLOC(Dvalue); 913*43205Sbostic p->tag = DVALUE; 914*43205Sbostic 915*43205Sbostic if (vs == ERRVAL) 916*43205Sbostic p->status = ERRVAL; 917*43205Sbostic else if (vs == NORMAL) 918*43205Sbostic { 919*43205Sbostic p->status = NORMAL; 920*43205Sbostic p->value = -(vp->dvalue.value); 921*43205Sbostic } 922*43205Sbostic else if (vs == MAXPLUS1) 923*43205Sbostic p->status = MINLESS1; 924*43205Sbostic else 925*43205Sbostic p->status = MAXPLUS1; 926*43205Sbostic 927*43205Sbostic return ((vexpr *) p); 928*43205Sbostic } 929*43205Sbostic 930*43205Sbostic 931*43205Sbostic 932*43205Sbostic vexpr *subivals(l, r) 933*43205Sbostic vexpr *l; 934*43205Sbostic vexpr *r; 935*43205Sbostic { 936*43205Sbostic static char *badtag = "bad tag in subivals"; 937*43205Sbostic 938*43205Sbostic register vexpr *p; 939*43205Sbostic register vexpr *t; 940*43205Sbostic 941*43205Sbostic if (l->tag != DVALUE || r->tag != DVALUE) 942*43205Sbostic fatal(badtag); 943*43205Sbostic 944*43205Sbostic t = negival(r); 945*43205Sbostic p = addivals(l, t); 946*43205Sbostic frvexpr(t); 947*43205Sbostic 948*43205Sbostic return (p); 949*43205Sbostic } 950*43205Sbostic 951*43205Sbostic 952*43205Sbostic 953*43205Sbostic vexpr *mulivals(l, r) 954*43205Sbostic vexpr *l; 955*43205Sbostic vexpr *r; 956*43205Sbostic { 957*43205Sbostic static char *badtag = "bad tag in mulivals"; 958*43205Sbostic static char *overflow = "integer value too large"; 959*43205Sbostic 960*43205Sbostic register int ls, rs; 961*43205Sbostic register ftnint lv, rv; 962*43205Sbostic register dvalue *p; 963*43205Sbostic 964*43205Sbostic if (l->tag != DVALUE || r->tag != DVALUE) 965*43205Sbostic fatal(badtag); 966*43205Sbostic 967*43205Sbostic ls = l->dvalue.status; 968*43205Sbostic lv = l->dvalue.value; 969*43205Sbostic rs = r->dvalue.status; 970*43205Sbostic rv = r->dvalue.value; 971*43205Sbostic 972*43205Sbostic p = ALLOC(Dvalue); 973*43205Sbostic p->tag = DVALUE; 974*43205Sbostic 975*43205Sbostic if (ls == ERRVAL || rs == ERRVAL) 976*43205Sbostic p->status = ERRVAL; 977*43205Sbostic 978*43205Sbostic else if (ls == NORMAL && rs == NORMAL) 979*43205Sbostic { 980*43205Sbostic mulints(lv, rv); 981*43205Sbostic if (rstatus == ERRVAL) 982*43205Sbostic err(overflow); 983*43205Sbostic p->status = rstatus; 984*43205Sbostic p->value = rvalue; 985*43205Sbostic } 986*43205Sbostic else 987*43205Sbostic { 988*43205Sbostic if (rs == MAXPLUS1 || rs == MINLESS1) 989*43205Sbostic { 990*43205Sbostic rs = ls; 991*43205Sbostic rv = lv; 992*43205Sbostic ls = r->dvalue.status; 993*43205Sbostic } 994*43205Sbostic 995*43205Sbostic if (rs == NORMAL && rv == 0) 996*43205Sbostic { 997*43205Sbostic p->status = NORMAL; 998*43205Sbostic p->value = 0; 999*43205Sbostic } 1000*43205Sbostic else if (rs == NORMAL && rv == 1) 1001*43205Sbostic p->status = ls; 1002*43205Sbostic else if (rs == NORMAL && rv == -1) 1003*43205Sbostic if (ls == MAXPLUS1) 1004*43205Sbostic p->status = MINLESS1; 1005*43205Sbostic else 1006*43205Sbostic p->status = MAXPLUS1; 1007*43205Sbostic else 1008*43205Sbostic { 1009*43205Sbostic err(overflow); 1010*43205Sbostic p->status = ERRVAL; 1011*43205Sbostic } 1012*43205Sbostic } 1013*43205Sbostic 1014*43205Sbostic return ((vexpr *) p); 1015*43205Sbostic } 1016*43205Sbostic 1017*43205Sbostic 1018*43205Sbostic 1019*43205Sbostic vexpr *divivals(l, r) 1020*43205Sbostic vexpr *l; 1021*43205Sbostic vexpr *r; 1022*43205Sbostic { 1023*43205Sbostic static char *badtag = "bad tag in divivals"; 1024*43205Sbostic static char *zerodivide = "division by zero"; 1025*43205Sbostic 1026*43205Sbostic register int ls, rs; 1027*43205Sbostic register ftnint lv, rv; 1028*43205Sbostic register dvalue *p; 1029*43205Sbostic register ftnint k; 1030*43205Sbostic register int sign; 1031*43205Sbostic 1032*43205Sbostic if (l->tag != DVALUE && r->tag != DVALUE) 1033*43205Sbostic fatal(badtag); 1034*43205Sbostic 1035*43205Sbostic ls = l->dvalue.status; 1036*43205Sbostic lv = l->dvalue.value; 1037*43205Sbostic rs = r->dvalue.status; 1038*43205Sbostic rv = r->dvalue.value; 1039*43205Sbostic 1040*43205Sbostic p = ALLOC(Dvalue); 1041*43205Sbostic p->tag = DVALUE; 1042*43205Sbostic 1043*43205Sbostic if (ls == ERRVAL || rs == ERRVAL) 1044*43205Sbostic p->status = ERRVAL; 1045*43205Sbostic else if (rs == NORMAL) 1046*43205Sbostic { 1047*43205Sbostic if (rv == 0) 1048*43205Sbostic { 1049*43205Sbostic err(zerodivide); 1050*43205Sbostic p->status = ERRVAL; 1051*43205Sbostic } 1052*43205Sbostic else if (ls == NORMAL) 1053*43205Sbostic { 1054*43205Sbostic p->status = NORMAL; 1055*43205Sbostic p->value = lv / rv; 1056*43205Sbostic } 1057*43205Sbostic else if (rv == 1) 1058*43205Sbostic p->status = ls; 1059*43205Sbostic else if (rv == -1) 1060*43205Sbostic if (ls == MAXPLUS1) 1061*43205Sbostic p->status = MINLESS1; 1062*43205Sbostic else 1063*43205Sbostic p->status = MAXPLUS1; 1064*43205Sbostic else 1065*43205Sbostic { 1066*43205Sbostic p->status = NORMAL; 1067*43205Sbostic 1068*43205Sbostic if (ls == MAXPLUS1) 1069*43205Sbostic sign = 1; 1070*43205Sbostic else 1071*43205Sbostic sign = -1; 1072*43205Sbostic 1073*43205Sbostic if (rv < 0) 1074*43205Sbostic { 1075*43205Sbostic rv = -rv; 1076*43205Sbostic sign = -sign; 1077*43205Sbostic } 1078*43205Sbostic 1079*43205Sbostic k = MAXINT - rv; 1080*43205Sbostic p->value = sign * ((k + 1)/rv + 1); 1081*43205Sbostic } 1082*43205Sbostic } 1083*43205Sbostic else 1084*43205Sbostic { 1085*43205Sbostic p->status = NORMAL; 1086*43205Sbostic if (ls == NORMAL) 1087*43205Sbostic p->value = 0; 1088*43205Sbostic else if ((ls == MAXPLUS1 && rs == MAXPLUS1) 1089*43205Sbostic || (ls == MINLESS1 && rs == MINLESS1)) 1090*43205Sbostic p->value = 1; 1091*43205Sbostic else 1092*43205Sbostic p->value = -1; 1093*43205Sbostic } 1094*43205Sbostic 1095*43205Sbostic return ((vexpr *) p); 1096*43205Sbostic } 1097*43205Sbostic 1098*43205Sbostic 1099*43205Sbostic 1100*43205Sbostic vexpr *powivals(l, r) 1101*43205Sbostic vexpr *l; 1102*43205Sbostic vexpr *r; 1103*43205Sbostic { 1104*43205Sbostic static char *badtag = "bad tag in powivals"; 1105*43205Sbostic static char *zerozero = "zero raised to the zero-th power"; 1106*43205Sbostic static char *zeroneg = "zero raised to a negative power"; 1107*43205Sbostic static char *overflow = "integer value too large"; 1108*43205Sbostic 1109*43205Sbostic register int ls, rs; 1110*43205Sbostic register ftnint lv, rv; 1111*43205Sbostic register dvalue *p; 1112*43205Sbostic 1113*43205Sbostic if (l->tag != DVALUE || r->tag != DVALUE) 1114*43205Sbostic fatal(badtag); 1115*43205Sbostic 1116*43205Sbostic ls = l->dvalue.status; 1117*43205Sbostic lv = l->dvalue.value; 1118*43205Sbostic rs = r->dvalue.status; 1119*43205Sbostic rv = r->dvalue.value; 1120*43205Sbostic 1121*43205Sbostic p = ALLOC(Dvalue); 1122*43205Sbostic p->tag = DVALUE; 1123*43205Sbostic 1124*43205Sbostic if (ls == ERRVAL || rs == ERRVAL) 1125*43205Sbostic p->status = ERRVAL; 1126*43205Sbostic 1127*43205Sbostic else if (ls == NORMAL) 1128*43205Sbostic { 1129*43205Sbostic if (lv == 1) 1130*43205Sbostic { 1131*43205Sbostic p->status = NORMAL; 1132*43205Sbostic p->value = 1; 1133*43205Sbostic } 1134*43205Sbostic else if (lv == 0) 1135*43205Sbostic { 1136*43205Sbostic if (rs == MAXPLUS1 || (rs == NORMAL && rv > 0)) 1137*43205Sbostic { 1138*43205Sbostic p->status = NORMAL; 1139*43205Sbostic p->value = 0; 1140*43205Sbostic } 1141*43205Sbostic else if (rs == NORMAL && rv == 0) 1142*43205Sbostic { 1143*43205Sbostic warn(zerozero); 1144*43205Sbostic p->status = NORMAL; 1145*43205Sbostic p->value = 1; 1146*43205Sbostic } 1147*43205Sbostic else 1148*43205Sbostic { 1149*43205Sbostic err(zeroneg); 1150*43205Sbostic p->status = ERRVAL; 1151*43205Sbostic } 1152*43205Sbostic } 1153*43205Sbostic else if (lv == -1) 1154*43205Sbostic { 1155*43205Sbostic p->status = NORMAL; 1156*43205Sbostic if (rs == NORMAL) 1157*43205Sbostic { 1158*43205Sbostic if (rv < 0) rv = -rv; 1159*43205Sbostic if (rv % 2 == 0) 1160*43205Sbostic p->value = 1; 1161*43205Sbostic else 1162*43205Sbostic p->value = -1; 1163*43205Sbostic } 1164*43205Sbostic else 1165*43205Sbostic # if (MAXINT % 2 == 1) 1166*43205Sbostic p->value = 1; 1167*43205Sbostic # else 1168*43205Sbostic p->value = -1; 1169*43205Sbostic # endif 1170*43205Sbostic } 1171*43205Sbostic else 1172*43205Sbostic { 1173*43205Sbostic if (rs == NORMAL && rv > 0) 1174*43205Sbostic { 1175*43205Sbostic rstatus = NORMAL; 1176*43205Sbostic rvalue = lv; 1177*43205Sbostic while (--rv && rstatus == NORMAL) 1178*43205Sbostic mulints(rvalue, lv); 1179*43205Sbostic if (rv == 0 && rstatus != ERRVAL) 1180*43205Sbostic { 1181*43205Sbostic p->status = rstatus; 1182*43205Sbostic p->value = rvalue; 1183*43205Sbostic } 1184*43205Sbostic else 1185*43205Sbostic { 1186*43205Sbostic err(overflow); 1187*43205Sbostic p->status = ERRVAL; 1188*43205Sbostic } 1189*43205Sbostic } 1190*43205Sbostic else if (rs == MAXPLUS1) 1191*43205Sbostic { 1192*43205Sbostic err(overflow); 1193*43205Sbostic p->status = ERRVAL; 1194*43205Sbostic } 1195*43205Sbostic else if (rs == NORMAL && rv == 0) 1196*43205Sbostic { 1197*43205Sbostic p->status = NORMAL; 1198*43205Sbostic p->value = 1; 1199*43205Sbostic } 1200*43205Sbostic else 1201*43205Sbostic { 1202*43205Sbostic p->status = NORMAL; 1203*43205Sbostic p->value = 0; 1204*43205Sbostic } 1205*43205Sbostic } 1206*43205Sbostic } 1207*43205Sbostic 1208*43205Sbostic else 1209*43205Sbostic { 1210*43205Sbostic if (rs == MAXPLUS1 || (rs == NORMAL && rv > 1)) 1211*43205Sbostic { 1212*43205Sbostic err(overflow); 1213*43205Sbostic p->status = ERRVAL; 1214*43205Sbostic } 1215*43205Sbostic else if (rs == NORMAL && rv == 1) 1216*43205Sbostic p->status = ls; 1217*43205Sbostic else if (rs == NORMAL && rv == 0) 1218*43205Sbostic { 1219*43205Sbostic p->status = NORMAL; 1220*43205Sbostic p->value = 1; 1221*43205Sbostic } 1222*43205Sbostic else 1223*43205Sbostic { 1224*43205Sbostic p->status = NORMAL; 1225*43205Sbostic p->value = 0; 1226*43205Sbostic } 1227*43205Sbostic } 1228*43205Sbostic 1229*43205Sbostic return ((vexpr *) p); 1230*43205Sbostic } 1231*43205Sbostic 1232*43205Sbostic 1233*43205Sbostic 1234*43205Sbostic /* Addints adds two integer values. */ 1235*43205Sbostic 1236*43205Sbostic addints(i, j) 1237*43205Sbostic register ftnint i, j; 1238*43205Sbostic { 1239*43205Sbostic register ftnint margin; 1240*43205Sbostic 1241*43205Sbostic if (i == 0) 1242*43205Sbostic { 1243*43205Sbostic rstatus = NORMAL; 1244*43205Sbostic rvalue = j; 1245*43205Sbostic } 1246*43205Sbostic else if (i > 0) 1247*43205Sbostic { 1248*43205Sbostic margin = MAXINT - i; 1249*43205Sbostic if (j <= margin) 1250*43205Sbostic { 1251*43205Sbostic rstatus = NORMAL; 1252*43205Sbostic rvalue = i + j; 1253*43205Sbostic } 1254*43205Sbostic else if (j == margin + 1) 1255*43205Sbostic rstatus = MAXPLUS1; 1256*43205Sbostic else 1257*43205Sbostic rstatus = ERRVAL; 1258*43205Sbostic } 1259*43205Sbostic else 1260*43205Sbostic { 1261*43205Sbostic margin = ( -MAXINT ) - i; 1262*43205Sbostic if (j >= margin) 1263*43205Sbostic { 1264*43205Sbostic rstatus = NORMAL; 1265*43205Sbostic rvalue = i + j; 1266*43205Sbostic } 1267*43205Sbostic else if (j == margin - 1) 1268*43205Sbostic rstatus = MINLESS1; 1269*43205Sbostic else 1270*43205Sbostic rstatus = ERRVAL; 1271*43205Sbostic } 1272*43205Sbostic 1273*43205Sbostic return; 1274*43205Sbostic } 1275*43205Sbostic 1276*43205Sbostic 1277*43205Sbostic 1278*43205Sbostic /* Mulints multiplies two integer values */ 1279*43205Sbostic 1280*43205Sbostic mulints(i, j) 1281*43205Sbostic register ftnint i, j; 1282*43205Sbostic { 1283*43205Sbostic register ftnint sign; 1284*43205Sbostic register ftnint margin; 1285*43205Sbostic 1286*43205Sbostic if (i == 0 || j == 0) 1287*43205Sbostic { 1288*43205Sbostic rstatus = NORMAL; 1289*43205Sbostic rvalue = 0; 1290*43205Sbostic } 1291*43205Sbostic else 1292*43205Sbostic { 1293*43205Sbostic if ((i > 0 && j > 0) || (i < 0 && j < 0)) 1294*43205Sbostic sign = 1; 1295*43205Sbostic else 1296*43205Sbostic sign = -1; 1297*43205Sbostic 1298*43205Sbostic if (i < 0) i = -i; 1299*43205Sbostic if (j < 0) j = -j; 1300*43205Sbostic 1301*43205Sbostic margin = MAXINT - i; 1302*43205Sbostic margin = (margin + 1) / i; 1303*43205Sbostic 1304*43205Sbostic if (j <= margin) 1305*43205Sbostic { 1306*43205Sbostic rstatus = NORMAL; 1307*43205Sbostic rvalue = i * j * sign; 1308*43205Sbostic } 1309*43205Sbostic else if (j - 1 == margin) 1310*43205Sbostic { 1311*43205Sbostic margin = i*margin - 1; 1312*43205Sbostic if (margin == MAXINT - i) 1313*43205Sbostic if (sign > 0) 1314*43205Sbostic rstatus = MAXPLUS1; 1315*43205Sbostic else 1316*43205Sbostic rstatus = MINLESS1; 1317*43205Sbostic else 1318*43205Sbostic { 1319*43205Sbostic rstatus = NORMAL; 1320*43205Sbostic rvalue = i * j * sign; 1321*43205Sbostic } 1322*43205Sbostic } 1323*43205Sbostic else 1324*43205Sbostic rstatus = ERRVAL; 1325*43205Sbostic } 1326*43205Sbostic 1327*43205Sbostic return; 1328*43205Sbostic } 1329*43205Sbostic 1330*43205Sbostic 1331*43205Sbostic 1332*43205Sbostic vexpr * 1333*43205Sbostic evalvexpr(ep) 1334*43205Sbostic vexpr *ep; 1335*43205Sbostic { 1336*43205Sbostic register vexpr *p; 1337*43205Sbostic register vexpr *l, *r; 1338*43205Sbostic 1339*43205Sbostic switch (ep->tag) 1340*43205Sbostic { 1341*43205Sbostic case DVALUE: 1342*43205Sbostic p = cpdvalue(ep); 1343*43205Sbostic break; 1344*43205Sbostic 1345*43205Sbostic case DVAR: 1346*43205Sbostic p = cpdvalue((vexpr *) ep->dvar.valp); 1347*43205Sbostic break; 1348*43205Sbostic 1349*43205Sbostic case DNAME: 1350*43205Sbostic p = evaldname(ep); 1351*43205Sbostic break; 1352*43205Sbostic 1353*43205Sbostic case DEXPR: 1354*43205Sbostic if (ep->dexpr.left == NULL) 1355*43205Sbostic l = NULL; 1356*43205Sbostic else 1357*43205Sbostic l = evalvexpr(ep->dexpr.left); 1358*43205Sbostic 1359*43205Sbostic if (ep->dexpr.right == NULL) 1360*43205Sbostic r = NULL; 1361*43205Sbostic else 1362*43205Sbostic r = evalvexpr(ep->dexpr.right); 1363*43205Sbostic 1364*43205Sbostic switch (ep->dexpr.opcode) 1365*43205Sbostic { 1366*43205Sbostic case OPNEG: 1367*43205Sbostic p = negival(r); 1368*43205Sbostic break; 1369*43205Sbostic 1370*43205Sbostic case OPPLUS: 1371*43205Sbostic p = addivals(l, r); 1372*43205Sbostic break; 1373*43205Sbostic 1374*43205Sbostic case OPMINUS: 1375*43205Sbostic p = subivals(l, r); 1376*43205Sbostic break; 1377*43205Sbostic 1378*43205Sbostic case OPSTAR: 1379*43205Sbostic p = mulivals(l, r); 1380*43205Sbostic break; 1381*43205Sbostic 1382*43205Sbostic case OPSLASH: 1383*43205Sbostic p = divivals(l, r); 1384*43205Sbostic break; 1385*43205Sbostic 1386*43205Sbostic case OPPOWER: 1387*43205Sbostic p = powivals(l, r); 1388*43205Sbostic break; 1389*43205Sbostic } 1390*43205Sbostic 1391*43205Sbostic frvexpr(l); 1392*43205Sbostic frvexpr(r); 1393*43205Sbostic break; 1394*43205Sbostic 1395*43205Sbostic case DERROR: 1396*43205Sbostic p = (vexpr *) ALLOC(Dvalue); 1397*43205Sbostic p->tag = DVALUE; 1398*43205Sbostic p->dvalue.status = ERRVAL; 1399*43205Sbostic break; 1400*43205Sbostic } 1401*43205Sbostic 1402*43205Sbostic return (p); 1403*43205Sbostic } 1404*43205Sbostic 1405*43205Sbostic 1406*43205Sbostic 1407*43205Sbostic vexpr * 1408*43205Sbostic refrigdname(vp) 1409*43205Sbostic vexpr *vp; 1410*43205Sbostic { 1411*43205Sbostic register vexpr *p; 1412*43205Sbostic register int len; 1413*43205Sbostic register char *repr; 1414*43205Sbostic register int found; 1415*43205Sbostic register dovars *dvp; 1416*43205Sbostic 1417*43205Sbostic len = vp->dname.len; 1418*43205Sbostic repr = vp->dname.repr; 1419*43205Sbostic 1420*43205Sbostic found = NO; 1421*43205Sbostic dvp = dvlist; 1422*43205Sbostic while (found == NO && dvp != NULL) 1423*43205Sbostic { 1424*43205Sbostic if (len == dvp->len && eqn(len, repr, dvp->repr)) 1425*43205Sbostic found = YES; 1426*43205Sbostic else 1427*43205Sbostic dvp = dvp->next; 1428*43205Sbostic } 1429*43205Sbostic 1430*43205Sbostic if (found == YES) 1431*43205Sbostic { 1432*43205Sbostic p = (vexpr *) ALLOC(Dvar); 1433*43205Sbostic p->tag = DVAR; 1434*43205Sbostic p->dvar.valp = dvp->valp; 1435*43205Sbostic } 1436*43205Sbostic else 1437*43205Sbostic { 1438*43205Sbostic p = evaldname(vp); 1439*43205Sbostic if (p->dvalue.status == ERRVAL) 1440*43205Sbostic dataerror = YES; 1441*43205Sbostic } 1442*43205Sbostic 1443*43205Sbostic return (p); 1444*43205Sbostic } 1445*43205Sbostic 1446*43205Sbostic 1447*43205Sbostic 1448*43205Sbostic refrigvexpr(vpp) 1449*43205Sbostic vexpr **vpp; 1450*43205Sbostic { 1451*43205Sbostic register vexpr *vp; 1452*43205Sbostic 1453*43205Sbostic vp = *vpp; 1454*43205Sbostic 1455*43205Sbostic switch (vp->tag) 1456*43205Sbostic { 1457*43205Sbostic case DVALUE: 1458*43205Sbostic case DVAR: 1459*43205Sbostic case DERROR: 1460*43205Sbostic break; 1461*43205Sbostic 1462*43205Sbostic case DEXPR: 1463*43205Sbostic refrigvexpr( &(vp->dexpr.left) ); 1464*43205Sbostic refrigvexpr( &(vp->dexpr.right) ); 1465*43205Sbostic break; 1466*43205Sbostic 1467*43205Sbostic case DNAME: 1468*43205Sbostic *(vpp) = refrigdname(vp); 1469*43205Sbostic frvexpr(vp); 1470*43205Sbostic break; 1471*43205Sbostic } 1472*43205Sbostic 1473*43205Sbostic return; 1474*43205Sbostic } 1475*43205Sbostic 1476*43205Sbostic 1477*43205Sbostic 1478*43205Sbostic int 1479*43205Sbostic chkvar(np, sname) 1480*43205Sbostic Namep np; 1481*43205Sbostic char *sname; 1482*43205Sbostic { 1483*43205Sbostic static char *nonvar = "%s is not a variable"; 1484*43205Sbostic static char *arginit = "attempt to initialize a dummy argument: %s"; 1485*43205Sbostic static char *autoinit = "attempt to initialize an automatic variable: %s"; 1486*43205Sbostic static char *badclass = "bad class in chkvar"; 1487*43205Sbostic 1488*43205Sbostic register int status; 1489*43205Sbostic register struct Dimblock *dp; 1490*43205Sbostic register int i; 1491*43205Sbostic 1492*43205Sbostic status = YES; 1493*43205Sbostic 1494*43205Sbostic if (np->vclass == CLUNKNOWN 1495*43205Sbostic || (np->vclass == CLVAR && !np->vdcldone)) 1496*43205Sbostic vardcl(np); 1497*43205Sbostic 1498*43205Sbostic if (np->vstg == STGARG) 1499*43205Sbostic { 1500*43205Sbostic errstr(arginit, sname); 1501*43205Sbostic dataerror = YES; 1502*43205Sbostic status = NO; 1503*43205Sbostic } 1504*43205Sbostic else if (np->vclass != CLVAR) 1505*43205Sbostic { 1506*43205Sbostic errstr(nonvar, sname); 1507*43205Sbostic dataerror = YES; 1508*43205Sbostic status = NO; 1509*43205Sbostic } 1510*43205Sbostic else if (np->vstg == STGAUTO) 1511*43205Sbostic { 1512*43205Sbostic errstr(autoinit, sname); 1513*43205Sbostic dataerror = YES; 1514*43205Sbostic status = NO; 1515*43205Sbostic } 1516*43205Sbostic else if (np->vstg != STGBSS && np->vstg != STGINIT 1517*43205Sbostic && np->vstg != STGCOMMON && np->vstg != STGEQUIV) 1518*43205Sbostic { 1519*43205Sbostic fatal(badclass); 1520*43205Sbostic } 1521*43205Sbostic else 1522*43205Sbostic { 1523*43205Sbostic switch (np->vtype) 1524*43205Sbostic { 1525*43205Sbostic case TYERROR: 1526*43205Sbostic status = NO; 1527*43205Sbostic dataerror = YES; 1528*43205Sbostic break; 1529*43205Sbostic 1530*43205Sbostic case TYSHORT: 1531*43205Sbostic case TYLONG: 1532*43205Sbostic case TYREAL: 1533*43205Sbostic case TYDREAL: 1534*43205Sbostic case TYCOMPLEX: 1535*43205Sbostic case TYDCOMPLEX: 1536*43205Sbostic case TYLOGICAL: 1537*43205Sbostic case TYCHAR: 1538*43205Sbostic dp = np->vdim; 1539*43205Sbostic if (dp != NULL) 1540*43205Sbostic { 1541*43205Sbostic if (dp->nelt == NULL || !ISICON(dp->nelt)) 1542*43205Sbostic { 1543*43205Sbostic status = NO; 1544*43205Sbostic dataerror = YES; 1545*43205Sbostic } 1546*43205Sbostic } 1547*43205Sbostic break; 1548*43205Sbostic 1549*43205Sbostic default: 1550*43205Sbostic badtype("chkvar", np->vtype); 1551*43205Sbostic } 1552*43205Sbostic } 1553*43205Sbostic 1554*43205Sbostic return (status); 1555*43205Sbostic } 1556*43205Sbostic 1557*43205Sbostic 1558*43205Sbostic 1559*43205Sbostic refrigsubs(ap, sname) 1560*43205Sbostic aelt *ap; 1561*43205Sbostic char *sname; 1562*43205Sbostic { 1563*43205Sbostic static char *nonarray = "subscripts on a simple variable: %s"; 1564*43205Sbostic static char *toofew = "not enough subscripts on %s"; 1565*43205Sbostic static char *toomany = "too many subscripts on %s"; 1566*43205Sbostic 1567*43205Sbostic register vlist *subp; 1568*43205Sbostic register int nsubs; 1569*43205Sbostic register Namep np; 1570*43205Sbostic register struct Dimblock *dp; 1571*43205Sbostic register int i; 1572*43205Sbostic 1573*43205Sbostic np = ap->var; 1574*43205Sbostic dp = np->vdim; 1575*43205Sbostic 1576*43205Sbostic if (ap->subs != NULL) 1577*43205Sbostic { 1578*43205Sbostic if (np->vdim == NULL) 1579*43205Sbostic { 1580*43205Sbostic errstr(nonarray, sname); 1581*43205Sbostic dataerror = YES; 1582*43205Sbostic } 1583*43205Sbostic else 1584*43205Sbostic { 1585*43205Sbostic nsubs = 0; 1586*43205Sbostic subp = ap->subs; 1587*43205Sbostic while (subp != NULL) 1588*43205Sbostic { 1589*43205Sbostic nsubs++; 1590*43205Sbostic refrigvexpr( &(subp->val) ); 1591*43205Sbostic subp = subp->next; 1592*43205Sbostic } 1593*43205Sbostic 1594*43205Sbostic if (dp->ndim != nsubs) 1595*43205Sbostic { 1596*43205Sbostic if (np->vdim->ndim > nsubs) 1597*43205Sbostic errstr(toofew, sname); 1598*43205Sbostic else 1599*43205Sbostic errstr(toomany, sname); 1600*43205Sbostic dataerror = YES; 1601*43205Sbostic } 1602*43205Sbostic else if (dp->baseoffset == NULL || !ISICON(dp->baseoffset)) 1603*43205Sbostic dataerror = YES; 1604*43205Sbostic else 1605*43205Sbostic { 1606*43205Sbostic i = dp->ndim; 1607*43205Sbostic while (i-- > 0) 1608*43205Sbostic { 1609*43205Sbostic if (dp->dims[i].dimsize == NULL 1610*43205Sbostic || !ISICON(dp->dims[i].dimsize)) 1611*43205Sbostic dataerror = YES; 1612*43205Sbostic } 1613*43205Sbostic } 1614*43205Sbostic } 1615*43205Sbostic } 1616*43205Sbostic 1617*43205Sbostic return; 1618*43205Sbostic } 1619*43205Sbostic 1620*43205Sbostic 1621*43205Sbostic 1622*43205Sbostic refrigrange(ap, sname) 1623*43205Sbostic aelt *ap; 1624*43205Sbostic char *sname; 1625*43205Sbostic { 1626*43205Sbostic static char *nonstr = "substring of a noncharacter variable: %s"; 1627*43205Sbostic static char *array = "substring applied to an array: %s"; 1628*43205Sbostic 1629*43205Sbostic register Namep np; 1630*43205Sbostic register dvalue *t; 1631*43205Sbostic register rpair *rp; 1632*43205Sbostic 1633*43205Sbostic if (ap->range != NULL) 1634*43205Sbostic { 1635*43205Sbostic np = ap->var; 1636*43205Sbostic if (np->vtype != TYCHAR) 1637*43205Sbostic { 1638*43205Sbostic errstr(nonstr, sname); 1639*43205Sbostic dataerror = YES; 1640*43205Sbostic } 1641*43205Sbostic else if (ap->subs == NULL && np->vdim != NULL) 1642*43205Sbostic { 1643*43205Sbostic errstr(array, sname); 1644*43205Sbostic dataerror = YES; 1645*43205Sbostic } 1646*43205Sbostic else 1647*43205Sbostic { 1648*43205Sbostic rp = ap->range; 1649*43205Sbostic 1650*43205Sbostic if (rp->low != NULL) 1651*43205Sbostic refrigvexpr( &(rp->low) ); 1652*43205Sbostic else 1653*43205Sbostic { 1654*43205Sbostic t = ALLOC(Dvalue); 1655*43205Sbostic t->tag = DVALUE; 1656*43205Sbostic t->status = NORMAL; 1657*43205Sbostic t->value = 1; 1658*43205Sbostic rp->low = (vexpr *) t; 1659*43205Sbostic } 1660*43205Sbostic 1661*43205Sbostic if (rp->high != NULL) 1662*43205Sbostic refrigvexpr( &(rp->high) ); 1663*43205Sbostic else 1664*43205Sbostic { 1665*43205Sbostic if (!ISICON(np->vleng)) 1666*43205Sbostic { 1667*43205Sbostic rp->high = (vexpr *) ALLOC(Derror); 1668*43205Sbostic rp->high->tag = DERROR; 1669*43205Sbostic } 1670*43205Sbostic else 1671*43205Sbostic { 1672*43205Sbostic t = ALLOC(Dvalue); 1673*43205Sbostic t->tag = DVALUE; 1674*43205Sbostic t->status = NORMAL; 1675*43205Sbostic t->value = np->vleng->constblock.const.ci; 1676*43205Sbostic rp->high = (vexpr *) t; 1677*43205Sbostic } 1678*43205Sbostic } 1679*43205Sbostic } 1680*43205Sbostic } 1681*43205Sbostic 1682*43205Sbostic return; 1683*43205Sbostic } 1684*43205Sbostic 1685*43205Sbostic 1686*43205Sbostic 1687*43205Sbostic refrigaelt(ap) 1688*43205Sbostic aelt *ap; 1689*43205Sbostic { 1690*43205Sbostic register Namep np; 1691*43205Sbostic register char *bp, *sp; 1692*43205Sbostic register int len; 1693*43205Sbostic char buff[VL+1]; 1694*43205Sbostic 1695*43205Sbostic np = ap->var; 1696*43205Sbostic 1697*43205Sbostic len = 0; 1698*43205Sbostic bp = buff; 1699*43205Sbostic sp = np->varname; 1700*43205Sbostic while (len < VL && *sp != ' ' && *sp != '\0') 1701*43205Sbostic { 1702*43205Sbostic *bp++ = *sp++; 1703*43205Sbostic len++; 1704*43205Sbostic } 1705*43205Sbostic *bp = '\0'; 1706*43205Sbostic 1707*43205Sbostic if (chkvar(np, buff)) 1708*43205Sbostic { 1709*43205Sbostic refrigsubs(ap, buff); 1710*43205Sbostic refrigrange(ap, buff); 1711*43205Sbostic } 1712*43205Sbostic 1713*43205Sbostic return; 1714*43205Sbostic } 1715*43205Sbostic 1716*43205Sbostic 1717*43205Sbostic 1718*43205Sbostic refrigdo(dp) 1719*43205Sbostic dolist *dp; 1720*43205Sbostic { 1721*43205Sbostic static char *duplicates = "implied DO variable %s redefined"; 1722*43205Sbostic static char *nonvar = "%s is not a variable"; 1723*43205Sbostic static char *nonint = "%s is not integer"; 1724*43205Sbostic 1725*43205Sbostic register int len; 1726*43205Sbostic register char *repr; 1727*43205Sbostic register int found; 1728*43205Sbostic register dovars *dvp; 1729*43205Sbostic register Namep np; 1730*43205Sbostic register dovars *t; 1731*43205Sbostic 1732*43205Sbostic refrigvexpr( &(dp->init) ); 1733*43205Sbostic refrigvexpr( &(dp->limit) ); 1734*43205Sbostic refrigvexpr( &(dp->step) ); 1735*43205Sbostic 1736*43205Sbostic len = dp->dovar->dname.len; 1737*43205Sbostic repr = dp->dovar->dname.repr; 1738*43205Sbostic 1739*43205Sbostic found = NO; 1740*43205Sbostic dvp = dvlist; 1741*43205Sbostic while (found == NO && dvp != NULL) 1742*43205Sbostic if (len == dvp->len && eqn(len, repr, dvp->repr)) 1743*43205Sbostic found = YES; 1744*43205Sbostic else 1745*43205Sbostic dvp = dvp->next; 1746*43205Sbostic 1747*43205Sbostic if (found == YES) 1748*43205Sbostic { 1749*43205Sbostic errnm(duplicates, len, repr); 1750*43205Sbostic dataerror = YES; 1751*43205Sbostic } 1752*43205Sbostic else 1753*43205Sbostic { 1754*43205Sbostic np = getname(len, repr); 1755*43205Sbostic if (np == NULL) 1756*43205Sbostic { 1757*43205Sbostic if (!ISINT(impltype[letter(*repr)])) 1758*43205Sbostic warnnm(nonint, len, repr); 1759*43205Sbostic } 1760*43205Sbostic else 1761*43205Sbostic { 1762*43205Sbostic if (np->vclass == CLUNKNOWN) 1763*43205Sbostic vardcl(np); 1764*43205Sbostic if (np->vclass != CLVAR) 1765*43205Sbostic warnnm(nonvar, len, repr); 1766*43205Sbostic else if (!ISINT(np->vtype)) 1767*43205Sbostic warnnm(nonint, len, repr); 1768*43205Sbostic } 1769*43205Sbostic } 1770*43205Sbostic 1771*43205Sbostic t = ALLOC(DoVars); 1772*43205Sbostic t->next = dvlist; 1773*43205Sbostic t->len = len; 1774*43205Sbostic t->repr = repr; 1775*43205Sbostic t->valp = ALLOC(Dvalue); 1776*43205Sbostic t->valp->tag = DVALUE; 1777*43205Sbostic dp->dovar = (vexpr *) t->valp; 1778*43205Sbostic 1779*43205Sbostic dvlist = t; 1780*43205Sbostic 1781*43205Sbostic refriglvals(dp->elts); 1782*43205Sbostic 1783*43205Sbostic dvlist = t->next; 1784*43205Sbostic free((char *) t); 1785*43205Sbostic 1786*43205Sbostic return; 1787*43205Sbostic } 1788*43205Sbostic 1789*43205Sbostic 1790*43205Sbostic 1791*43205Sbostic refriglvals(lvals) 1792*43205Sbostic elist *lvals; 1793*43205Sbostic { 1794*43205Sbostic register elist *top; 1795*43205Sbostic 1796*43205Sbostic top = lvals; 1797*43205Sbostic 1798*43205Sbostic while (top != NULL) 1799*43205Sbostic { 1800*43205Sbostic if (top->elt->tag == SIMPLE) 1801*43205Sbostic refrigaelt((aelt *) top->elt); 1802*43205Sbostic else 1803*43205Sbostic refrigdo((dolist *) top->elt); 1804*43205Sbostic 1805*43205Sbostic top = top->next; 1806*43205Sbostic } 1807*43205Sbostic 1808*43205Sbostic return; 1809*43205Sbostic } 1810*43205Sbostic 1811*43205Sbostic 1812*43205Sbostic 1813*43205Sbostic /* Refrig freezes name/value bindings in the DATA name list */ 1814*43205Sbostic 1815*43205Sbostic 1816*43205Sbostic refrig(lvals) 1817*43205Sbostic elist *lvals; 1818*43205Sbostic { 1819*43205Sbostic dvlist = NULL; 1820*43205Sbostic refriglvals(lvals); 1821*43205Sbostic return; 1822*43205Sbostic } 1823*43205Sbostic 1824*43205Sbostic 1825*43205Sbostic 1826*43205Sbostic ftnint 1827*43205Sbostic indexer(ap) 1828*43205Sbostic aelt *ap; 1829*43205Sbostic { 1830*43205Sbostic static char *badvar = "bad variable in indexer"; 1831*43205Sbostic static char *boundserror = "subscript out of bounds"; 1832*43205Sbostic 1833*43205Sbostic register ftnint index; 1834*43205Sbostic register vlist *sp; 1835*43205Sbostic register Namep np; 1836*43205Sbostic register struct Dimblock *dp; 1837*43205Sbostic register int i; 1838*43205Sbostic register dvalue *vp; 1839*43205Sbostic register ftnint size; 1840*43205Sbostic ftnint sub[MAXDIM]; 1841*43205Sbostic 1842*43205Sbostic sp = ap->subs; 1843*43205Sbostic if (sp == NULL) return (0); 1844*43205Sbostic 1845*43205Sbostic np = ap->var; 1846*43205Sbostic dp = np->vdim; 1847*43205Sbostic 1848*43205Sbostic if (dp == NULL) 1849*43205Sbostic fatal(badvar); 1850*43205Sbostic 1851*43205Sbostic i = 0; 1852*43205Sbostic while (sp != NULL) 1853*43205Sbostic { 1854*43205Sbostic vp = (dvalue *) evalvexpr(sp->val); 1855*43205Sbostic 1856*43205Sbostic if (vp->status == NORMAL) 1857*43205Sbostic sub[i++] = vp->value; 1858*43205Sbostic else if ((MININT + MAXINT == -1) && vp->status == MINLESS1) 1859*43205Sbostic sub[i++] = MININT; 1860*43205Sbostic else 1861*43205Sbostic { 1862*43205Sbostic frvexpr((vexpr *) vp); 1863*43205Sbostic return (-1); 1864*43205Sbostic } 1865*43205Sbostic 1866*43205Sbostic frvexpr((vexpr *) vp); 1867*43205Sbostic sp = sp->next; 1868*43205Sbostic } 1869*43205Sbostic 1870*43205Sbostic index = sub[--i]; 1871*43205Sbostic while (i-- > 0) 1872*43205Sbostic { 1873*43205Sbostic size = dp->dims[i].dimsize->constblock.const.ci; 1874*43205Sbostic index = sub[i] + index * size; 1875*43205Sbostic } 1876*43205Sbostic 1877*43205Sbostic index -= dp->baseoffset->constblock.const.ci; 1878*43205Sbostic 1879*43205Sbostic if (index < 0 || index >= dp->nelt->constblock.const.ci) 1880*43205Sbostic { 1881*43205Sbostic err(boundserror); 1882*43205Sbostic return (-1); 1883*43205Sbostic } 1884*43205Sbostic 1885*43205Sbostic return (index); 1886*43205Sbostic } 1887*43205Sbostic 1888*43205Sbostic 1889*43205Sbostic 1890*43205Sbostic savedata(lvals, rvals) 1891*43205Sbostic elist *lvals; 1892*43205Sbostic vallist *rvals; 1893*43205Sbostic { 1894*43205Sbostic static char *toomany = "more data values than data items"; 1895*43205Sbostic 1896*43205Sbostic register elist *top; 1897*43205Sbostic 1898*43205Sbostic dataerror = NO; 1899*43205Sbostic badvalue = NO; 1900*43205Sbostic 1901*43205Sbostic lvals = revelist(lvals); 1902*43205Sbostic grvals = revrvals(rvals); 1903*43205Sbostic 1904*43205Sbostic refrig(lvals); 1905*43205Sbostic 1906*43205Sbostic if (!dataerror) 1907*43205Sbostic outdata(lvals); 1908*43205Sbostic 1909*43205Sbostic frelist(lvals); 1910*43205Sbostic 1911*43205Sbostic while (grvals != NULL && dataerror == NO) 1912*43205Sbostic { 1913*43205Sbostic if (grvals->status != NORMAL) 1914*43205Sbostic dataerror = YES; 1915*43205Sbostic else if (grvals->repl <= 0) 1916*43205Sbostic grvals = grvals->next; 1917*43205Sbostic else 1918*43205Sbostic { 1919*43205Sbostic err(toomany); 1920*43205Sbostic dataerror = YES; 1921*43205Sbostic } 1922*43205Sbostic } 1923*43205Sbostic 1924*43205Sbostic frvallist(grvals); 1925*43205Sbostic 1926*43205Sbostic return; 1927*43205Sbostic } 1928*43205Sbostic 1929*43205Sbostic 1930*43205Sbostic 1931*43205Sbostic setdfiles(np) 1932*43205Sbostic register Namep np; 1933*43205Sbostic { 1934*43205Sbostic register struct Extsym *cp; 1935*43205Sbostic register struct Equivblock *ep; 1936*43205Sbostic register int stg; 1937*43205Sbostic register int type; 1938*43205Sbostic register ftnint typelen; 1939*43205Sbostic register ftnint nelt; 1940*43205Sbostic register ftnint varsize; 1941*43205Sbostic 1942*43205Sbostic stg = np->vstg; 1943*43205Sbostic 1944*43205Sbostic if (stg == STGBSS || stg == STGINIT) 1945*43205Sbostic { 1946*43205Sbostic datafile = vdatafile; 1947*43205Sbostic chkfile = vchkfile; 1948*43205Sbostic if (np->init == YES) 1949*43205Sbostic base = np->initoffset; 1950*43205Sbostic else 1951*43205Sbostic { 1952*43205Sbostic np->init = YES; 1953*43205Sbostic np->initoffset = base = vdatahwm; 1954*43205Sbostic if (np->vdim != NULL) 1955*43205Sbostic nelt = np->vdim->nelt->constblock.const.ci; 1956*43205Sbostic else 1957*43205Sbostic nelt = 1; 1958*43205Sbostic type = np->vtype; 1959*43205Sbostic if (type == TYCHAR) 1960*43205Sbostic typelen = np->vleng->constblock.const.ci; 1961*43205Sbostic else if (type == TYLOGICAL) 1962*43205Sbostic typelen = typesize[tylogical]; 1963*43205Sbostic else 1964*43205Sbostic typelen = typesize[type]; 1965*43205Sbostic varsize = nelt * typelen; 1966*43205Sbostic vdatahwm += varsize; 1967*43205Sbostic } 1968*43205Sbostic } 1969*43205Sbostic else if (stg == STGEQUIV) 1970*43205Sbostic { 1971*43205Sbostic datafile = vdatafile; 1972*43205Sbostic chkfile = vchkfile; 1973*43205Sbostic ep = &eqvclass[np->vardesc.varno]; 1974*43205Sbostic if (ep->init == YES) 1975*43205Sbostic base = ep->initoffset; 1976*43205Sbostic else 1977*43205Sbostic { 1978*43205Sbostic ep->init = YES; 1979*43205Sbostic ep->initoffset = base = vdatahwm; 1980*43205Sbostic vdatahwm += ep->eqvleng; 1981*43205Sbostic } 1982*43205Sbostic base += np->voffset; 1983*43205Sbostic } 1984*43205Sbostic else if (stg == STGCOMMON) 1985*43205Sbostic { 1986*43205Sbostic datafile = cdatafile; 1987*43205Sbostic chkfile = cchkfile; 1988*43205Sbostic cp = &extsymtab[np->vardesc.varno]; 1989*43205Sbostic if (cp->init == YES) 1990*43205Sbostic base = cp->initoffset; 1991*43205Sbostic else 1992*43205Sbostic { 1993*43205Sbostic cp->init = YES; 1994*43205Sbostic cp->initoffset = base = cdatahwm; 1995*43205Sbostic cdatahwm += cp->maxleng; 1996*43205Sbostic } 1997*43205Sbostic base += np->voffset; 1998*43205Sbostic } 1999*43205Sbostic 2000*43205Sbostic return; 2001*43205Sbostic } 2002*43205Sbostic 2003*43205Sbostic 2004*43205Sbostic 2005*43205Sbostic wrtdata(offset, repl, len, const) 2006*43205Sbostic long offset; 2007*43205Sbostic ftnint repl; 2008*43205Sbostic ftnint len; 2009*43205Sbostic char *const; 2010*43205Sbostic { 2011*43205Sbostic static char *badoffset = "bad offset in wrtdata"; 2012*43205Sbostic static char *toomuch = "too much data"; 2013*43205Sbostic static char *readerror = "read error on tmp file"; 2014*43205Sbostic static char *writeerror = "write error on tmp file"; 2015*43205Sbostic static char *seekerror = "seek error on tmp file"; 2016*43205Sbostic 2017*43205Sbostic register ftnint k; 2018*43205Sbostic long lastbyte; 2019*43205Sbostic int bitpos; 2020*43205Sbostic long chkoff; 2021*43205Sbostic long lastoff; 2022*43205Sbostic long chklen; 2023*43205Sbostic long pos; 2024*43205Sbostic int n; 2025*43205Sbostic ftnint nbytes; 2026*43205Sbostic int mask; 2027*43205Sbostic register int i; 2028*43205Sbostic char overlap; 2029*43205Sbostic char allzero; 2030*43205Sbostic char buff[BUFSIZ]; 2031*43205Sbostic 2032*43205Sbostic if (offset < 0) 2033*43205Sbostic fatal(badoffset); 2034*43205Sbostic 2035*43205Sbostic overlap = NO; 2036*43205Sbostic 2037*43205Sbostic k = repl * len; 2038*43205Sbostic lastbyte = offset + k - 1; 2039*43205Sbostic if (lastbyte < 0) 2040*43205Sbostic { 2041*43205Sbostic err(toomuch); 2042*43205Sbostic dataerror = YES; 2043*43205Sbostic return; 2044*43205Sbostic } 2045*43205Sbostic 2046*43205Sbostic bitpos = offset % BYTESIZE; 2047*43205Sbostic chkoff = offset/BYTESIZE; 2048*43205Sbostic lastoff = lastbyte/BYTESIZE; 2049*43205Sbostic chklen = lastoff - chkoff + 1; 2050*43205Sbostic 2051*43205Sbostic pos = lseek(chkfile, chkoff, 0); 2052*43205Sbostic if (pos == -1) 2053*43205Sbostic { 2054*43205Sbostic err(seekerror); 2055*43205Sbostic done(1); 2056*43205Sbostic } 2057*43205Sbostic 2058*43205Sbostic while (k > 0) 2059*43205Sbostic { 2060*43205Sbostic if (chklen <= BUFSIZ) 2061*43205Sbostic n = chklen; 2062*43205Sbostic else 2063*43205Sbostic { 2064*43205Sbostic n = BUFSIZ; 2065*43205Sbostic chklen -= BUFSIZ; 2066*43205Sbostic } 2067*43205Sbostic 2068*43205Sbostic nbytes = read(chkfile, buff, n); 2069*43205Sbostic if (nbytes < 0) 2070*43205Sbostic { 2071*43205Sbostic err(readerror); 2072*43205Sbostic done(1); 2073*43205Sbostic } 2074*43205Sbostic 2075*43205Sbostic if (nbytes == 0) 2076*43205Sbostic buff[0] = '\0'; 2077*43205Sbostic 2078*43205Sbostic if (nbytes < n) 2079*43205Sbostic buff[ n-1 ] = '\0'; 2080*43205Sbostic 2081*43205Sbostic i = 0; 2082*43205Sbostic 2083*43205Sbostic if (bitpos > 0) 2084*43205Sbostic { 2085*43205Sbostic while (k > 0 && bitpos < BYTESIZE) 2086*43205Sbostic { 2087*43205Sbostic mask = 1 << bitpos; 2088*43205Sbostic 2089*43205Sbostic if (mask & buff[0]) 2090*43205Sbostic overlap = YES; 2091*43205Sbostic else 2092*43205Sbostic buff[0] |= mask; 2093*43205Sbostic 2094*43205Sbostic k--; 2095*43205Sbostic bitpos++; 2096*43205Sbostic } 2097*43205Sbostic 2098*43205Sbostic if (bitpos == BYTESIZE) 2099*43205Sbostic { 2100*43205Sbostic bitpos = 0; 2101*43205Sbostic i++; 2102*43205Sbostic } 2103*43205Sbostic } 2104*43205Sbostic 2105*43205Sbostic while (i < nbytes && overlap == NO) 2106*43205Sbostic { 2107*43205Sbostic if (buff[i] == 0 && k >= BYTESIZE) 2108*43205Sbostic { 2109*43205Sbostic buff[i++] = MAXBYTE; 2110*43205Sbostic k -= BYTESIZE; 2111*43205Sbostic } 2112*43205Sbostic else if (k < BYTESIZE) 2113*43205Sbostic { 2114*43205Sbostic while (k-- > 0) 2115*43205Sbostic { 2116*43205Sbostic mask = 1 << k; 2117*43205Sbostic if (mask & buff[i]) 2118*43205Sbostic overlap = YES; 2119*43205Sbostic else 2120*43205Sbostic buff[i] |= mask; 2121*43205Sbostic } 2122*43205Sbostic i++; 2123*43205Sbostic } 2124*43205Sbostic else 2125*43205Sbostic { 2126*43205Sbostic overlap = YES; 2127*43205Sbostic buff[i++] = MAXBYTE; 2128*43205Sbostic k -= BYTESIZE; 2129*43205Sbostic } 2130*43205Sbostic } 2131*43205Sbostic 2132*43205Sbostic while (i < n) 2133*43205Sbostic { 2134*43205Sbostic if (k >= BYTESIZE) 2135*43205Sbostic { 2136*43205Sbostic buff[i++] = MAXBYTE; 2137*43205Sbostic k -= BYTESIZE; 2138*43205Sbostic } 2139*43205Sbostic else 2140*43205Sbostic { 2141*43205Sbostic while (k-- > 0) 2142*43205Sbostic { 2143*43205Sbostic mask = 1 << k; 2144*43205Sbostic buff[i] |= mask; 2145*43205Sbostic } 2146*43205Sbostic i++; 2147*43205Sbostic } 2148*43205Sbostic } 2149*43205Sbostic 2150*43205Sbostic pos = lseek(chkfile, -nbytes, 1); 2151*43205Sbostic if (pos == -1) 2152*43205Sbostic { 2153*43205Sbostic err(seekerror); 2154*43205Sbostic done(1); 2155*43205Sbostic } 2156*43205Sbostic 2157*43205Sbostic nbytes = write(chkfile, buff, n); 2158*43205Sbostic if (nbytes != n) 2159*43205Sbostic { 2160*43205Sbostic err(writeerror); 2161*43205Sbostic done(1); 2162*43205Sbostic } 2163*43205Sbostic } 2164*43205Sbostic 2165*43205Sbostic if (overlap == NO) 2166*43205Sbostic { 2167*43205Sbostic allzero = YES; 2168*43205Sbostic k = len; 2169*43205Sbostic 2170*43205Sbostic while (k > 0 && allzero != NO) 2171*43205Sbostic if (const[--k] != 0) allzero = NO; 2172*43205Sbostic 2173*43205Sbostic if (allzero == YES) 2174*43205Sbostic return; 2175*43205Sbostic } 2176*43205Sbostic 2177*43205Sbostic pos = lseek(datafile, offset, 0); 2178*43205Sbostic if (pos == -1) 2179*43205Sbostic { 2180*43205Sbostic err(seekerror); 2181*43205Sbostic done(1); 2182*43205Sbostic } 2183*43205Sbostic 2184*43205Sbostic k = repl; 2185*43205Sbostic while (k-- > 0) 2186*43205Sbostic { 2187*43205Sbostic nbytes = write(datafile, const, len); 2188*43205Sbostic if (nbytes != len) 2189*43205Sbostic { 2190*43205Sbostic err(writeerror); 2191*43205Sbostic done(1); 2192*43205Sbostic } 2193*43205Sbostic } 2194*43205Sbostic 2195*43205Sbostic if (overlap) overlapflag = YES; 2196*43205Sbostic 2197*43205Sbostic return; 2198*43205Sbostic } 2199*43205Sbostic 2200*43205Sbostic 2201*43205Sbostic 2202*43205Sbostic Constp 2203*43205Sbostic getdatum() 2204*43205Sbostic { 2205*43205Sbostic static char *toofew = "more data items than data values"; 2206*43205Sbostic 2207*43205Sbostic register vallist *t; 2208*43205Sbostic 2209*43205Sbostic while (grvals != NULL) 2210*43205Sbostic { 2211*43205Sbostic if (grvals->status != NORMAL) 2212*43205Sbostic { 2213*43205Sbostic dataerror = YES; 2214*43205Sbostic return (NULL); 2215*43205Sbostic } 2216*43205Sbostic else if (grvals->repl > 0) 2217*43205Sbostic { 2218*43205Sbostic grvals->repl--; 2219*43205Sbostic return (grvals->value); 2220*43205Sbostic } 2221*43205Sbostic else 2222*43205Sbostic { 2223*43205Sbostic badvalue = 0; 2224*43205Sbostic frexpr ((tagptr) grvals->value); 2225*43205Sbostic t = grvals; 2226*43205Sbostic grvals = t->next; 2227*43205Sbostic free((char *) t); 2228*43205Sbostic } 2229*43205Sbostic } 2230*43205Sbostic 2231*43205Sbostic err(toofew); 2232*43205Sbostic dataerror = YES; 2233*43205Sbostic return (NULL); 2234*43205Sbostic } 2235*43205Sbostic 2236*43205Sbostic 2237*43205Sbostic 2238*43205Sbostic outdata(lvals) 2239*43205Sbostic elist *lvals; 2240*43205Sbostic { 2241*43205Sbostic register elist *top; 2242*43205Sbostic 2243*43205Sbostic top = lvals; 2244*43205Sbostic 2245*43205Sbostic while (top != NULL && dataerror == NO) 2246*43205Sbostic { 2247*43205Sbostic if (top->elt->tag == SIMPLE) 2248*43205Sbostic outaelt((aelt *) top->elt); 2249*43205Sbostic else 2250*43205Sbostic outdolist((dolist *) top->elt); 2251*43205Sbostic 2252*43205Sbostic top = top->next; 2253*43205Sbostic } 2254*43205Sbostic 2255*43205Sbostic return; 2256*43205Sbostic } 2257*43205Sbostic 2258*43205Sbostic 2259*43205Sbostic 2260*43205Sbostic outaelt(ap) 2261*43205Sbostic aelt *ap; 2262*43205Sbostic { 2263*43205Sbostic static char *toofew = "more data items than data values"; 2264*43205Sbostic static char *boundserror = "substring expression out of bounds"; 2265*43205Sbostic static char *order = "substring expressions out of order"; 2266*43205Sbostic 2267*43205Sbostic register Namep np; 2268*43205Sbostic register long soffset; 2269*43205Sbostic register dvalue *lwb; 2270*43205Sbostic register dvalue *upb; 2271*43205Sbostic register Constp const; 2272*43205Sbostic register int k; 2273*43205Sbostic register vallist *t; 2274*43205Sbostic register int type; 2275*43205Sbostic register ftnint typelen; 2276*43205Sbostic register ftnint repl; 2277*43205Sbostic 2278*43205Sbostic extern char *packbytes(); 2279*43205Sbostic 2280*43205Sbostic np = ap->var; 2281*43205Sbostic setdfiles(np); 2282*43205Sbostic 2283*43205Sbostic type = np->vtype; 2284*43205Sbostic 2285*43205Sbostic if (type == TYCHAR) 2286*43205Sbostic typelen = np->vleng->constblock.const.ci; 2287*43205Sbostic else if (type == TYLOGICAL) 2288*43205Sbostic typelen = typesize[tylogical]; 2289*43205Sbostic else 2290*43205Sbostic typelen = typesize[type]; 2291*43205Sbostic 2292*43205Sbostic if (ap->subs != NULL || np->vdim == NULL) 2293*43205Sbostic { 2294*43205Sbostic soffset = indexer(ap); 2295*43205Sbostic if (soffset == -1) 2296*43205Sbostic { 2297*43205Sbostic dataerror = YES; 2298*43205Sbostic return; 2299*43205Sbostic } 2300*43205Sbostic 2301*43205Sbostic soffset = soffset * typelen; 2302*43205Sbostic 2303*43205Sbostic if (ap->range != NULL) 2304*43205Sbostic { 2305*43205Sbostic lwb = (dvalue *) evalvexpr(ap->range->low); 2306*43205Sbostic upb = (dvalue *) evalvexpr(ap->range->high); 2307*43205Sbostic if (lwb->status == ERRVAL || upb->status == ERRVAL) 2308*43205Sbostic { 2309*43205Sbostic frvexpr((vexpr *) lwb); 2310*43205Sbostic frvexpr((vexpr *) upb); 2311*43205Sbostic dataerror = YES; 2312*43205Sbostic return; 2313*43205Sbostic } 2314*43205Sbostic 2315*43205Sbostic if (lwb->status != NORMAL || 2316*43205Sbostic lwb->value < 1 || 2317*43205Sbostic lwb->value > typelen || 2318*43205Sbostic upb->status != NORMAL || 2319*43205Sbostic upb->value < 1 || 2320*43205Sbostic upb->value > typelen) 2321*43205Sbostic { 2322*43205Sbostic err(boundserror); 2323*43205Sbostic frvexpr((vexpr *) lwb); 2324*43205Sbostic frvexpr((vexpr *) upb); 2325*43205Sbostic dataerror = YES; 2326*43205Sbostic return; 2327*43205Sbostic } 2328*43205Sbostic 2329*43205Sbostic if (lwb->value > upb->value) 2330*43205Sbostic { 2331*43205Sbostic err(order); 2332*43205Sbostic frvexpr((vexpr *) lwb); 2333*43205Sbostic frvexpr((vexpr *) upb); 2334*43205Sbostic dataerror = YES; 2335*43205Sbostic return; 2336*43205Sbostic } 2337*43205Sbostic 2338*43205Sbostic soffset = soffset + lwb->value - 1; 2339*43205Sbostic typelen = upb->value - lwb->value + 1; 2340*43205Sbostic frvexpr((vexpr *) lwb); 2341*43205Sbostic frvexpr((vexpr *) upb); 2342*43205Sbostic } 2343*43205Sbostic 2344*43205Sbostic const = getdatum(); 2345*43205Sbostic if (const == NULL || !ISCONST(const)) 2346*43205Sbostic return; 2347*43205Sbostic 2348*43205Sbostic const = (Constp) convconst(type, typelen, const); 2349*43205Sbostic if (const == NULL || !ISCONST(const)) 2350*43205Sbostic { 2351*43205Sbostic frexpr((tagptr) const); 2352*43205Sbostic return; 2353*43205Sbostic } 2354*43205Sbostic 2355*43205Sbostic if (type == TYCHAR) 2356*43205Sbostic wrtdata(base + soffset, 1, typelen, const->const.ccp); 2357*43205Sbostic else 2358*43205Sbostic wrtdata(base + soffset, 1, typelen, packbytes(const)); 2359*43205Sbostic 2360*43205Sbostic frexpr((tagptr) const); 2361*43205Sbostic } 2362*43205Sbostic else 2363*43205Sbostic { 2364*43205Sbostic soffset = 0; 2365*43205Sbostic k = np->vdim->nelt->constblock.const.ci; 2366*43205Sbostic while (k > 0 && dataerror == NO) 2367*43205Sbostic { 2368*43205Sbostic if (grvals == NULL) 2369*43205Sbostic { 2370*43205Sbostic err(toofew); 2371*43205Sbostic dataerror = YES; 2372*43205Sbostic } 2373*43205Sbostic else if (grvals->status != NORMAL) 2374*43205Sbostic dataerror = YES; 2375*43205Sbostic else if (grvals-> repl <= 0) 2376*43205Sbostic { 2377*43205Sbostic badvalue = 0; 2378*43205Sbostic frexpr((tagptr) grvals->value); 2379*43205Sbostic t = grvals; 2380*43205Sbostic grvals = t->next; 2381*43205Sbostic free((char *) t); 2382*43205Sbostic } 2383*43205Sbostic else 2384*43205Sbostic { 2385*43205Sbostic const = grvals->value; 2386*43205Sbostic if (const == NULL || !ISCONST(const)) 2387*43205Sbostic { 2388*43205Sbostic dataerror = YES; 2389*43205Sbostic } 2390*43205Sbostic else 2391*43205Sbostic { 2392*43205Sbostic const = (Constp) convconst(type, typelen, const); 2393*43205Sbostic if (const == NULL || !ISCONST(const)) 2394*43205Sbostic { 2395*43205Sbostic dataerror = YES; 2396*43205Sbostic frexpr((tagptr) const); 2397*43205Sbostic } 2398*43205Sbostic else 2399*43205Sbostic { 2400*43205Sbostic if (k > grvals->repl) 2401*43205Sbostic repl = grvals->repl; 2402*43205Sbostic else 2403*43205Sbostic repl = k; 2404*43205Sbostic 2405*43205Sbostic grvals->repl -= repl; 2406*43205Sbostic k -= repl; 2407*43205Sbostic 2408*43205Sbostic if (type == TYCHAR) 2409*43205Sbostic wrtdata(base+soffset, repl, typelen, const->const.ccp); 2410*43205Sbostic else 2411*43205Sbostic wrtdata(base+soffset, repl, typelen, packbytes(const)); 2412*43205Sbostic 2413*43205Sbostic soffset = soffset + repl * typelen; 2414*43205Sbostic 2415*43205Sbostic frexpr((tagptr) const); 2416*43205Sbostic } 2417*43205Sbostic } 2418*43205Sbostic } 2419*43205Sbostic } 2420*43205Sbostic } 2421*43205Sbostic 2422*43205Sbostic return; 2423*43205Sbostic } 2424*43205Sbostic 2425*43205Sbostic 2426*43205Sbostic 2427*43205Sbostic outdolist(dp) 2428*43205Sbostic dolist *dp; 2429*43205Sbostic { 2430*43205Sbostic static char *zerostep = "zero step in implied-DO"; 2431*43205Sbostic static char *order = "zero iteration count in implied-DO"; 2432*43205Sbostic 2433*43205Sbostic register dvalue *e1, *e2, *e3; 2434*43205Sbostic register int direction; 2435*43205Sbostic register dvalue *dv; 2436*43205Sbostic register int done; 2437*43205Sbostic register int addin; 2438*43205Sbostic register int ts; 2439*43205Sbostic register ftnint tv; 2440*43205Sbostic 2441*43205Sbostic e1 = (dvalue *) evalvexpr(dp->init); 2442*43205Sbostic e2 = (dvalue *) evalvexpr(dp->limit); 2443*43205Sbostic e3 = (dvalue *) evalvexpr(dp->step); 2444*43205Sbostic 2445*43205Sbostic if (e1->status == ERRVAL || 2446*43205Sbostic e2->status == ERRVAL || 2447*43205Sbostic e3->status == ERRVAL) 2448*43205Sbostic { 2449*43205Sbostic dataerror = YES; 2450*43205Sbostic goto ret; 2451*43205Sbostic } 2452*43205Sbostic 2453*43205Sbostic if (e1->status == NORMAL) 2454*43205Sbostic { 2455*43205Sbostic if (e2->status == NORMAL) 2456*43205Sbostic { 2457*43205Sbostic if (e1->value < e2->value) 2458*43205Sbostic direction = 1; 2459*43205Sbostic else if (e1->value > e2->value) 2460*43205Sbostic direction = -1; 2461*43205Sbostic else 2462*43205Sbostic direction = 0; 2463*43205Sbostic } 2464*43205Sbostic else if (e2->status == MAXPLUS1) 2465*43205Sbostic direction = 1; 2466*43205Sbostic else 2467*43205Sbostic direction = -1; 2468*43205Sbostic } 2469*43205Sbostic else if (e1->status == MAXPLUS1) 2470*43205Sbostic { 2471*43205Sbostic if (e2->status == MAXPLUS1) 2472*43205Sbostic direction = 0; 2473*43205Sbostic else 2474*43205Sbostic direction = -1; 2475*43205Sbostic } 2476*43205Sbostic else 2477*43205Sbostic { 2478*43205Sbostic if (e2->status == MINLESS1) 2479*43205Sbostic direction = 0; 2480*43205Sbostic else 2481*43205Sbostic direction = 1; 2482*43205Sbostic } 2483*43205Sbostic 2484*43205Sbostic if (e3->status == NORMAL && e3->value == 0) 2485*43205Sbostic { 2486*43205Sbostic err(zerostep); 2487*43205Sbostic dataerror = YES; 2488*43205Sbostic goto ret; 2489*43205Sbostic } 2490*43205Sbostic else if (e3->status == MAXPLUS1 || 2491*43205Sbostic (e3->status == NORMAL && e3->value > 0)) 2492*43205Sbostic { 2493*43205Sbostic if (direction == -1) 2494*43205Sbostic { 2495*43205Sbostic warn(order); 2496*43205Sbostic goto ret; 2497*43205Sbostic } 2498*43205Sbostic } 2499*43205Sbostic else 2500*43205Sbostic { 2501*43205Sbostic if (direction == 1) 2502*43205Sbostic { 2503*43205Sbostic warn(order); 2504*43205Sbostic goto ret; 2505*43205Sbostic } 2506*43205Sbostic } 2507*43205Sbostic 2508*43205Sbostic dv = (dvalue *) dp->dovar; 2509*43205Sbostic dv->status = e1->status; 2510*43205Sbostic dv->value = e1->value; 2511*43205Sbostic 2512*43205Sbostic done = NO; 2513*43205Sbostic while (done == NO && dataerror == NO) 2514*43205Sbostic { 2515*43205Sbostic outdata(dp->elts); 2516*43205Sbostic 2517*43205Sbostic if (e3->status == NORMAL && dv->status == NORMAL) 2518*43205Sbostic { 2519*43205Sbostic addints(e3->value, dv->value); 2520*43205Sbostic dv->status = rstatus; 2521*43205Sbostic dv->value = rvalue; 2522*43205Sbostic } 2523*43205Sbostic else 2524*43205Sbostic { 2525*43205Sbostic if (e3->status != NORMAL) 2526*43205Sbostic { 2527*43205Sbostic if (e3->status == MAXPLUS1) 2528*43205Sbostic addin = MAXPLUS1; 2529*43205Sbostic else 2530*43205Sbostic addin = MINLESS1; 2531*43205Sbostic ts = dv->status; 2532*43205Sbostic tv = dv->value; 2533*43205Sbostic } 2534*43205Sbostic else 2535*43205Sbostic { 2536*43205Sbostic if (dv->status == MAXPLUS1) 2537*43205Sbostic addin = MAXPLUS1; 2538*43205Sbostic else 2539*43205Sbostic addin = MINLESS1; 2540*43205Sbostic ts = e3->status; 2541*43205Sbostic tv = e3->value; 2542*43205Sbostic } 2543*43205Sbostic 2544*43205Sbostic if (addin == MAXPLUS1) 2545*43205Sbostic { 2546*43205Sbostic if (ts == MAXPLUS1 || (ts == NORMAL && tv > 0)) 2547*43205Sbostic dv->status = ERRVAL; 2548*43205Sbostic else if (ts == NORMAL && tv == 0) 2549*43205Sbostic dv->status = MAXPLUS1; 2550*43205Sbostic else if (ts == NORMAL) 2551*43205Sbostic { 2552*43205Sbostic dv->status = NORMAL; 2553*43205Sbostic dv->value = tv + MAXINT; 2554*43205Sbostic dv->value++; 2555*43205Sbostic } 2556*43205Sbostic else 2557*43205Sbostic { 2558*43205Sbostic dv->status = NORMAL; 2559*43205Sbostic dv->value = 0; 2560*43205Sbostic } 2561*43205Sbostic } 2562*43205Sbostic else 2563*43205Sbostic { 2564*43205Sbostic if (ts == MINLESS1 || (ts == NORMAL && tv < 0)) 2565*43205Sbostic dv->status = ERRVAL; 2566*43205Sbostic else if (ts == NORMAL && tv == 0) 2567*43205Sbostic dv->status = MINLESS1; 2568*43205Sbostic else if (ts == NORMAL) 2569*43205Sbostic { 2570*43205Sbostic dv->status = NORMAL; 2571*43205Sbostic dv->value = tv - MAXINT; 2572*43205Sbostic dv->value--; 2573*43205Sbostic } 2574*43205Sbostic else 2575*43205Sbostic { 2576*43205Sbostic dv->status = NORMAL; 2577*43205Sbostic dv->value = 0; 2578*43205Sbostic } 2579*43205Sbostic } 2580*43205Sbostic } 2581*43205Sbostic 2582*43205Sbostic if (dv->status == ERRVAL) 2583*43205Sbostic done = YES; 2584*43205Sbostic else if (direction > 0) 2585*43205Sbostic { 2586*43205Sbostic if (e2->status == NORMAL) 2587*43205Sbostic { 2588*43205Sbostic if (dv->status == MAXPLUS1 || 2589*43205Sbostic (dv->status == NORMAL && dv->value > e2->value)) 2590*43205Sbostic done = YES; 2591*43205Sbostic } 2592*43205Sbostic } 2593*43205Sbostic else if (direction < 0) 2594*43205Sbostic { 2595*43205Sbostic if (e2->status == NORMAL) 2596*43205Sbostic { 2597*43205Sbostic if (dv->status == MINLESS1 || 2598*43205Sbostic (dv->status == NORMAL && dv->value < e2->value)) 2599*43205Sbostic done = YES; 2600*43205Sbostic } 2601*43205Sbostic } 2602*43205Sbostic else 2603*43205Sbostic done = YES; 2604*43205Sbostic } 2605*43205Sbostic 2606*43205Sbostic ret: 2607*43205Sbostic frvexpr((vexpr *) e1); 2608*43205Sbostic frvexpr((vexpr *) e2); 2609*43205Sbostic frvexpr((vexpr *) e3); 2610*43205Sbostic return; 2611*43205Sbostic } 2612