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