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