xref: /csrg-svn/usr.bin/f77/pass1.vax/conv.c (revision 33256)
122800Smckusick /*
222800Smckusick  * Copyright (c) 1980 Regents of the University of California.
322800Smckusick  * All rights reserved.  The Berkeley software License Agreement
422800Smckusick  * specifies the terms and conditions for redistribution.
522800Smckusick  */
622800Smckusick 
722800Smckusick #ifndef lint
8*33256Sbostic static char sccsid[] = "@(#)conv.c	5.2 (Berkeley) 01/03/88";
922800Smckusick #endif not lint
1022800Smckusick 
1122800Smckusick /*
1222800Smckusick  * conv.c
1322800Smckusick  *
1422800Smckusick  * Routines for type conversions, f77 compiler pass 1.
1522800Smckusick  *
1622800Smckusick  * University of Utah CS Dept modification history:
1722800Smckusick  *
1822800Smckusick  * $Log:	conv.c,v $
1922800Smckusick  * Revision 2.2  85/06/07  21:09:29  root
2022800Smckusick  * Add copyright
2122800Smckusick  *
2222800Smckusick  * Revision 2.1  84/07/19  12:02:29  donn
2322800Smckusick  * Changed comment headers for UofU.
2422800Smckusick  *
2522800Smckusick  * Revision 1.2  84/04/13  01:07:02  donn
2622800Smckusick  * Fixed value of dminreal to be -1.7e38 + epsilon instead of -2.59e33, per
2722800Smckusick  * Bob Corbett's approval.
2822800Smckusick  *
2922800Smckusick  */
3022800Smckusick 
3122800Smckusick #include "defs.h"
3222800Smckusick #include "conv.h"
3322800Smckusick 
3422800Smckusick int badvalue;
3522800Smckusick 
3622800Smckusick 
3722800Smckusick /*  The following constants are used to check the limits of  */
3822800Smckusick /*  conversions.  Dmaxword is the largest double precision   */
3922800Smckusick /*  number which can be converted to a two-byte integer      */
4022800Smckusick /*  without overflow.  Dminword is the smallest double       */
4122800Smckusick /*  precision value which can be converted to a two-byte     */
4222800Smckusick /*  integer without overflow.  Dmaxint and dminint are the   */
4322800Smckusick /*  analogous values for four-byte integers.                 */
4422800Smckusick 
4522800Smckusick 
4622800Smckusick LOCAL long dmaxword[] = { 0xfeff47ff, 0xffffffff };
4722800Smckusick LOCAL long dminword[] = { 0x00ffc800, 0xffffffff };
4822800Smckusick 
4922800Smckusick LOCAL long dmaxint[]  = { 0xffff4fff, 0xfffffeff };
5022800Smckusick LOCAL long dminint[]  = { 0x0000d000, 0xffff00ff };
5122800Smckusick 
5222800Smckusick LOCAL long dmaxreal[] = { 0xffff7fff, 0xffff7fff };
5322800Smckusick LOCAL long dminreal[] = { 0xffffffff, 0xffff7fff };
5422800Smckusick 
5522800Smckusick 
5622800Smckusick 
5722800Smckusick /*  The routines which follow are used to convert  */
5822800Smckusick /*  constants into constants of other types.       */
5922800Smckusick 
6022800Smckusick LOCAL char *
6122800Smckusick grabbits(len, cp)
6222800Smckusick int len;
6322800Smckusick Constp cp;
6422800Smckusick {
6522800Smckusick 
6622800Smckusick   static char *toobig = "bit value too large";
6722800Smckusick 
6822800Smckusick   register char *p;
6922800Smckusick   register char *bits;
7022800Smckusick   register int i;
7122800Smckusick   register int k;
7222800Smckusick   register int lenb;
7322800Smckusick 
74*33256Sbostic   bits = cp->constant.ccp;
75*33256Sbostic   lenb = cp->vleng->constblock.constant.ci;
7622800Smckusick 
7722800Smckusick   p = (char *) ckalloc(len);
7822800Smckusick 
7922800Smckusick   if (len >= lenb)
8022800Smckusick     k = lenb;
8122800Smckusick   else
8222800Smckusick     {
8322800Smckusick       k = len;
8422800Smckusick       if ( badvalue == 0 )
8522800Smckusick 	{
8622800Smckusick #if (TARGET == PDP11 || TARGET == VAX)
8722800Smckusick 	  i = len;
8822800Smckusick 	  while ( i < lenb && bits[i] == 0 )
8922800Smckusick 	    i++;
9022800Smckusick 	  if (i < lenb)
9122800Smckusick 	    badvalue = 1;
9222800Smckusick #else
9322800Smckusick 	  i = lenb - len - 1;
9422800Smckusick 	  while ( i >= 0 && bits[i] == 0)
9522800Smckusick 	    i--;
9622800Smckusick 	  if (i >= 0)
9722800Smckusick 	    badvalue = 1;
9822800Smckusick #endif
9922800Smckusick 	  if (badvalue)
10022800Smckusick 	    warn(toobig);
10122800Smckusick 	}
10222800Smckusick     }
10322800Smckusick 
10422800Smckusick #if (TARGET == PDP11 || TARGET == VAX)
10522800Smckusick   i = 0;
10622800Smckusick   while (i < k)
10722800Smckusick     {
10822800Smckusick       p[i] = bits[i];
10922800Smckusick       i++;
11022800Smckusick     }
11122800Smckusick #else
11222800Smckusick   i = lenb;
11322800Smckusick   while (k > 0)
11422800Smckusick     p[--k] = bits[--i];
11522800Smckusick #endif
11622800Smckusick 
11722800Smckusick   return (p);
11822800Smckusick }
11922800Smckusick 
12022800Smckusick 
12122800Smckusick 
12222800Smckusick LOCAL char *
12322800Smckusick grabbytes(len, cp)
12422800Smckusick int len;
12522800Smckusick Constp cp;
12622800Smckusick {
12722800Smckusick   register char *p;
12822800Smckusick   register char *bytes;
12922800Smckusick   register int i;
13022800Smckusick   register int k;
13122800Smckusick   register int lenb;
13222800Smckusick 
133*33256Sbostic   bytes = cp->constant.ccp;
134*33256Sbostic   lenb = cp->vleng->constblock.constant.ci;
13522800Smckusick 
13622800Smckusick   p = (char *) ckalloc(len);
13722800Smckusick 
13822800Smckusick   if (len >= lenb)
13922800Smckusick     k = lenb;
14022800Smckusick   else
14122800Smckusick     k = len;
14222800Smckusick 
14322800Smckusick   i = 0;
14422800Smckusick   while (i < k)
14522800Smckusick     {
14622800Smckusick       p[i] = bytes[i];
14722800Smckusick       i++;
14822800Smckusick     }
14922800Smckusick 
15022800Smckusick   while (i < len)
15122800Smckusick     p[i++] = BLANK;
15222800Smckusick 
15322800Smckusick   return (p);
15422800Smckusick }
15522800Smckusick 
15622800Smckusick 
15722800Smckusick 
15822800Smckusick LOCAL expptr
15922800Smckusick cshort(cp)
16022800Smckusick Constp cp;
16122800Smckusick {
16222800Smckusick   static char *toobig = "data value too large";
16322800Smckusick   static char *reserved = "reserved operand assigned to an integer";
16422800Smckusick   static char *compat1 = "logical datum assigned to an integer variable";
16522800Smckusick   static char *compat2 = "character datum assigned to an integer variable";
16622800Smckusick 
16722800Smckusick   register expptr p;
16822800Smckusick   register short *shortp;
16922800Smckusick   register ftnint value;
17022800Smckusick   register long *rp;
17122800Smckusick   register double *minp;
17222800Smckusick   register double *maxp;
17322800Smckusick   realvalue x;
17422800Smckusick 
17522800Smckusick   switch (cp->vtype)
17622800Smckusick     {
17722800Smckusick     case TYBITSTR:
17822800Smckusick       shortp = (short *) grabbits(2, cp);
17922800Smckusick       p = (expptr) mkconst(TYSHORT);
180*33256Sbostic       p->constblock.constant.ci = *shortp;
18122800Smckusick       free((char *) shortp);
18222800Smckusick       break;
18322800Smckusick 
18422800Smckusick     case TYSHORT:
18522800Smckusick       p = (expptr) cpexpr(cp);
18622800Smckusick       break;
18722800Smckusick 
18822800Smckusick     case TYLONG:
189*33256Sbostic       value = cp->constant.ci;
19022800Smckusick       if (value >= MINWORD && value <= MAXWORD)
19122800Smckusick 	{
19222800Smckusick 	  p = (expptr) mkconst(TYSHORT);
193*33256Sbostic 	  p->constblock.constant.ci = value;
19422800Smckusick 	}
19522800Smckusick       else
19622800Smckusick 	{
19722800Smckusick 	  if (badvalue <= 1)
19822800Smckusick 	    {
19922800Smckusick 	      badvalue = 2;
20022800Smckusick 	      err(toobig);
20122800Smckusick 	    }
20222800Smckusick 	  p = errnode();
20322800Smckusick 	}
20422800Smckusick       break;
20522800Smckusick 
20622800Smckusick     case TYREAL:
20722800Smckusick     case TYDREAL:
20822800Smckusick     case TYCOMPLEX:
20922800Smckusick     case TYDCOMPLEX:
21022800Smckusick       minp = (double *) dminword;
21122800Smckusick       maxp = (double *) dmaxword;
212*33256Sbostic       rp = (long *) &(cp->constant.cd[0]);
21322800Smckusick       x.q.word1 = rp[0];
21422800Smckusick       x.q.word2 = rp[1];
21522800Smckusick       if (x.f.sign == 1 && x.f.exp == 0)
21622800Smckusick 	{
21722800Smckusick 	  if (badvalue <= 1)
21822800Smckusick 	    {
21922800Smckusick 	      badvalue = 2;
22022800Smckusick 	      err(reserved);
22122800Smckusick 	    }
22222800Smckusick 	  p = errnode();
22322800Smckusick 	}
22422800Smckusick       else if (x.d >= *minp && x.d <= *maxp)
22522800Smckusick 	{
22622800Smckusick 	  p = (expptr) mkconst(TYSHORT);
227*33256Sbostic 	  p->constblock.constant.ci = x.d;
22822800Smckusick 	}
22922800Smckusick       else
23022800Smckusick 	{
23122800Smckusick 	  if (badvalue <= 1)
23222800Smckusick 	    {
23322800Smckusick 	      badvalue = 2;
23422800Smckusick 	      err(toobig);
23522800Smckusick 	    }
23622800Smckusick 	  p = errnode();
23722800Smckusick 	}
23822800Smckusick       break;
23922800Smckusick 
24022800Smckusick     case TYLOGICAL:
24122800Smckusick       if (badvalue <= 1)
24222800Smckusick 	{
24322800Smckusick 	  badvalue = 2;
24422800Smckusick 	  err(compat1);
24522800Smckusick 	}
24622800Smckusick       p = errnode();
24722800Smckusick       break;
24822800Smckusick 
24922800Smckusick     case TYCHAR:
25022800Smckusick       if ( !ftn66flag && badvalue == 0 )
25122800Smckusick 	{
25222800Smckusick 	  badvalue = 1;
25322800Smckusick 	  warn(compat2);
25422800Smckusick 	}
25522800Smckusick 
25622800Smckusick     case TYHOLLERITH:
25722800Smckusick       shortp = (short *) grabbytes(2, cp);
25822800Smckusick       p = (expptr) mkconst(TYSHORT);
259*33256Sbostic       p->constblock.constant.ci = *shortp;
26022800Smckusick       free((char *) shortp);
26122800Smckusick       break;
26222800Smckusick 
26322800Smckusick     case TYERROR:
26422800Smckusick       p = errnode();
26522800Smckusick       break;
26622800Smckusick     }
26722800Smckusick 
26822800Smckusick   return (p);
26922800Smckusick }
27022800Smckusick 
27122800Smckusick 
27222800Smckusick 
27322800Smckusick LOCAL expptr
27422800Smckusick clong(cp)
27522800Smckusick Constp cp;
27622800Smckusick {
27722800Smckusick   static char *toobig = "data value too large";
27822800Smckusick   static char *reserved = "reserved operand assigned to an integer";
27922800Smckusick   static char *compat1 = "logical datum assigned to an integer variable";
28022800Smckusick   static char *compat2 = "character datum assigned to an integer variable";
28122800Smckusick 
28222800Smckusick   register expptr p;
28322800Smckusick   register ftnint *longp;
28422800Smckusick   register long *rp;
28522800Smckusick   register double *minp;
28622800Smckusick   register double *maxp;
28722800Smckusick   realvalue x;
28822800Smckusick 
28922800Smckusick   switch (cp->vtype)
29022800Smckusick     {
29122800Smckusick     case TYBITSTR:
29222800Smckusick       longp = (ftnint *) grabbits(4, cp);
29322800Smckusick       p = (expptr) mkconst(TYLONG);
294*33256Sbostic       p->constblock.constant.ci = *longp;
29522800Smckusick       free((char *) longp);
29622800Smckusick       break;
29722800Smckusick 
29822800Smckusick     case TYSHORT:
29922800Smckusick       p = (expptr) mkconst(TYLONG);
300*33256Sbostic       p->constblock.constant.ci = cp->constant.ci;
30122800Smckusick       break;
30222800Smckusick 
30322800Smckusick     case TYLONG:
30422800Smckusick       p = (expptr) cpexpr(cp);
30522800Smckusick       break;
30622800Smckusick 
30722800Smckusick     case TYREAL:
30822800Smckusick     case TYDREAL:
30922800Smckusick     case TYCOMPLEX:
31022800Smckusick     case TYDCOMPLEX:
31122800Smckusick       minp = (double *) dminint;
31222800Smckusick       maxp = (double *) dmaxint;
313*33256Sbostic       rp = (long *) &(cp->constant.cd[0]);
31422800Smckusick       x.q.word1 = rp[0];
31522800Smckusick       x.q.word2 = rp[1];
31622800Smckusick       if (x.f.sign == 1 && x.f.exp == 0)
31722800Smckusick 	{
31822800Smckusick 	  if (badvalue <= 1)
31922800Smckusick 	    {
32022800Smckusick 	      badvalue = 2;
32122800Smckusick 	      err(reserved);
32222800Smckusick 	    }
32322800Smckusick 	  p = errnode();
32422800Smckusick 	}
32522800Smckusick       else if (x.d >= *minp && x.d <= *maxp)
32622800Smckusick 	{
32722800Smckusick 	  p = (expptr) mkconst(TYLONG);
328*33256Sbostic 	  p->constblock.constant.ci = x.d;
32922800Smckusick 	}
33022800Smckusick       else
33122800Smckusick 	{
33222800Smckusick 	  if (badvalue <= 1)
33322800Smckusick 	    {
33422800Smckusick 	      badvalue = 2;
33522800Smckusick 	      err(toobig);
33622800Smckusick 	    }
33722800Smckusick 	  p = errnode();
33822800Smckusick 	}
33922800Smckusick       break;
34022800Smckusick 
34122800Smckusick     case TYLOGICAL:
34222800Smckusick       if (badvalue <= 1)
34322800Smckusick 	{
34422800Smckusick 	  badvalue = 2;
34522800Smckusick 	  err(compat1);
34622800Smckusick 	}
34722800Smckusick       p = errnode();
34822800Smckusick       break;
34922800Smckusick 
35022800Smckusick     case TYCHAR:
35122800Smckusick       if ( !ftn66flag && badvalue == 0 )
35222800Smckusick 	{
35322800Smckusick 	  badvalue = 1;
35422800Smckusick 	  warn(compat2);
35522800Smckusick 	}
35622800Smckusick 
35722800Smckusick     case TYHOLLERITH:
35822800Smckusick       longp = (ftnint *) grabbytes(4, cp);
35922800Smckusick       p = (expptr) mkconst(TYLONG);
360*33256Sbostic       p->constblock.constant.ci = *longp;
36122800Smckusick       free((char *) longp);
36222800Smckusick       break;
36322800Smckusick 
36422800Smckusick     case TYERROR:
36522800Smckusick       p = errnode();
36622800Smckusick       break;
36722800Smckusick     }
36822800Smckusick 
36922800Smckusick   return (p);
37022800Smckusick }
37122800Smckusick 
37222800Smckusick 
37322800Smckusick 
37422800Smckusick LOCAL expptr
37522800Smckusick creal(cp)
37622800Smckusick Constp cp;
37722800Smckusick {
37822800Smckusick   static char *toobig = "data value too large";
37922800Smckusick   static char *compat1 = "logical datum assigned to a real variable";
38022800Smckusick   static char *compat2 = "character datum assigned to a real variable";
38122800Smckusick 
38222800Smckusick   register expptr p;
38322800Smckusick   register long *longp;
38422800Smckusick   register long *rp;
38522800Smckusick   register double *minp;
38622800Smckusick   register double *maxp;
38722800Smckusick   realvalue x;
38822800Smckusick   float y;
38922800Smckusick 
39022800Smckusick   switch (cp->vtype)
39122800Smckusick     {
39222800Smckusick     case TYBITSTR:
39322800Smckusick       longp = (long *) grabbits(4, cp);
39422800Smckusick       p = (expptr) mkconst(TYREAL);
395*33256Sbostic       rp = (long *) &(p->constblock.constant.cd[0]);
39622800Smckusick       rp[0] = *longp;
39722800Smckusick       free((char *) longp);
39822800Smckusick       break;
39922800Smckusick 
40022800Smckusick     case TYSHORT:
40122800Smckusick     case TYLONG:
40222800Smckusick       p = (expptr) mkconst(TYREAL);
403*33256Sbostic       p->constblock.constant.cd[0] = cp->constant.ci;
40422800Smckusick       break;
40522800Smckusick 
40622800Smckusick     case TYREAL:
40722800Smckusick     case TYDREAL:
40822800Smckusick     case TYCOMPLEX:
40922800Smckusick     case TYDCOMPLEX:
41022800Smckusick       minp = (double *) dminreal;
41122800Smckusick       maxp = (double *) dmaxreal;
412*33256Sbostic       rp = (long *) &(cp->constant.cd[0]);
41322800Smckusick       x.q.word1 = rp[0];
41422800Smckusick       x.q.word2 = rp[1];
41522800Smckusick       if (x.f.sign == 1 && x.f.exp == 0)
41622800Smckusick 	{
41722800Smckusick 	  p = (expptr) mkconst(TYREAL);
418*33256Sbostic 	  rp = (long *) &(p->constblock.constant.cd[0]);
41922800Smckusick 	  rp[0] = x.q.word1;
42022800Smckusick 	}
42122800Smckusick       else if (x.d >= *minp && x.d <= *maxp)
42222800Smckusick 	{
42322800Smckusick 	  p = (expptr) mkconst(TYREAL);
42422800Smckusick 	  y = x.d;
425*33256Sbostic 	  p->constblock.constant.cd[0] = y;
42622800Smckusick 	}
42722800Smckusick       else
42822800Smckusick 	{
42922800Smckusick 	  if (badvalue <= 1)
43022800Smckusick 	    {
43122800Smckusick 	      badvalue = 2;
43222800Smckusick 	      err(toobig);
43322800Smckusick 	    }
43422800Smckusick 	  p = errnode();
43522800Smckusick 	}
43622800Smckusick       break;
43722800Smckusick 
43822800Smckusick     case TYLOGICAL:
43922800Smckusick       if (badvalue <= 1)
44022800Smckusick 	{
44122800Smckusick 	  badvalue = 2;
44222800Smckusick 	  err(compat1);
44322800Smckusick 	}
44422800Smckusick       p = errnode();
44522800Smckusick       break;
44622800Smckusick 
44722800Smckusick     case TYCHAR:
44822800Smckusick       if ( !ftn66flag && badvalue == 0)
44922800Smckusick 	{
45022800Smckusick 	  badvalue = 1;
45122800Smckusick 	  warn(compat2);
45222800Smckusick 	}
45322800Smckusick 
45422800Smckusick     case TYHOLLERITH:
45522800Smckusick       longp = (long *) grabbytes(4, cp);
45622800Smckusick       p = (expptr) mkconst(TYREAL);
457*33256Sbostic       rp = (long *) &(p->constblock.constant.cd[0]);
45822800Smckusick       rp[0] = *longp;
45922800Smckusick       free((char *) longp);
46022800Smckusick       break;
46122800Smckusick 
46222800Smckusick     case TYERROR:
46322800Smckusick       p = errnode();
46422800Smckusick       break;
46522800Smckusick     }
46622800Smckusick 
46722800Smckusick   return (p);
46822800Smckusick }
46922800Smckusick 
47022800Smckusick 
47122800Smckusick 
47222800Smckusick LOCAL expptr
47322800Smckusick cdreal(cp)
47422800Smckusick Constp cp;
47522800Smckusick {
47622800Smckusick   static char *compat1 =
47722800Smckusick 	"logical datum assigned to a double precision variable";
47822800Smckusick   static char *compat2 =
47922800Smckusick 	"character datum assigned to a double precision variable";
48022800Smckusick 
48122800Smckusick   register expptr p;
48222800Smckusick   register long *longp;
48322800Smckusick   register long *rp;
48422800Smckusick 
48522800Smckusick   switch (cp->vtype)
48622800Smckusick     {
48722800Smckusick     case TYBITSTR:
48822800Smckusick       longp = (long *) grabbits(8, cp);
48922800Smckusick       p = (expptr) mkconst(TYDREAL);
490*33256Sbostic       rp = (long *) &(p->constblock.constant.cd[0]);
49122800Smckusick       rp[0] = longp[0];
49222800Smckusick       rp[1] = longp[1];
49322800Smckusick       free((char *) longp);
49422800Smckusick       break;
49522800Smckusick 
49622800Smckusick     case TYSHORT:
49722800Smckusick     case TYLONG:
49822800Smckusick       p = (expptr) mkconst(TYDREAL);
499*33256Sbostic       p->constblock.constant.cd[0] = cp->constant.ci;
50022800Smckusick       break;
50122800Smckusick 
50222800Smckusick     case TYREAL:
50322800Smckusick     case TYDREAL:
50422800Smckusick     case TYCOMPLEX:
50522800Smckusick     case TYDCOMPLEX:
50622800Smckusick       p = (expptr) mkconst(TYDREAL);
507*33256Sbostic       longp = (long *) &(cp->constant.cd[0]);
508*33256Sbostic       rp = (long *) &(p->constblock.constant.cd[0]);
50922800Smckusick       rp[0] = longp[0];
51022800Smckusick       rp[1] = longp[1];
51122800Smckusick       break;
51222800Smckusick 
51322800Smckusick     case TYLOGICAL:
51422800Smckusick       if (badvalue <= 1)
51522800Smckusick 	{
51622800Smckusick 	  badvalue = 2;
51722800Smckusick 	  err(compat1);
51822800Smckusick 	}
51922800Smckusick       p = errnode();
52022800Smckusick       break;
52122800Smckusick 
52222800Smckusick     case TYCHAR:
52322800Smckusick       if ( !ftn66flag && badvalue == 0 )
52422800Smckusick 	{
52522800Smckusick 	  badvalue = 1;
52622800Smckusick 	  warn(compat2);
52722800Smckusick 	}
52822800Smckusick 
52922800Smckusick     case TYHOLLERITH:
53022800Smckusick       longp = (long *) grabbytes(8, cp);
53122800Smckusick       p = (expptr) mkconst(TYDREAL);
532*33256Sbostic       rp = (long *) &(p->constblock.constant.cd[0]);
53322800Smckusick       rp[0] = longp[0];
53422800Smckusick       rp[1] = longp[1];
53522800Smckusick       free((char *) longp);
53622800Smckusick       break;
53722800Smckusick 
53822800Smckusick     case TYERROR:
53922800Smckusick       p = errnode();
54022800Smckusick       break;
54122800Smckusick     }
54222800Smckusick 
54322800Smckusick   return (p);
54422800Smckusick }
54522800Smckusick 
54622800Smckusick 
54722800Smckusick 
54822800Smckusick LOCAL expptr
54922800Smckusick ccomplex(cp)
55022800Smckusick Constp cp;
55122800Smckusick {
55222800Smckusick   static char *toobig = "data value too large";
55322800Smckusick   static char *compat1 = "logical datum assigned to a complex variable";
55422800Smckusick   static char *compat2 = "character datum assigned to a complex variable";
55522800Smckusick 
55622800Smckusick   register expptr p;
55722800Smckusick   register long *longp;
55822800Smckusick   register long *rp;
55922800Smckusick   register double *minp;
56022800Smckusick   register double *maxp;
56122800Smckusick   realvalue re, im;
56222800Smckusick   int overflow;
56322800Smckusick   float x;
56422800Smckusick 
56522800Smckusick   switch (cp->vtype)
56622800Smckusick     {
56722800Smckusick     case TYBITSTR:
56822800Smckusick       longp = (long *) grabbits(8, cp);
56922800Smckusick       p = (expptr) mkconst(TYCOMPLEX);
570*33256Sbostic       rp = (long *) &(p->constblock.constant.cd[0]);
57122800Smckusick       rp[0] = longp[0];
57222800Smckusick       rp[2] = longp[1];
57322800Smckusick       free((char *) longp);
57422800Smckusick       break;
57522800Smckusick 
57622800Smckusick     case TYSHORT:
57722800Smckusick     case TYLONG:
57822800Smckusick       p = (expptr) mkconst(TYCOMPLEX);
579*33256Sbostic       p->constblock.constant.cd[0] = cp->constant.ci;
58022800Smckusick       break;
58122800Smckusick 
58222800Smckusick     case TYREAL:
58322800Smckusick     case TYDREAL:
58422800Smckusick     case TYCOMPLEX:
58522800Smckusick     case TYDCOMPLEX:
58622800Smckusick       overflow = 0;
58722800Smckusick       minp = (double *) dminreal;
58822800Smckusick       maxp = (double *) dmaxreal;
589*33256Sbostic       rp = (long *) &(cp->constant.cd[0]);
59022800Smckusick       re.q.word1 = rp[0];
59122800Smckusick       re.q.word2 = rp[1];
59222800Smckusick       im.q.word1 = rp[2];
59322800Smckusick       im.q.word2 = rp[3];
59422800Smckusick       if (((re.f.sign == 0 || re.f.exp != 0) &&
59522800Smckusick 	   (re.d < *minp || re.d > *maxp))       ||
59622800Smckusick 	  ((im.f.sign == 0 || re.f.exp != 0) &&
59722800Smckusick 	   (im.d < *minp || re.d > *maxp)))
59822800Smckusick 	{
59922800Smckusick 	  if (badvalue <= 1)
60022800Smckusick 	    {
60122800Smckusick 	      badvalue = 2;
60222800Smckusick 	      err(toobig);
60322800Smckusick 	    }
60422800Smckusick 	  p = errnode();
60522800Smckusick 	}
60622800Smckusick       else
60722800Smckusick 	{
60822800Smckusick 	  p = (expptr) mkconst(TYCOMPLEX);
60922800Smckusick 	  if (re.f.sign == 1 && re.f.exp == 0)
61022800Smckusick 	    re.q.word2 = 0;
61122800Smckusick 	  else
61222800Smckusick 	    {
61322800Smckusick 	      x = re.d;
61422800Smckusick 	      re.d = x;
61522800Smckusick 	    }
61622800Smckusick 	  if (im.f.sign == 1 && im.f.exp == 0)
61722800Smckusick 	    im.q.word2 = 0;
61822800Smckusick 	  else
61922800Smckusick 	    {
62022800Smckusick 	      x = im.d;
62122800Smckusick 	      im.d = x;
62222800Smckusick 	    }
623*33256Sbostic 	  rp = (long *) &(p->constblock.constant.cd[0]);
62422800Smckusick 	  rp[0] = re.q.word1;
62522800Smckusick 	  rp[1] = re.q.word2;
62622800Smckusick 	  rp[2] = im.q.word1;
62722800Smckusick 	  rp[3] = im.q.word2;
62822800Smckusick 	}
62922800Smckusick       break;
63022800Smckusick 
63122800Smckusick     case TYLOGICAL:
63222800Smckusick       if (badvalue <= 1)
63322800Smckusick 	{
63422800Smckusick 	  badvalue = 2;
63522800Smckusick 	  err(compat1);
63622800Smckusick 	}
63722800Smckusick       break;
63822800Smckusick 
63922800Smckusick     case TYCHAR:
64022800Smckusick       if ( !ftn66flag && badvalue == 0)
64122800Smckusick 	{
64222800Smckusick 	  badvalue = 1;
64322800Smckusick 	  warn(compat2);
64422800Smckusick 	}
64522800Smckusick 
64622800Smckusick     case TYHOLLERITH:
64722800Smckusick       longp = (long *) grabbytes(8, cp);
64822800Smckusick       p = (expptr) mkconst(TYCOMPLEX);
649*33256Sbostic       rp = (long *) &(p->constblock.constant.cd[0]);
65022800Smckusick       rp[0] = longp[0];
65122800Smckusick       rp[2] = longp[1];
65222800Smckusick       free((char *) longp);
65322800Smckusick       break;
65422800Smckusick 
65522800Smckusick     case TYERROR:
65622800Smckusick       p = errnode();
65722800Smckusick       break;
65822800Smckusick     }
65922800Smckusick 
66022800Smckusick   return (p);
66122800Smckusick }
66222800Smckusick 
66322800Smckusick 
66422800Smckusick 
66522800Smckusick LOCAL expptr
66622800Smckusick cdcomplex(cp)
66722800Smckusick Constp cp;
66822800Smckusick {
66922800Smckusick   static char *compat1 = "logical datum assigned to a complex variable";
67022800Smckusick   static char *compat2 = "character datum assigned to a complex variable";
67122800Smckusick 
67222800Smckusick   register expptr p;
67322800Smckusick   register long *longp;
67422800Smckusick   register long *rp;
67522800Smckusick 
67622800Smckusick   switch (cp->vtype)
67722800Smckusick     {
67822800Smckusick     case TYBITSTR:
67922800Smckusick       longp = (long *) grabbits(16, cp);
68022800Smckusick       p = (expptr) mkconst(TYDCOMPLEX);
681*33256Sbostic       rp = (long *) &(p->constblock.constant.cd[0]);
68222800Smckusick       rp[0] = longp[0];
68322800Smckusick       rp[1] = longp[1];
68422800Smckusick       rp[2] = longp[2];
68522800Smckusick       rp[3] = longp[3];
68622800Smckusick       free((char *) longp);
68722800Smckusick       break;
68822800Smckusick 
68922800Smckusick     case TYSHORT:
69022800Smckusick     case TYLONG:
69122800Smckusick       p = (expptr) mkconst(TYDCOMPLEX);
692*33256Sbostic       p->constblock.constant.cd[0] = cp->constant.ci;
69322800Smckusick       break;
69422800Smckusick 
69522800Smckusick     case TYREAL:
69622800Smckusick     case TYDREAL:
69722800Smckusick     case TYCOMPLEX:
69822800Smckusick     case TYDCOMPLEX:
69922800Smckusick       p = (expptr) mkconst(TYDCOMPLEX);
700*33256Sbostic       longp = (long *) &(cp->constant.cd[0]);
701*33256Sbostic       rp = (long *) &(p->constblock.constant.cd[0]);
70222800Smckusick       rp[0] = longp[0];
70322800Smckusick       rp[1] = longp[1];
70422800Smckusick       rp[2] = longp[2];
70522800Smckusick       rp[3] = longp[3];
70622800Smckusick       break;
70722800Smckusick 
70822800Smckusick     case TYLOGICAL:
70922800Smckusick       if (badvalue <= 1)
71022800Smckusick 	{
71122800Smckusick 	  badvalue = 2;
71222800Smckusick 	  err(compat1);
71322800Smckusick 	}
71422800Smckusick       p = errnode();
71522800Smckusick       break;
71622800Smckusick 
71722800Smckusick     case TYCHAR:
71822800Smckusick       if ( !ftn66flag && badvalue == 0 )
71922800Smckusick 	{
72022800Smckusick 	  badvalue = 1;
72122800Smckusick 	  warn(compat2);
72222800Smckusick 	}
72322800Smckusick 
72422800Smckusick     case TYHOLLERITH:
72522800Smckusick       longp = (long *) grabbytes(16, cp);
72622800Smckusick       p = (expptr) mkconst(TYDCOMPLEX);
727*33256Sbostic       rp = (long *) &(p->constblock.constant.cd[0]);
72822800Smckusick       rp[0] = longp[0];
72922800Smckusick       rp[1] = longp[1];
73022800Smckusick       rp[2] = longp[2];
73122800Smckusick       rp[3] = longp[3];
73222800Smckusick       free((char *) longp);
73322800Smckusick       break;
73422800Smckusick 
73522800Smckusick     case TYERROR:
73622800Smckusick       p = errnode();
73722800Smckusick       break;
73822800Smckusick     }
73922800Smckusick 
74022800Smckusick   return (p);
74122800Smckusick }
74222800Smckusick 
74322800Smckusick 
74422800Smckusick 
74522800Smckusick LOCAL expptr
74622800Smckusick clogical(cp)
74722800Smckusick Constp cp;
74822800Smckusick {
74922800Smckusick   static char *compat1 = "numeric datum assigned to a logical variable";
75022800Smckusick   static char *compat2 = "character datum assigned to a logical variable";
75122800Smckusick 
75222800Smckusick   register expptr p;
75322800Smckusick   register long *longp;
75422800Smckusick   register short *shortp;
75522800Smckusick   register int size;
75622800Smckusick 
75722800Smckusick   size = typesize[tylogical];
75822800Smckusick 
75922800Smckusick   switch (cp->vtype)
76022800Smckusick     {
76122800Smckusick     case TYBITSTR:
76222800Smckusick       p = (expptr) mkconst(tylogical);
76322800Smckusick       if (tylogical == TYSHORT)
76422800Smckusick 	{
76522800Smckusick 	  shortp = (short *) grabbits(size, cp);
766*33256Sbostic 	  p->constblock.constant.ci = (int) *shortp;
76722800Smckusick 	  free((char *) shortp);
76822800Smckusick 	}
76922800Smckusick       else
77022800Smckusick 	{
77122800Smckusick 	  longp = (long *) grabbits(size, cp);
772*33256Sbostic 	  p->constblock.constant.ci = *longp;
77322800Smckusick 	  free((char *) longp);
77422800Smckusick 	}
77522800Smckusick       break;
77622800Smckusick 
77722800Smckusick     case TYSHORT:
77822800Smckusick     case TYLONG:
77922800Smckusick     case TYREAL:
78022800Smckusick     case TYDREAL:
78122800Smckusick     case TYCOMPLEX:
78222800Smckusick     case TYDCOMPLEX:
78322800Smckusick       if (badvalue <= 1)
78422800Smckusick 	{
78522800Smckusick 	  badvalue = 2;
78622800Smckusick 	  err(compat1);
78722800Smckusick 	}
78822800Smckusick       p = errnode();
78922800Smckusick       break;
79022800Smckusick 
79122800Smckusick     case TYLOGICAL:
79222800Smckusick       p = (expptr) cpexpr(cp);
79322800Smckusick       p->constblock.vtype = tylogical;
79422800Smckusick       break;
79522800Smckusick 
79622800Smckusick     case TYCHAR:
79722800Smckusick       if ( !ftn66flag && badvalue == 0 )
79822800Smckusick 	{
79922800Smckusick 	  badvalue = 1;
80022800Smckusick 	  warn(compat2);
80122800Smckusick 	}
80222800Smckusick 
80322800Smckusick     case TYHOLLERITH:
80422800Smckusick       p = (expptr) mkconst(tylogical);
80522800Smckusick       if (tylogical == TYSHORT)
80622800Smckusick 	{
80722800Smckusick 	  shortp = (short *) grabbytes(size, cp);
808*33256Sbostic 	  p->constblock.constant.ci = (int) *shortp;
80922800Smckusick 	  free((char *) shortp);
81022800Smckusick 	}
81122800Smckusick       else
81222800Smckusick 	{
81322800Smckusick 	  longp = (long *) grabbytes(4, cp);
814*33256Sbostic 	  p->constblock.constant.ci = *longp;
81522800Smckusick 	  free((char *) longp);
81622800Smckusick 	}
81722800Smckusick       break;
81822800Smckusick 
81922800Smckusick     case TYERROR:
82022800Smckusick       p = errnode();
82122800Smckusick       break;
82222800Smckusick     }
82322800Smckusick 
82422800Smckusick   return (p);
82522800Smckusick }
82622800Smckusick 
82722800Smckusick 
82822800Smckusick 
82922800Smckusick LOCAL expptr
83022800Smckusick cchar(len, cp)
83122800Smckusick int len;
83222800Smckusick Constp cp;
83322800Smckusick {
83422800Smckusick   static char *compat1 = "numeric datum assigned to a character variable";
83522800Smckusick   static char *compat2 = "logical datum assigned to a character variable";
83622800Smckusick 
83722800Smckusick   register expptr p;
83822800Smckusick   register char *value;
83922800Smckusick 
84022800Smckusick   switch (cp->vtype)
84122800Smckusick     {
84222800Smckusick     case TYBITSTR:
84322800Smckusick       value = grabbits(len, cp);
84422800Smckusick       p = (expptr) mkstrcon(len, value);
84522800Smckusick       free(value);
84622800Smckusick       break;
84722800Smckusick 
84822800Smckusick     case TYSHORT:
84922800Smckusick     case TYLONG:
85022800Smckusick     case TYREAL:
85122800Smckusick     case TYDREAL:
85222800Smckusick     case TYCOMPLEX:
85322800Smckusick     case TYDCOMPLEX:
85422800Smckusick       if (badvalue <= 1)
85522800Smckusick 	{
85622800Smckusick 	  badvalue = 2;
85722800Smckusick 	  err(compat1);
85822800Smckusick 	}
85922800Smckusick       p = errnode();
86022800Smckusick       break;
86122800Smckusick 
86222800Smckusick     case TYLOGICAL:
86322800Smckusick       if (badvalue <= 1)
86422800Smckusick 	{
86522800Smckusick 	  badvalue = 2;
86622800Smckusick 	  err(compat2);
86722800Smckusick 	}
86822800Smckusick       p = errnode();
86922800Smckusick       break;
87022800Smckusick 
87122800Smckusick     case TYCHAR:
87222800Smckusick     case TYHOLLERITH:
87322800Smckusick       value = grabbytes(len, cp);
87422800Smckusick       p = (expptr) mkstrcon(len, value);
87522800Smckusick       free(value);
87622800Smckusick       break;
87722800Smckusick 
87822800Smckusick     case TYERROR:
87922800Smckusick       p = errnode();
88022800Smckusick       break;
88122800Smckusick     }
88222800Smckusick 
88322800Smckusick   return (p);
88422800Smckusick }
88522800Smckusick 
88622800Smckusick 
88722800Smckusick 
88822800Smckusick expptr
889*33256Sbostic convconst(type, len, constant)
89022800Smckusick int type;
89122800Smckusick int len;
892*33256Sbostic Constp constant;
89322800Smckusick {
89422800Smckusick   register expptr p;
89522800Smckusick 
89622800Smckusick   switch (type)
89722800Smckusick     {
89822800Smckusick     case TYSHORT:
899*33256Sbostic       p = cshort(constant);
90022800Smckusick       break;
90122800Smckusick 
90222800Smckusick     case TYLONG:
903*33256Sbostic       p = clong(constant);
90422800Smckusick       break;
90522800Smckusick 
90622800Smckusick     case TYREAL:
907*33256Sbostic       p = creal(constant);
90822800Smckusick       break;
90922800Smckusick 
91022800Smckusick     case TYDREAL:
911*33256Sbostic       p = cdreal(constant);
91222800Smckusick       break;
91322800Smckusick 
91422800Smckusick     case TYCOMPLEX:
915*33256Sbostic       p = ccomplex(constant);
91622800Smckusick       break;
91722800Smckusick 
91822800Smckusick     case TYDCOMPLEX:
919*33256Sbostic       p = cdcomplex(constant);
92022800Smckusick       break;
92122800Smckusick 
92222800Smckusick     case TYLOGICAL:
923*33256Sbostic       p = clogical(constant);
92422800Smckusick       break;
92522800Smckusick 
92622800Smckusick     case TYCHAR:
927*33256Sbostic       p = cchar(len, constant);
92822800Smckusick       break;
92922800Smckusick 
93022800Smckusick     case TYERROR:
93122800Smckusick     case TYUNKNOWN:
93222800Smckusick       p = errnode();
93322800Smckusick       break;
93422800Smckusick 
93522800Smckusick     default:
93622800Smckusick       badtype("convconst", type);
93722800Smckusick     }
93822800Smckusick 
93922800Smckusick   return (p);
94022800Smckusick }
941