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