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