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

unix.superglobalmegacorp.com

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