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