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