xref: /original-bsd/usr.bin/f77/pass1.tahoe/conv.c (revision b8be84b8)
1*b8be84b8Sbostic /*-
2*b8be84b8Sbostic  * Copyright (c) 1980 The Regents of the University of California.
3*b8be84b8Sbostic  * All rights reserved.
4*b8be84b8Sbostic  *
5*b8be84b8Sbostic  * %sccs.include.proprietary.c%
6*b8be84b8Sbostic  */
7*b8be84b8Sbostic 
8*b8be84b8Sbostic #ifndef lint
9*b8be84b8Sbostic static char sccsid[] = "@(#)conv.c	5.3 (Berkeley) 04/12/91";
10*b8be84b8Sbostic #endif /* not lint */
11*b8be84b8Sbostic 
125d35f963Sbostic #include "defs.h"
135d35f963Sbostic #include "conv.h"
145d35f963Sbostic 
155d35f963Sbostic int badvalue;
165d35f963Sbostic 
175d35f963Sbostic 
185d35f963Sbostic /*  The following constants are used to check the limits of  */
195d35f963Sbostic /*  conversions.  Dmaxword is the largest double precision   */
205d35f963Sbostic /*  number which can be converted to a two-byte integer      */
215d35f963Sbostic /*  without overflow.  Dminword is the smallest double       */
225d35f963Sbostic /*  precision value which can be converted to a two-byte     */
235d35f963Sbostic /*  integer without overflow.  Dmaxint and dminint are the   */
245d35f963Sbostic /*  analogous values for four-byte integers.                 */
255d35f963Sbostic 
265d35f963Sbostic /* short array should be correct for both VAX and TAHOE */
275d35f963Sbostic 
285d35f963Sbostic LOCAL short dmaxword[] = { 0x47ff, 0xfeff, 0xffff, 0xffff }; /* 32767.5 */
295d35f963Sbostic LOCAL short dminword[] = { 0xc800, 0x007f, 0xffff, 0xffff }; /* -32768.499999999999 */
305d35f963Sbostic 
315d35f963Sbostic LOCAL short dmaxint[]  = { 0x4fff, 0xffff, 0xfeff, 0xffff }; /* 2147483647.5 */
325d35f963Sbostic LOCAL short dminint[]  = { 0xd000, 0x0000, 0x007f, 0xffff }; /* -2147483648.4999999 */
335d35f963Sbostic 
345d35f963Sbostic LOCAL short dmaxreal[] = { 0x7fff, 0xffff, 0x7fff, 0xffff }; /* 1.7014117838986683e+38 */
355d35f963Sbostic LOCAL short dminreal[] = { 0xffff, 0xffff, 0x7fff, 0xffff }; /* -1.7014117838986683e+38 */
365d35f963Sbostic 
375d35f963Sbostic 
385d35f963Sbostic 
395d35f963Sbostic /*  The routines which follow are used to convert  */
405d35f963Sbostic /*  constants into constants of other types.       */
415d35f963Sbostic 
425d35f963Sbostic LOCAL char *
grabbits(len,cp)435d35f963Sbostic grabbits(len, cp)
445d35f963Sbostic int len;
455d35f963Sbostic Constp cp;
465d35f963Sbostic {
475d35f963Sbostic 
485d35f963Sbostic   static char *toobig = "bit value too large";
495d35f963Sbostic 
505d35f963Sbostic   register char *p;
515d35f963Sbostic   register char *bits;
525d35f963Sbostic   register int i;
535d35f963Sbostic   register int k;
545d35f963Sbostic   register int lenb;
555d35f963Sbostic 
5686947eabSbostic   bits = cp->constant.ccp;
5786947eabSbostic   lenb = cp->vleng->constblock.constant.ci;
585d35f963Sbostic 
595d35f963Sbostic   p = (char *) ckalloc(len);
605d35f963Sbostic 
615d35f963Sbostic   if (len >= lenb)
625d35f963Sbostic     k = lenb;
635d35f963Sbostic   else
645d35f963Sbostic     {
655d35f963Sbostic       k = len;
665d35f963Sbostic       if ( badvalue == 0 )
675d35f963Sbostic 	{
685d35f963Sbostic #if (HERE == PDP11 || HERE == VAX)
695d35f963Sbostic 	  i = len;
705d35f963Sbostic 	  while ( i < lenb && bits[i] == 0 )
715d35f963Sbostic 	    i++;
725d35f963Sbostic 	  if (i < lenb)
735d35f963Sbostic 	    badvalue = 1;
745d35f963Sbostic #else
755d35f963Sbostic 	  i = lenb - len - 1;
765d35f963Sbostic 	  while ( i >= 0 && bits[i] == 0)
775d35f963Sbostic 	    i--;
785d35f963Sbostic 	  if (i >= 0)
795d35f963Sbostic 	    badvalue = 1;
805d35f963Sbostic #endif
815d35f963Sbostic 	  if (badvalue)
825d35f963Sbostic 	    warn(toobig);
835d35f963Sbostic 	}
845d35f963Sbostic     }
855d35f963Sbostic 
865d35f963Sbostic #if (HERE == PDP11 || HERE == VAX)
875d35f963Sbostic   i = 0;
885d35f963Sbostic   while (i < k)
895d35f963Sbostic     {
905d35f963Sbostic       p[i] = bits[i];
915d35f963Sbostic       i++;
925d35f963Sbostic     }
935d35f963Sbostic #else
945d35f963Sbostic   i = lenb;
955d35f963Sbostic   while (k > 0)
965d35f963Sbostic     p[--k] = bits[--i];
975d35f963Sbostic #endif
985d35f963Sbostic 
995d35f963Sbostic   return (p);
1005d35f963Sbostic }
1015d35f963Sbostic 
1025d35f963Sbostic 
1035d35f963Sbostic 
1045d35f963Sbostic LOCAL char *
grabbytes(len,cp)1055d35f963Sbostic grabbytes(len, cp)
1065d35f963Sbostic int len;
1075d35f963Sbostic Constp cp;
1085d35f963Sbostic {
1095d35f963Sbostic   register char *p;
1105d35f963Sbostic   register char *bytes;
1115d35f963Sbostic   register int i;
1125d35f963Sbostic   register int k;
1135d35f963Sbostic   register int lenb;
1145d35f963Sbostic 
11586947eabSbostic   bytes = cp->constant.ccp;
11686947eabSbostic   lenb = cp->vleng->constblock.constant.ci;
1175d35f963Sbostic 
1185d35f963Sbostic   p = (char *) ckalloc(len);
1195d35f963Sbostic 
1205d35f963Sbostic   if (len >= lenb)
1215d35f963Sbostic     k = lenb;
1225d35f963Sbostic   else
1235d35f963Sbostic     k = len;
1245d35f963Sbostic 
1255d35f963Sbostic   i = 0;
1265d35f963Sbostic   while (i < k)
1275d35f963Sbostic     {
1285d35f963Sbostic       p[i] = bytes[i];
1295d35f963Sbostic       i++;
1305d35f963Sbostic     }
1315d35f963Sbostic 
1325d35f963Sbostic   while (i < len)
1335d35f963Sbostic     p[i++] = BLANK;
1345d35f963Sbostic 
1355d35f963Sbostic   return (p);
1365d35f963Sbostic }
1375d35f963Sbostic 
1385d35f963Sbostic 
1395d35f963Sbostic 
1405d35f963Sbostic LOCAL expptr
cshort(cp)1415d35f963Sbostic cshort(cp)
1425d35f963Sbostic Constp cp;
1435d35f963Sbostic {
1445d35f963Sbostic   static char *toobig = "data value too large";
1455d35f963Sbostic   static char *reserved = "reserved operand assigned to an integer";
1465d35f963Sbostic   static char *compat1 = "logical datum assigned to an integer variable";
1475d35f963Sbostic   static char *compat2 = "character datum assigned to an integer variable";
1485d35f963Sbostic 
1495d35f963Sbostic   register expptr p;
1505d35f963Sbostic   register short *shortp;
1515d35f963Sbostic   register ftnint value;
1525d35f963Sbostic   register long *rp;
1535d35f963Sbostic   register double *minp;
1545d35f963Sbostic   register double *maxp;
1555d35f963Sbostic   realvalue x;
1565d35f963Sbostic 
1575d35f963Sbostic   switch (cp->vtype)
1585d35f963Sbostic     {
1595d35f963Sbostic     case TYBITSTR:
1605d35f963Sbostic       shortp = (short *) grabbits(2, cp);
1615d35f963Sbostic       p = (expptr) mkconst(TYSHORT);
16286947eabSbostic       p->constblock.constant.ci = *shortp;
1635d35f963Sbostic       free((char *) shortp);
1645d35f963Sbostic       break;
1655d35f963Sbostic 
1665d35f963Sbostic     case TYSHORT:
1675d35f963Sbostic       p = (expptr) cpexpr(cp);
1685d35f963Sbostic       break;
1695d35f963Sbostic 
1705d35f963Sbostic     case TYLONG:
17186947eabSbostic       value = cp->constant.ci;
1725d35f963Sbostic       if (value >= MINWORD && value <= MAXWORD)
1735d35f963Sbostic 	{
1745d35f963Sbostic 	  p = (expptr) mkconst(TYSHORT);
17586947eabSbostic 	  p->constblock.constant.ci = value;
1765d35f963Sbostic 	}
1775d35f963Sbostic       else
1785d35f963Sbostic 	{
1795d35f963Sbostic 	  if (badvalue <= 1)
1805d35f963Sbostic 	    {
1815d35f963Sbostic 	      badvalue = 2;
1825d35f963Sbostic 	      err(toobig);
1835d35f963Sbostic 	    }
1845d35f963Sbostic 	  p = errnode();
1855d35f963Sbostic 	}
1865d35f963Sbostic       break;
1875d35f963Sbostic 
1885d35f963Sbostic     case TYREAL:
1895d35f963Sbostic     case TYDREAL:
1905d35f963Sbostic     case TYCOMPLEX:
1915d35f963Sbostic     case TYDCOMPLEX:
1925d35f963Sbostic       minp = (double *) dminword;
1935d35f963Sbostic       maxp = (double *) dmaxword;
19486947eabSbostic       rp = (long *) &(cp->constant.cd[0]);
1955d35f963Sbostic       x.q.word1 = rp[0];
1965d35f963Sbostic       x.q.word2 = rp[1];
1975d35f963Sbostic       if (x.f.sign == 1 && x.f.exp == 0)
1985d35f963Sbostic 	{
1995d35f963Sbostic 	  if (badvalue <= 1)
2005d35f963Sbostic 	    {
2015d35f963Sbostic 	      badvalue = 2;
2025d35f963Sbostic 	      err(reserved);
2035d35f963Sbostic 	    }
2045d35f963Sbostic 	  p = errnode();
2055d35f963Sbostic 	}
2065d35f963Sbostic       else if (x.d >= *minp && x.d <= *maxp)
2075d35f963Sbostic 	{
2085d35f963Sbostic 	  p = (expptr) mkconst(TYSHORT);
20986947eabSbostic 	  p->constblock.constant.ci = x.d;
2105d35f963Sbostic 	}
2115d35f963Sbostic       else
2125d35f963Sbostic 	{
2135d35f963Sbostic 	  if (badvalue <= 1)
2145d35f963Sbostic 	    {
2155d35f963Sbostic 	      badvalue = 2;
2165d35f963Sbostic 	      err(toobig);
2175d35f963Sbostic 	    }
2185d35f963Sbostic 	  p = errnode();
2195d35f963Sbostic 	}
2205d35f963Sbostic       break;
2215d35f963Sbostic 
2225d35f963Sbostic     case TYLOGICAL:
2235d35f963Sbostic       if (badvalue <= 1)
2245d35f963Sbostic 	{
2255d35f963Sbostic 	  badvalue = 2;
2265d35f963Sbostic 	  err(compat1);
2275d35f963Sbostic 	}
2285d35f963Sbostic       p = errnode();
2295d35f963Sbostic       break;
2305d35f963Sbostic 
2315d35f963Sbostic     case TYCHAR:
2325d35f963Sbostic       if ( !ftn66flag && badvalue == 0 )
2335d35f963Sbostic 	{
2345d35f963Sbostic 	  badvalue = 1;
2355d35f963Sbostic 	  warn(compat2);
2365d35f963Sbostic 	}
2375d35f963Sbostic 
2385d35f963Sbostic     case TYHOLLERITH:
2395d35f963Sbostic       shortp = (short *) grabbytes(2, cp);
2405d35f963Sbostic       p = (expptr) mkconst(TYSHORT);
24186947eabSbostic       p->constblock.constant.ci = *shortp;
2425d35f963Sbostic       free((char *) shortp);
2435d35f963Sbostic       break;
2445d35f963Sbostic 
2455d35f963Sbostic     case TYERROR:
2465d35f963Sbostic       p = errnode();
2475d35f963Sbostic       break;
2485d35f963Sbostic     }
2495d35f963Sbostic 
2505d35f963Sbostic   return (p);
2515d35f963Sbostic }
2525d35f963Sbostic 
2535d35f963Sbostic 
2545d35f963Sbostic 
2555d35f963Sbostic LOCAL expptr
clong(cp)2565d35f963Sbostic clong(cp)
2575d35f963Sbostic Constp cp;
2585d35f963Sbostic {
2595d35f963Sbostic   static char *toobig = "data value too large";
2605d35f963Sbostic   static char *reserved = "reserved operand assigned to an integer";
2615d35f963Sbostic   static char *compat1 = "logical datum assigned to an integer variable";
2625d35f963Sbostic   static char *compat2 = "character datum assigned to an integer variable";
2635d35f963Sbostic 
2645d35f963Sbostic   register expptr p;
2655d35f963Sbostic   register ftnint *longp;
2665d35f963Sbostic   register long *rp;
2675d35f963Sbostic   register double *minp;
2685d35f963Sbostic   register double *maxp;
2695d35f963Sbostic   realvalue x;
2705d35f963Sbostic 
2715d35f963Sbostic   switch (cp->vtype)
2725d35f963Sbostic     {
2735d35f963Sbostic     case TYBITSTR:
2745d35f963Sbostic       longp = (ftnint *) grabbits(4, cp);
2755d35f963Sbostic       p = (expptr) mkconst(TYLONG);
27686947eabSbostic       p->constblock.constant.ci = *longp;
2775d35f963Sbostic       free((char *) longp);
2785d35f963Sbostic       break;
2795d35f963Sbostic 
2805d35f963Sbostic     case TYSHORT:
2815d35f963Sbostic       p = (expptr) mkconst(TYLONG);
28286947eabSbostic       p->constblock.constant.ci = cp->constant.ci;
2835d35f963Sbostic       break;
2845d35f963Sbostic 
2855d35f963Sbostic     case TYLONG:
2865d35f963Sbostic       p = (expptr) cpexpr(cp);
2875d35f963Sbostic       break;
2885d35f963Sbostic 
2895d35f963Sbostic     case TYREAL:
2905d35f963Sbostic     case TYDREAL:
2915d35f963Sbostic     case TYCOMPLEX:
2925d35f963Sbostic     case TYDCOMPLEX:
2935d35f963Sbostic       minp = (double *) dminint;
2945d35f963Sbostic       maxp = (double *) dmaxint;
29586947eabSbostic       rp = (long *) &(cp->constant.cd[0]);
2965d35f963Sbostic       x.q.word1 = rp[0];
2975d35f963Sbostic       x.q.word2 = rp[1];
2985d35f963Sbostic       if (x.f.sign == 1 && x.f.exp == 0)
2995d35f963Sbostic 	{
3005d35f963Sbostic 	  if (badvalue <= 1)
3015d35f963Sbostic 	    {
3025d35f963Sbostic 	      badvalue = 2;
3035d35f963Sbostic 	      err(reserved);
3045d35f963Sbostic 	    }
3055d35f963Sbostic 	  p = errnode();
3065d35f963Sbostic 	}
3075d35f963Sbostic       else if (x.d >= *minp && x.d <= *maxp)
3085d35f963Sbostic 	{
3095d35f963Sbostic 	  p = (expptr) mkconst(TYLONG);
31086947eabSbostic 	  p->constblock.constant.ci = x.d;
3115d35f963Sbostic 	}
3125d35f963Sbostic       else
3135d35f963Sbostic 	{
3145d35f963Sbostic 	  if (badvalue <= 1)
3155d35f963Sbostic 	    {
3165d35f963Sbostic 	      badvalue = 2;
3175d35f963Sbostic 	      err(toobig);
3185d35f963Sbostic 	    }
3195d35f963Sbostic 	  p = errnode();
3205d35f963Sbostic 	}
3215d35f963Sbostic       break;
3225d35f963Sbostic 
3235d35f963Sbostic     case TYLOGICAL:
3245d35f963Sbostic       if (badvalue <= 1)
3255d35f963Sbostic 	{
3265d35f963Sbostic 	  badvalue = 2;
3275d35f963Sbostic 	  err(compat1);
3285d35f963Sbostic 	}
3295d35f963Sbostic       p = errnode();
3305d35f963Sbostic       break;
3315d35f963Sbostic 
3325d35f963Sbostic     case TYCHAR:
3335d35f963Sbostic       if ( !ftn66flag && badvalue == 0 )
3345d35f963Sbostic 	{
3355d35f963Sbostic 	  badvalue = 1;
3365d35f963Sbostic 	  warn(compat2);
3375d35f963Sbostic 	}
3385d35f963Sbostic 
3395d35f963Sbostic     case TYHOLLERITH:
3405d35f963Sbostic       longp = (ftnint *) grabbytes(4, cp);
3415d35f963Sbostic       p = (expptr) mkconst(TYLONG);
34286947eabSbostic       p->constblock.constant.ci = *longp;
3435d35f963Sbostic       free((char *) longp);
3445d35f963Sbostic       break;
3455d35f963Sbostic 
3465d35f963Sbostic     case TYERROR:
3475d35f963Sbostic       p = errnode();
3485d35f963Sbostic       break;
3495d35f963Sbostic     }
3505d35f963Sbostic 
3515d35f963Sbostic   return (p);
3525d35f963Sbostic }
3535d35f963Sbostic 
3545d35f963Sbostic 
3555d35f963Sbostic 
3565d35f963Sbostic LOCAL expptr
creal(cp)3575d35f963Sbostic creal(cp)
3585d35f963Sbostic Constp cp;
3595d35f963Sbostic {
3605d35f963Sbostic   static char *toobig = "data value too large";
3615d35f963Sbostic   static char *compat1 = "logical datum assigned to a real variable";
3625d35f963Sbostic   static char *compat2 = "character datum assigned to a real variable";
3635d35f963Sbostic 
3645d35f963Sbostic   register expptr p;
3655d35f963Sbostic   register long *longp;
3665d35f963Sbostic   register long *rp;
3675d35f963Sbostic   register double *minp;
3685d35f963Sbostic   register double *maxp;
3695d35f963Sbostic   realvalue x;
3705d35f963Sbostic   float y;
3715d35f963Sbostic 
3725d35f963Sbostic   switch (cp->vtype)
3735d35f963Sbostic     {
3745d35f963Sbostic     case TYBITSTR:
3755d35f963Sbostic       longp = (long *) grabbits(4, cp);
3765d35f963Sbostic       p = (expptr) mkconst(TYREAL);
37786947eabSbostic       rp = (long *) &(p->constblock.constant.cd[0]);
3785d35f963Sbostic       rp[0] = *longp;
3795d35f963Sbostic       free((char *) longp);
3805d35f963Sbostic       break;
3815d35f963Sbostic 
3825d35f963Sbostic     case TYSHORT:
3835d35f963Sbostic     case TYLONG:
3845d35f963Sbostic       p = (expptr) mkconst(TYREAL);
38586947eabSbostic       p->constblock.constant.cd[0] = cp->constant.ci;
3865d35f963Sbostic       break;
3875d35f963Sbostic 
3885d35f963Sbostic     case TYREAL:
3895d35f963Sbostic     case TYDREAL:
3905d35f963Sbostic     case TYCOMPLEX:
3915d35f963Sbostic     case TYDCOMPLEX:
3925d35f963Sbostic       minp = (double *) dminreal;
3935d35f963Sbostic       maxp = (double *) dmaxreal;
39486947eabSbostic       rp = (long *) &(cp->constant.cd[0]);
3955d35f963Sbostic       x.q.word1 = rp[0];
3965d35f963Sbostic       x.q.word2 = rp[1];
3975d35f963Sbostic       if (x.f.sign == 1 && x.f.exp == 0)
3985d35f963Sbostic 	{
3995d35f963Sbostic 	  p = (expptr) mkconst(TYREAL);
40086947eabSbostic 	  rp = (long *) &(p->constblock.constant.cd[0]);
4015d35f963Sbostic 	  rp[0] = x.q.word1;
4025d35f963Sbostic 	}
4035d35f963Sbostic       else if (x.d >= *minp && x.d <= *maxp)
4045d35f963Sbostic 	{
4055d35f963Sbostic 	  p = (expptr) mkconst(TYREAL);
4065d35f963Sbostic 	  y = x.d;
40786947eabSbostic 	  p->constblock.constant.cd[0] = y;
4085d35f963Sbostic 	}
4095d35f963Sbostic       else
4105d35f963Sbostic 	{
4115d35f963Sbostic 	  if (badvalue <= 1)
4125d35f963Sbostic 	    {
4135d35f963Sbostic 	      badvalue = 2;
4145d35f963Sbostic 	      err(toobig);
4155d35f963Sbostic 	    }
4165d35f963Sbostic 	  p = errnode();
4175d35f963Sbostic 	}
4185d35f963Sbostic       break;
4195d35f963Sbostic 
4205d35f963Sbostic     case TYLOGICAL:
4215d35f963Sbostic       if (badvalue <= 1)
4225d35f963Sbostic 	{
4235d35f963Sbostic 	  badvalue = 2;
4245d35f963Sbostic 	  err(compat1);
4255d35f963Sbostic 	}
4265d35f963Sbostic       p = errnode();
4275d35f963Sbostic       break;
4285d35f963Sbostic 
4295d35f963Sbostic     case TYCHAR:
4305d35f963Sbostic       if ( !ftn66flag && badvalue == 0)
4315d35f963Sbostic 	{
4325d35f963Sbostic 	  badvalue = 1;
4335d35f963Sbostic 	  warn(compat2);
4345d35f963Sbostic 	}
4355d35f963Sbostic 
4365d35f963Sbostic     case TYHOLLERITH:
4375d35f963Sbostic       longp = (long *) grabbytes(4, cp);
4385d35f963Sbostic       p = (expptr) mkconst(TYREAL);
43986947eabSbostic       rp = (long *) &(p->constblock.constant.cd[0]);
4405d35f963Sbostic       rp[0] = *longp;
4415d35f963Sbostic       free((char *) longp);
4425d35f963Sbostic       break;
4435d35f963Sbostic 
4445d35f963Sbostic     case TYERROR:
4455d35f963Sbostic       p = errnode();
4465d35f963Sbostic       break;
4475d35f963Sbostic     }
4485d35f963Sbostic 
4495d35f963Sbostic   return (p);
4505d35f963Sbostic }
4515d35f963Sbostic 
4525d35f963Sbostic 
4535d35f963Sbostic 
4545d35f963Sbostic LOCAL expptr
cdreal(cp)4555d35f963Sbostic cdreal(cp)
4565d35f963Sbostic Constp cp;
4575d35f963Sbostic {
4585d35f963Sbostic   static char *compat1 =
4595d35f963Sbostic 	"logical datum assigned to a double precision variable";
4605d35f963Sbostic   static char *compat2 =
4615d35f963Sbostic 	"character datum assigned to a double precision variable";
4625d35f963Sbostic 
4635d35f963Sbostic   register expptr p;
4645d35f963Sbostic   register long *longp;
4655d35f963Sbostic   register long *rp;
4665d35f963Sbostic 
4675d35f963Sbostic   switch (cp->vtype)
4685d35f963Sbostic     {
4695d35f963Sbostic     case TYBITSTR:
4705d35f963Sbostic       longp = (long *) grabbits(8, cp);
4715d35f963Sbostic       p = (expptr) mkconst(TYDREAL);
47286947eabSbostic       rp = (long *) &(p->constblock.constant.cd[0]);
4735d35f963Sbostic       rp[0] = longp[0];
4745d35f963Sbostic       rp[1] = longp[1];
4755d35f963Sbostic       free((char *) longp);
4765d35f963Sbostic       break;
4775d35f963Sbostic 
4785d35f963Sbostic     case TYSHORT:
4795d35f963Sbostic     case TYLONG:
4805d35f963Sbostic       p = (expptr) mkconst(TYDREAL);
48186947eabSbostic       p->constblock.constant.cd[0] = cp->constant.ci;
4825d35f963Sbostic       break;
4835d35f963Sbostic 
4845d35f963Sbostic     case TYREAL:
4855d35f963Sbostic     case TYDREAL:
4865d35f963Sbostic     case TYCOMPLEX:
4875d35f963Sbostic     case TYDCOMPLEX:
4885d35f963Sbostic       p = (expptr) mkconst(TYDREAL);
48986947eabSbostic       longp = (long *) &(cp->constant.cd[0]);
49086947eabSbostic       rp = (long *) &(p->constblock.constant.cd[0]);
4915d35f963Sbostic       rp[0] = longp[0];
4925d35f963Sbostic       rp[1] = longp[1];
4935d35f963Sbostic       break;
4945d35f963Sbostic 
4955d35f963Sbostic     case TYLOGICAL:
4965d35f963Sbostic       if (badvalue <= 1)
4975d35f963Sbostic 	{
4985d35f963Sbostic 	  badvalue = 2;
4995d35f963Sbostic 	  err(compat1);
5005d35f963Sbostic 	}
5015d35f963Sbostic       p = errnode();
5025d35f963Sbostic       break;
5035d35f963Sbostic 
5045d35f963Sbostic     case TYCHAR:
5055d35f963Sbostic       if ( !ftn66flag && badvalue == 0 )
5065d35f963Sbostic 	{
5075d35f963Sbostic 	  badvalue = 1;
5085d35f963Sbostic 	  warn(compat2);
5095d35f963Sbostic 	}
5105d35f963Sbostic 
5115d35f963Sbostic     case TYHOLLERITH:
5125d35f963Sbostic       longp = (long *) grabbytes(8, cp);
5135d35f963Sbostic       p = (expptr) mkconst(TYDREAL);
51486947eabSbostic       rp = (long *) &(p->constblock.constant.cd[0]);
5155d35f963Sbostic       rp[0] = longp[0];
5165d35f963Sbostic       rp[1] = longp[1];
5175d35f963Sbostic       free((char *) longp);
5185d35f963Sbostic       break;
5195d35f963Sbostic 
5205d35f963Sbostic     case TYERROR:
5215d35f963Sbostic       p = errnode();
5225d35f963Sbostic       break;
5235d35f963Sbostic     }
5245d35f963Sbostic 
5255d35f963Sbostic   return (p);
5265d35f963Sbostic }
5275d35f963Sbostic 
5285d35f963Sbostic 
5295d35f963Sbostic 
5305d35f963Sbostic LOCAL expptr
ccomplex(cp)5315d35f963Sbostic ccomplex(cp)
5325d35f963Sbostic Constp cp;
5335d35f963Sbostic {
5345d35f963Sbostic   static char *toobig = "data value too large";
5355d35f963Sbostic   static char *compat1 = "logical datum assigned to a complex variable";
5365d35f963Sbostic   static char *compat2 = "character datum assigned to a complex variable";
5375d35f963Sbostic 
5385d35f963Sbostic   register expptr p;
5395d35f963Sbostic   register long *longp;
5405d35f963Sbostic   register long *rp;
5415d35f963Sbostic   register double *minp;
5425d35f963Sbostic   register double *maxp;
5435d35f963Sbostic   realvalue re, im;
5445d35f963Sbostic   int overflow;
5455d35f963Sbostic   float x;
5465d35f963Sbostic 
5475d35f963Sbostic   switch (cp->vtype)
5485d35f963Sbostic     {
5495d35f963Sbostic     case TYBITSTR:
5505d35f963Sbostic       longp = (long *) grabbits(8, cp);
5515d35f963Sbostic       p = (expptr) mkconst(TYCOMPLEX);
55286947eabSbostic       rp = (long *) &(p->constblock.constant.cd[0]);
5535d35f963Sbostic       rp[0] = longp[0];
5545d35f963Sbostic       rp[2] = longp[1];
5555d35f963Sbostic       free((char *) longp);
5565d35f963Sbostic       break;
5575d35f963Sbostic 
5585d35f963Sbostic     case TYSHORT:
5595d35f963Sbostic     case TYLONG:
5605d35f963Sbostic       p = (expptr) mkconst(TYCOMPLEX);
56186947eabSbostic       p->constblock.constant.cd[0] = cp->constant.ci;
5625d35f963Sbostic       break;
5635d35f963Sbostic 
5645d35f963Sbostic     case TYREAL:
5655d35f963Sbostic     case TYDREAL:
5665d35f963Sbostic     case TYCOMPLEX:
5675d35f963Sbostic     case TYDCOMPLEX:
5685d35f963Sbostic       overflow = 0;
5695d35f963Sbostic       minp = (double *) dminreal;
5705d35f963Sbostic       maxp = (double *) dmaxreal;
57186947eabSbostic       rp = (long *) &(cp->constant.cd[0]);
5725d35f963Sbostic       re.q.word1 = rp[0];
5735d35f963Sbostic       re.q.word2 = rp[1];
5745d35f963Sbostic       im.q.word1 = rp[2];
5755d35f963Sbostic       im.q.word2 = rp[3];
5765d35f963Sbostic       if (((re.f.sign == 0 || re.f.exp != 0) &&
5775d35f963Sbostic 	   (re.d < *minp || re.d > *maxp))       ||
5785d35f963Sbostic 	  ((im.f.sign == 0 || re.f.exp != 0) &&
5795d35f963Sbostic 	   (im.d < *minp || re.d > *maxp)))
5805d35f963Sbostic 	{
5815d35f963Sbostic 	  if (badvalue <= 1)
5825d35f963Sbostic 	    {
5835d35f963Sbostic 	      badvalue = 2;
5845d35f963Sbostic 	      err(toobig);
5855d35f963Sbostic 	    }
5865d35f963Sbostic 	  p = errnode();
5875d35f963Sbostic 	}
5885d35f963Sbostic       else
5895d35f963Sbostic 	{
5905d35f963Sbostic 	  p = (expptr) mkconst(TYCOMPLEX);
5915d35f963Sbostic 	  if (re.f.sign == 1 && re.f.exp == 0)
5925d35f963Sbostic 	    re.q.word2 = 0;
5935d35f963Sbostic 	  else
5945d35f963Sbostic 	    {
5955d35f963Sbostic 	      x = re.d;
5965d35f963Sbostic 	      re.d = x;
5975d35f963Sbostic 	    }
5985d35f963Sbostic 	  if (im.f.sign == 1 && im.f.exp == 0)
5995d35f963Sbostic 	    im.q.word2 = 0;
6005d35f963Sbostic 	  else
6015d35f963Sbostic 	    {
6025d35f963Sbostic 	      x = im.d;
6035d35f963Sbostic 	      im.d = x;
6045d35f963Sbostic 	    }
60586947eabSbostic 	  rp = (long *) &(p->constblock.constant.cd[0]);
6065d35f963Sbostic 	  rp[0] = re.q.word1;
6075d35f963Sbostic 	  rp[1] = re.q.word2;
6085d35f963Sbostic 	  rp[2] = im.q.word1;
6095d35f963Sbostic 	  rp[3] = im.q.word2;
6105d35f963Sbostic 	}
6115d35f963Sbostic       break;
6125d35f963Sbostic 
6135d35f963Sbostic     case TYLOGICAL:
6145d35f963Sbostic       if (badvalue <= 1)
6155d35f963Sbostic 	{
6165d35f963Sbostic 	  badvalue = 2;
6175d35f963Sbostic 	  err(compat1);
6185d35f963Sbostic 	}
6195d35f963Sbostic       break;
6205d35f963Sbostic 
6215d35f963Sbostic     case TYCHAR:
6225d35f963Sbostic       if ( !ftn66flag && badvalue == 0)
6235d35f963Sbostic 	{
6245d35f963Sbostic 	  badvalue = 1;
6255d35f963Sbostic 	  warn(compat2);
6265d35f963Sbostic 	}
6275d35f963Sbostic 
6285d35f963Sbostic     case TYHOLLERITH:
6295d35f963Sbostic       longp = (long *) grabbytes(8, cp);
6305d35f963Sbostic       p = (expptr) mkconst(TYCOMPLEX);
63186947eabSbostic       rp = (long *) &(p->constblock.constant.cd[0]);
6325d35f963Sbostic       rp[0] = longp[0];
6335d35f963Sbostic       rp[2] = longp[1];
6345d35f963Sbostic       free((char *) longp);
6355d35f963Sbostic       break;
6365d35f963Sbostic 
6375d35f963Sbostic     case TYERROR:
6385d35f963Sbostic       p = errnode();
6395d35f963Sbostic       break;
6405d35f963Sbostic     }
6415d35f963Sbostic 
6425d35f963Sbostic   return (p);
6435d35f963Sbostic }
6445d35f963Sbostic 
6455d35f963Sbostic 
6465d35f963Sbostic 
6475d35f963Sbostic LOCAL expptr
cdcomplex(cp)6485d35f963Sbostic cdcomplex(cp)
6495d35f963Sbostic Constp cp;
6505d35f963Sbostic {
6515d35f963Sbostic   static char *compat1 = "logical datum assigned to a complex variable";
6525d35f963Sbostic   static char *compat2 = "character datum assigned to a complex variable";
6535d35f963Sbostic 
6545d35f963Sbostic   register expptr p;
6555d35f963Sbostic   register long *longp;
6565d35f963Sbostic   register long *rp;
6575d35f963Sbostic 
6585d35f963Sbostic   switch (cp->vtype)
6595d35f963Sbostic     {
6605d35f963Sbostic     case TYBITSTR:
6615d35f963Sbostic       longp = (long *) grabbits(16, cp);
6625d35f963Sbostic       p = (expptr) mkconst(TYDCOMPLEX);
66386947eabSbostic       rp = (long *) &(p->constblock.constant.cd[0]);
6645d35f963Sbostic       rp[0] = longp[0];
6655d35f963Sbostic       rp[1] = longp[1];
6665d35f963Sbostic       rp[2] = longp[2];
6675d35f963Sbostic       rp[3] = longp[3];
6685d35f963Sbostic       free((char *) longp);
6695d35f963Sbostic       break;
6705d35f963Sbostic 
6715d35f963Sbostic     case TYSHORT:
6725d35f963Sbostic     case TYLONG:
6735d35f963Sbostic       p = (expptr) mkconst(TYDCOMPLEX);
67486947eabSbostic       p->constblock.constant.cd[0] = cp->constant.ci;
6755d35f963Sbostic       break;
6765d35f963Sbostic 
6775d35f963Sbostic     case TYREAL:
6785d35f963Sbostic     case TYDREAL:
6795d35f963Sbostic     case TYCOMPLEX:
6805d35f963Sbostic     case TYDCOMPLEX:
6815d35f963Sbostic       p = (expptr) mkconst(TYDCOMPLEX);
68286947eabSbostic       longp = (long *) &(cp->constant.cd[0]);
68386947eabSbostic       rp = (long *) &(p->constblock.constant.cd[0]);
6845d35f963Sbostic       rp[0] = longp[0];
6855d35f963Sbostic       rp[1] = longp[1];
6865d35f963Sbostic       rp[2] = longp[2];
6875d35f963Sbostic       rp[3] = longp[3];
6885d35f963Sbostic       break;
6895d35f963Sbostic 
6905d35f963Sbostic     case TYLOGICAL:
6915d35f963Sbostic       if (badvalue <= 1)
6925d35f963Sbostic 	{
6935d35f963Sbostic 	  badvalue = 2;
6945d35f963Sbostic 	  err(compat1);
6955d35f963Sbostic 	}
6965d35f963Sbostic       p = errnode();
6975d35f963Sbostic       break;
6985d35f963Sbostic 
6995d35f963Sbostic     case TYCHAR:
7005d35f963Sbostic       if ( !ftn66flag && badvalue == 0 )
7015d35f963Sbostic 	{
7025d35f963Sbostic 	  badvalue = 1;
7035d35f963Sbostic 	  warn(compat2);
7045d35f963Sbostic 	}
7055d35f963Sbostic 
7065d35f963Sbostic     case TYHOLLERITH:
7075d35f963Sbostic       longp = (long *) grabbytes(16, cp);
7085d35f963Sbostic       p = (expptr) mkconst(TYDCOMPLEX);
70986947eabSbostic       rp = (long *) &(p->constblock.constant.cd[0]);
7105d35f963Sbostic       rp[0] = longp[0];
7115d35f963Sbostic       rp[1] = longp[1];
7125d35f963Sbostic       rp[2] = longp[2];
7135d35f963Sbostic       rp[3] = longp[3];
7145d35f963Sbostic       free((char *) longp);
7155d35f963Sbostic       break;
7165d35f963Sbostic 
7175d35f963Sbostic     case TYERROR:
7185d35f963Sbostic       p = errnode();
7195d35f963Sbostic       break;
7205d35f963Sbostic     }
7215d35f963Sbostic 
7225d35f963Sbostic   return (p);
7235d35f963Sbostic }
7245d35f963Sbostic 
7255d35f963Sbostic 
7265d35f963Sbostic 
7275d35f963Sbostic LOCAL expptr
clogical(cp)7285d35f963Sbostic clogical(cp)
7295d35f963Sbostic Constp cp;
7305d35f963Sbostic {
7315d35f963Sbostic   static char *compat1 = "numeric datum assigned to a logical variable";
7325d35f963Sbostic   static char *compat2 = "character datum assigned to a logical variable";
7335d35f963Sbostic 
7345d35f963Sbostic   register expptr p;
7355d35f963Sbostic   register long *longp;
7365d35f963Sbostic   register short *shortp;
7375d35f963Sbostic   register int size;
7385d35f963Sbostic 
7395d35f963Sbostic   size = typesize[tylogical];
7405d35f963Sbostic 
7415d35f963Sbostic   switch (cp->vtype)
7425d35f963Sbostic     {
7435d35f963Sbostic     case TYBITSTR:
7445d35f963Sbostic       p = (expptr) mkconst(tylogical);
7455d35f963Sbostic       if (tylogical == TYSHORT)
7465d35f963Sbostic 	{
7475d35f963Sbostic 	  shortp = (short *) grabbits(size, cp);
74886947eabSbostic 	  p->constblock.constant.ci = (int) *shortp;
7495d35f963Sbostic 	  free((char *) shortp);
7505d35f963Sbostic 	}
7515d35f963Sbostic       else
7525d35f963Sbostic 	{
7535d35f963Sbostic 	  longp = (long *) grabbits(size, cp);
75486947eabSbostic 	  p->constblock.constant.ci = *longp;
7555d35f963Sbostic 	  free((char *) longp);
7565d35f963Sbostic 	}
7575d35f963Sbostic       break;
7585d35f963Sbostic 
7595d35f963Sbostic     case TYSHORT:
7605d35f963Sbostic     case TYLONG:
7615d35f963Sbostic     case TYREAL:
7625d35f963Sbostic     case TYDREAL:
7635d35f963Sbostic     case TYCOMPLEX:
7645d35f963Sbostic     case TYDCOMPLEX:
7655d35f963Sbostic       if (badvalue <= 1)
7665d35f963Sbostic 	{
7675d35f963Sbostic 	  badvalue = 2;
7685d35f963Sbostic 	  err(compat1);
7695d35f963Sbostic 	}
7705d35f963Sbostic       p = errnode();
7715d35f963Sbostic       break;
7725d35f963Sbostic 
7735d35f963Sbostic     case TYLOGICAL:
7745d35f963Sbostic       p = (expptr) cpexpr(cp);
7755d35f963Sbostic       p->constblock.vtype = tylogical;
7765d35f963Sbostic       break;
7775d35f963Sbostic 
7785d35f963Sbostic     case TYCHAR:
7795d35f963Sbostic       if ( !ftn66flag && badvalue == 0 )
7805d35f963Sbostic 	{
7815d35f963Sbostic 	  badvalue = 1;
7825d35f963Sbostic 	  warn(compat2);
7835d35f963Sbostic 	}
7845d35f963Sbostic 
7855d35f963Sbostic     case TYHOLLERITH:
7865d35f963Sbostic       p = (expptr) mkconst(tylogical);
7875d35f963Sbostic       if (tylogical == TYSHORT)
7885d35f963Sbostic 	{
7895d35f963Sbostic 	  shortp = (short *) grabbytes(size, cp);
79086947eabSbostic 	  p->constblock.constant.ci = (int) *shortp;
7915d35f963Sbostic 	  free((char *) shortp);
7925d35f963Sbostic 	}
7935d35f963Sbostic       else
7945d35f963Sbostic 	{
7955d35f963Sbostic 	  longp = (long *) grabbytes(4, cp);
79686947eabSbostic 	  p->constblock.constant.ci = *longp;
7975d35f963Sbostic 	  free((char *) longp);
7985d35f963Sbostic 	}
7995d35f963Sbostic       break;
8005d35f963Sbostic 
8015d35f963Sbostic     case TYERROR:
8025d35f963Sbostic       p = errnode();
8035d35f963Sbostic       break;
8045d35f963Sbostic     }
8055d35f963Sbostic 
8065d35f963Sbostic   return (p);
8075d35f963Sbostic }
8085d35f963Sbostic 
8095d35f963Sbostic 
8105d35f963Sbostic 
8115d35f963Sbostic LOCAL expptr
cchar(len,cp)8125d35f963Sbostic cchar(len, cp)
8135d35f963Sbostic int len;
8145d35f963Sbostic Constp cp;
8155d35f963Sbostic {
8165d35f963Sbostic   static char *compat1 = "numeric datum assigned to a character variable";
8175d35f963Sbostic   static char *compat2 = "logical datum assigned to a character variable";
8185d35f963Sbostic 
8195d35f963Sbostic   register expptr p;
8205d35f963Sbostic   register char *value;
8215d35f963Sbostic 
8225d35f963Sbostic   switch (cp->vtype)
8235d35f963Sbostic     {
8245d35f963Sbostic     case TYBITSTR:
8255d35f963Sbostic       value = grabbits(len, cp);
8265d35f963Sbostic       p = (expptr) mkstrcon(len, value);
8275d35f963Sbostic       free(value);
8285d35f963Sbostic       break;
8295d35f963Sbostic 
8305d35f963Sbostic     case TYSHORT:
8315d35f963Sbostic     case TYLONG:
8325d35f963Sbostic     case TYREAL:
8335d35f963Sbostic     case TYDREAL:
8345d35f963Sbostic     case TYCOMPLEX:
8355d35f963Sbostic     case TYDCOMPLEX:
8365d35f963Sbostic       if (badvalue <= 1)
8375d35f963Sbostic 	{
8385d35f963Sbostic 	  badvalue = 2;
8395d35f963Sbostic 	  err(compat1);
8405d35f963Sbostic 	}
8415d35f963Sbostic       p = errnode();
8425d35f963Sbostic       break;
8435d35f963Sbostic 
8445d35f963Sbostic     case TYLOGICAL:
8455d35f963Sbostic       if (badvalue <= 1)
8465d35f963Sbostic 	{
8475d35f963Sbostic 	  badvalue = 2;
8485d35f963Sbostic 	  err(compat2);
8495d35f963Sbostic 	}
8505d35f963Sbostic       p = errnode();
8515d35f963Sbostic       break;
8525d35f963Sbostic 
8535d35f963Sbostic     case TYCHAR:
8545d35f963Sbostic     case TYHOLLERITH:
8555d35f963Sbostic       value = grabbytes(len, cp);
8565d35f963Sbostic       p = (expptr) mkstrcon(len, value);
8575d35f963Sbostic       free(value);
8585d35f963Sbostic       break;
8595d35f963Sbostic 
8605d35f963Sbostic     case TYERROR:
8615d35f963Sbostic       p = errnode();
8625d35f963Sbostic       break;
8635d35f963Sbostic     }
8645d35f963Sbostic 
8655d35f963Sbostic   return (p);
8665d35f963Sbostic }
8675d35f963Sbostic 
8685d35f963Sbostic 
8695d35f963Sbostic 
8705d35f963Sbostic expptr
convconst(type,len,constant)87186947eabSbostic convconst(type, len, constant)
8725d35f963Sbostic int type;
8735d35f963Sbostic int len;
87486947eabSbostic Constp constant;
8755d35f963Sbostic {
8765d35f963Sbostic   register expptr p;
8775d35f963Sbostic 
8785d35f963Sbostic   switch (type)
8795d35f963Sbostic     {
8805d35f963Sbostic     case TYSHORT:
88186947eabSbostic       p = cshort(constant);
8825d35f963Sbostic       break;
8835d35f963Sbostic 
8845d35f963Sbostic     case TYLONG:
88586947eabSbostic       p = clong(constant);
8865d35f963Sbostic       break;
8875d35f963Sbostic 
8885d35f963Sbostic     case TYREAL:
88986947eabSbostic       p = creal(constant);
8905d35f963Sbostic       break;
8915d35f963Sbostic 
8925d35f963Sbostic     case TYDREAL:
89386947eabSbostic       p = cdreal(constant);
8945d35f963Sbostic       break;
8955d35f963Sbostic 
8965d35f963Sbostic     case TYCOMPLEX:
89786947eabSbostic       p = ccomplex(constant);
8985d35f963Sbostic       break;
8995d35f963Sbostic 
9005d35f963Sbostic     case TYDCOMPLEX:
90186947eabSbostic       p = cdcomplex(constant);
9025d35f963Sbostic       break;
9035d35f963Sbostic 
9045d35f963Sbostic     case TYLOGICAL:
90586947eabSbostic       p = clogical(constant);
9065d35f963Sbostic       break;
9075d35f963Sbostic 
9085d35f963Sbostic     case TYCHAR:
90986947eabSbostic       p = cchar(len, constant);
9105d35f963Sbostic       break;
9115d35f963Sbostic 
9125d35f963Sbostic     case TYERROR:
9135d35f963Sbostic     case TYUNKNOWN:
9145d35f963Sbostic       p = errnode();
9155d35f963Sbostic       break;
9165d35f963Sbostic 
9175d35f963Sbostic     default:
9185d35f963Sbostic       badtype("convconst", type);
9195d35f963Sbostic     }
9205d35f963Sbostic 
9215d35f963Sbostic   return (p);
9225d35f963Sbostic }
923