Annotation of 43BSDTahoe/usr.bin/f77/f77.tahoe/f77pass1/data.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.