xref: /csrg-svn/usr.bin/f77/pass1.tahoe/conv.c (revision 46301)
143203Sbostic #include "defs.h"
243203Sbostic #include "conv.h"
343203Sbostic 
443203Sbostic int badvalue;
543203Sbostic 
643203Sbostic 
743203Sbostic /*  The following constants are used to check the limits of  */
843203Sbostic /*  conversions.  Dmaxword is the largest double precision   */
943203Sbostic /*  number which can be converted to a two-byte integer      */
1043203Sbostic /*  without overflow.  Dminword is the smallest double       */
1143203Sbostic /*  precision value which can be converted to a two-byte     */
1243203Sbostic /*  integer without overflow.  Dmaxint and dminint are the   */
1343203Sbostic /*  analogous values for four-byte integers.                 */
1443203Sbostic 
1543203Sbostic /* short array should be correct for both VAX and TAHOE */
1643203Sbostic 
1743203Sbostic LOCAL short dmaxword[] = { 0x47ff, 0xfeff, 0xffff, 0xffff }; /* 32767.5 */
1843203Sbostic LOCAL short dminword[] = { 0xc800, 0x007f, 0xffff, 0xffff }; /* -32768.499999999999 */
1943203Sbostic 
2043203Sbostic LOCAL short dmaxint[]  = { 0x4fff, 0xffff, 0xfeff, 0xffff }; /* 2147483647.5 */
2143203Sbostic LOCAL short dminint[]  = { 0xd000, 0x0000, 0x007f, 0xffff }; /* -2147483648.4999999 */
2243203Sbostic 
2343203Sbostic LOCAL short dmaxreal[] = { 0x7fff, 0xffff, 0x7fff, 0xffff }; /* 1.7014117838986683e+38 */
2443203Sbostic LOCAL short dminreal[] = { 0xffff, 0xffff, 0x7fff, 0xffff }; /* -1.7014117838986683e+38 */
2543203Sbostic 
2643203Sbostic 
2743203Sbostic 
2843203Sbostic /*  The routines which follow are used to convert  */
2943203Sbostic /*  constants into constants of other types.       */
3043203Sbostic 
3143203Sbostic LOCAL char *
3243203Sbostic grabbits(len, cp)
3343203Sbostic int len;
3443203Sbostic Constp cp;
3543203Sbostic {
3643203Sbostic 
3743203Sbostic   static char *toobig = "bit value too large";
3843203Sbostic 
3943203Sbostic   register char *p;
4043203Sbostic   register char *bits;
4143203Sbostic   register int i;
4243203Sbostic   register int k;
4343203Sbostic   register int lenb;
4443203Sbostic 
45*46301Sbostic   bits = cp->constant.ccp;
46*46301Sbostic   lenb = cp->vleng->constblock.constant.ci;
4743203Sbostic 
4843203Sbostic   p = (char *) ckalloc(len);
4943203Sbostic 
5043203Sbostic   if (len >= lenb)
5143203Sbostic     k = lenb;
5243203Sbostic   else
5343203Sbostic     {
5443203Sbostic       k = len;
5543203Sbostic       if ( badvalue == 0 )
5643203Sbostic 	{
5743203Sbostic #if (HERE == PDP11 || HERE == VAX)
5843203Sbostic 	  i = len;
5943203Sbostic 	  while ( i < lenb && bits[i] == 0 )
6043203Sbostic 	    i++;
6143203Sbostic 	  if (i < lenb)
6243203Sbostic 	    badvalue = 1;
6343203Sbostic #else
6443203Sbostic 	  i = lenb - len - 1;
6543203Sbostic 	  while ( i >= 0 && bits[i] == 0)
6643203Sbostic 	    i--;
6743203Sbostic 	  if (i >= 0)
6843203Sbostic 	    badvalue = 1;
6943203Sbostic #endif
7043203Sbostic 	  if (badvalue)
7143203Sbostic 	    warn(toobig);
7243203Sbostic 	}
7343203Sbostic     }
7443203Sbostic 
7543203Sbostic #if (HERE == PDP11 || HERE == VAX)
7643203Sbostic   i = 0;
7743203Sbostic   while (i < k)
7843203Sbostic     {
7943203Sbostic       p[i] = bits[i];
8043203Sbostic       i++;
8143203Sbostic     }
8243203Sbostic #else
8343203Sbostic   i = lenb;
8443203Sbostic   while (k > 0)
8543203Sbostic     p[--k] = bits[--i];
8643203Sbostic #endif
8743203Sbostic 
8843203Sbostic   return (p);
8943203Sbostic }
9043203Sbostic 
9143203Sbostic 
9243203Sbostic 
9343203Sbostic LOCAL char *
9443203Sbostic grabbytes(len, cp)
9543203Sbostic int len;
9643203Sbostic Constp cp;
9743203Sbostic {
9843203Sbostic   register char *p;
9943203Sbostic   register char *bytes;
10043203Sbostic   register int i;
10143203Sbostic   register int k;
10243203Sbostic   register int lenb;
10343203Sbostic 
104*46301Sbostic   bytes = cp->constant.ccp;
105*46301Sbostic   lenb = cp->vleng->constblock.constant.ci;
10643203Sbostic 
10743203Sbostic   p = (char *) ckalloc(len);
10843203Sbostic 
10943203Sbostic   if (len >= lenb)
11043203Sbostic     k = lenb;
11143203Sbostic   else
11243203Sbostic     k = len;
11343203Sbostic 
11443203Sbostic   i = 0;
11543203Sbostic   while (i < k)
11643203Sbostic     {
11743203Sbostic       p[i] = bytes[i];
11843203Sbostic       i++;
11943203Sbostic     }
12043203Sbostic 
12143203Sbostic   while (i < len)
12243203Sbostic     p[i++] = BLANK;
12343203Sbostic 
12443203Sbostic   return (p);
12543203Sbostic }
12643203Sbostic 
12743203Sbostic 
12843203Sbostic 
12943203Sbostic LOCAL expptr
13043203Sbostic cshort(cp)
13143203Sbostic Constp cp;
13243203Sbostic {
13343203Sbostic   static char *toobig = "data value too large";
13443203Sbostic   static char *reserved = "reserved operand assigned to an integer";
13543203Sbostic   static char *compat1 = "logical datum assigned to an integer variable";
13643203Sbostic   static char *compat2 = "character datum assigned to an integer variable";
13743203Sbostic 
13843203Sbostic   register expptr p;
13943203Sbostic   register short *shortp;
14043203Sbostic   register ftnint value;
14143203Sbostic   register long *rp;
14243203Sbostic   register double *minp;
14343203Sbostic   register double *maxp;
14443203Sbostic   realvalue x;
14543203Sbostic 
14643203Sbostic   switch (cp->vtype)
14743203Sbostic     {
14843203Sbostic     case TYBITSTR:
14943203Sbostic       shortp = (short *) grabbits(2, cp);
15043203Sbostic       p = (expptr) mkconst(TYSHORT);
151*46301Sbostic       p->constblock.constant.ci = *shortp;
15243203Sbostic       free((char *) shortp);
15343203Sbostic       break;
15443203Sbostic 
15543203Sbostic     case TYSHORT:
15643203Sbostic       p = (expptr) cpexpr(cp);
15743203Sbostic       break;
15843203Sbostic 
15943203Sbostic     case TYLONG:
160*46301Sbostic       value = cp->constant.ci;
16143203Sbostic       if (value >= MINWORD && value <= MAXWORD)
16243203Sbostic 	{
16343203Sbostic 	  p = (expptr) mkconst(TYSHORT);
164*46301Sbostic 	  p->constblock.constant.ci = value;
16543203Sbostic 	}
16643203Sbostic       else
16743203Sbostic 	{
16843203Sbostic 	  if (badvalue <= 1)
16943203Sbostic 	    {
17043203Sbostic 	      badvalue = 2;
17143203Sbostic 	      err(toobig);
17243203Sbostic 	    }
17343203Sbostic 	  p = errnode();
17443203Sbostic 	}
17543203Sbostic       break;
17643203Sbostic 
17743203Sbostic     case TYREAL:
17843203Sbostic     case TYDREAL:
17943203Sbostic     case TYCOMPLEX:
18043203Sbostic     case TYDCOMPLEX:
18143203Sbostic       minp = (double *) dminword;
18243203Sbostic       maxp = (double *) dmaxword;
183*46301Sbostic       rp = (long *) &(cp->constant.cd[0]);
18443203Sbostic       x.q.word1 = rp[0];
18543203Sbostic       x.q.word2 = rp[1];
18643203Sbostic       if (x.f.sign == 1 && x.f.exp == 0)
18743203Sbostic 	{
18843203Sbostic 	  if (badvalue <= 1)
18943203Sbostic 	    {
19043203Sbostic 	      badvalue = 2;
19143203Sbostic 	      err(reserved);
19243203Sbostic 	    }
19343203Sbostic 	  p = errnode();
19443203Sbostic 	}
19543203Sbostic       else if (x.d >= *minp && x.d <= *maxp)
19643203Sbostic 	{
19743203Sbostic 	  p = (expptr) mkconst(TYSHORT);
198*46301Sbostic 	  p->constblock.constant.ci = x.d;
19943203Sbostic 	}
20043203Sbostic       else
20143203Sbostic 	{
20243203Sbostic 	  if (badvalue <= 1)
20343203Sbostic 	    {
20443203Sbostic 	      badvalue = 2;
20543203Sbostic 	      err(toobig);
20643203Sbostic 	    }
20743203Sbostic 	  p = errnode();
20843203Sbostic 	}
20943203Sbostic       break;
21043203Sbostic 
21143203Sbostic     case TYLOGICAL:
21243203Sbostic       if (badvalue <= 1)
21343203Sbostic 	{
21443203Sbostic 	  badvalue = 2;
21543203Sbostic 	  err(compat1);
21643203Sbostic 	}
21743203Sbostic       p = errnode();
21843203Sbostic       break;
21943203Sbostic 
22043203Sbostic     case TYCHAR:
22143203Sbostic       if ( !ftn66flag && badvalue == 0 )
22243203Sbostic 	{
22343203Sbostic 	  badvalue = 1;
22443203Sbostic 	  warn(compat2);
22543203Sbostic 	}
22643203Sbostic 
22743203Sbostic     case TYHOLLERITH:
22843203Sbostic       shortp = (short *) grabbytes(2, cp);
22943203Sbostic       p = (expptr) mkconst(TYSHORT);
230*46301Sbostic       p->constblock.constant.ci = *shortp;
23143203Sbostic       free((char *) shortp);
23243203Sbostic       break;
23343203Sbostic 
23443203Sbostic     case TYERROR:
23543203Sbostic       p = errnode();
23643203Sbostic       break;
23743203Sbostic     }
23843203Sbostic 
23943203Sbostic   return (p);
24043203Sbostic }
24143203Sbostic 
24243203Sbostic 
24343203Sbostic 
24443203Sbostic LOCAL expptr
24543203Sbostic clong(cp)
24643203Sbostic Constp cp;
24743203Sbostic {
24843203Sbostic   static char *toobig = "data value too large";
24943203Sbostic   static char *reserved = "reserved operand assigned to an integer";
25043203Sbostic   static char *compat1 = "logical datum assigned to an integer variable";
25143203Sbostic   static char *compat2 = "character datum assigned to an integer variable";
25243203Sbostic 
25343203Sbostic   register expptr p;
25443203Sbostic   register ftnint *longp;
25543203Sbostic   register long *rp;
25643203Sbostic   register double *minp;
25743203Sbostic   register double *maxp;
25843203Sbostic   realvalue x;
25943203Sbostic 
26043203Sbostic   switch (cp->vtype)
26143203Sbostic     {
26243203Sbostic     case TYBITSTR:
26343203Sbostic       longp = (ftnint *) grabbits(4, cp);
26443203Sbostic       p = (expptr) mkconst(TYLONG);
265*46301Sbostic       p->constblock.constant.ci = *longp;
26643203Sbostic       free((char *) longp);
26743203Sbostic       break;
26843203Sbostic 
26943203Sbostic     case TYSHORT:
27043203Sbostic       p = (expptr) mkconst(TYLONG);
271*46301Sbostic       p->constblock.constant.ci = cp->constant.ci;
27243203Sbostic       break;
27343203Sbostic 
27443203Sbostic     case TYLONG:
27543203Sbostic       p = (expptr) cpexpr(cp);
27643203Sbostic       break;
27743203Sbostic 
27843203Sbostic     case TYREAL:
27943203Sbostic     case TYDREAL:
28043203Sbostic     case TYCOMPLEX:
28143203Sbostic     case TYDCOMPLEX:
28243203Sbostic       minp = (double *) dminint;
28343203Sbostic       maxp = (double *) dmaxint;
284*46301Sbostic       rp = (long *) &(cp->constant.cd[0]);
28543203Sbostic       x.q.word1 = rp[0];
28643203Sbostic       x.q.word2 = rp[1];
28743203Sbostic       if (x.f.sign == 1 && x.f.exp == 0)
28843203Sbostic 	{
28943203Sbostic 	  if (badvalue <= 1)
29043203Sbostic 	    {
29143203Sbostic 	      badvalue = 2;
29243203Sbostic 	      err(reserved);
29343203Sbostic 	    }
29443203Sbostic 	  p = errnode();
29543203Sbostic 	}
29643203Sbostic       else if (x.d >= *minp && x.d <= *maxp)
29743203Sbostic 	{
29843203Sbostic 	  p = (expptr) mkconst(TYLONG);
299*46301Sbostic 	  p->constblock.constant.ci = x.d;
30043203Sbostic 	}
30143203Sbostic       else
30243203Sbostic 	{
30343203Sbostic 	  if (badvalue <= 1)
30443203Sbostic 	    {
30543203Sbostic 	      badvalue = 2;
30643203Sbostic 	      err(toobig);
30743203Sbostic 	    }
30843203Sbostic 	  p = errnode();
30943203Sbostic 	}
31043203Sbostic       break;
31143203Sbostic 
31243203Sbostic     case TYLOGICAL:
31343203Sbostic       if (badvalue <= 1)
31443203Sbostic 	{
31543203Sbostic 	  badvalue = 2;
31643203Sbostic 	  err(compat1);
31743203Sbostic 	}
31843203Sbostic       p = errnode();
31943203Sbostic       break;
32043203Sbostic 
32143203Sbostic     case TYCHAR:
32243203Sbostic       if ( !ftn66flag && badvalue == 0 )
32343203Sbostic 	{
32443203Sbostic 	  badvalue = 1;
32543203Sbostic 	  warn(compat2);
32643203Sbostic 	}
32743203Sbostic 
32843203Sbostic     case TYHOLLERITH:
32943203Sbostic       longp = (ftnint *) grabbytes(4, cp);
33043203Sbostic       p = (expptr) mkconst(TYLONG);
331*46301Sbostic       p->constblock.constant.ci = *longp;
33243203Sbostic       free((char *) longp);
33343203Sbostic       break;
33443203Sbostic 
33543203Sbostic     case TYERROR:
33643203Sbostic       p = errnode();
33743203Sbostic       break;
33843203Sbostic     }
33943203Sbostic 
34043203Sbostic   return (p);
34143203Sbostic }
34243203Sbostic 
34343203Sbostic 
34443203Sbostic 
34543203Sbostic LOCAL expptr
34643203Sbostic creal(cp)
34743203Sbostic Constp cp;
34843203Sbostic {
34943203Sbostic   static char *toobig = "data value too large";
35043203Sbostic   static char *compat1 = "logical datum assigned to a real variable";
35143203Sbostic   static char *compat2 = "character datum assigned to a real variable";
35243203Sbostic 
35343203Sbostic   register expptr p;
35443203Sbostic   register long *longp;
35543203Sbostic   register long *rp;
35643203Sbostic   register double *minp;
35743203Sbostic   register double *maxp;
35843203Sbostic   realvalue x;
35943203Sbostic   float y;
36043203Sbostic 
36143203Sbostic   switch (cp->vtype)
36243203Sbostic     {
36343203Sbostic     case TYBITSTR:
36443203Sbostic       longp = (long *) grabbits(4, cp);
36543203Sbostic       p = (expptr) mkconst(TYREAL);
366*46301Sbostic       rp = (long *) &(p->constblock.constant.cd[0]);
36743203Sbostic       rp[0] = *longp;
36843203Sbostic       free((char *) longp);
36943203Sbostic       break;
37043203Sbostic 
37143203Sbostic     case TYSHORT:
37243203Sbostic     case TYLONG:
37343203Sbostic       p = (expptr) mkconst(TYREAL);
374*46301Sbostic       p->constblock.constant.cd[0] = cp->constant.ci;
37543203Sbostic       break;
37643203Sbostic 
37743203Sbostic     case TYREAL:
37843203Sbostic     case TYDREAL:
37943203Sbostic     case TYCOMPLEX:
38043203Sbostic     case TYDCOMPLEX:
38143203Sbostic       minp = (double *) dminreal;
38243203Sbostic       maxp = (double *) dmaxreal;
383*46301Sbostic       rp = (long *) &(cp->constant.cd[0]);
38443203Sbostic       x.q.word1 = rp[0];
38543203Sbostic       x.q.word2 = rp[1];
38643203Sbostic       if (x.f.sign == 1 && x.f.exp == 0)
38743203Sbostic 	{
38843203Sbostic 	  p = (expptr) mkconst(TYREAL);
389*46301Sbostic 	  rp = (long *) &(p->constblock.constant.cd[0]);
39043203Sbostic 	  rp[0] = x.q.word1;
39143203Sbostic 	}
39243203Sbostic       else if (x.d >= *minp && x.d <= *maxp)
39343203Sbostic 	{
39443203Sbostic 	  p = (expptr) mkconst(TYREAL);
39543203Sbostic 	  y = x.d;
396*46301Sbostic 	  p->constblock.constant.cd[0] = y;
39743203Sbostic 	}
39843203Sbostic       else
39943203Sbostic 	{
40043203Sbostic 	  if (badvalue <= 1)
40143203Sbostic 	    {
40243203Sbostic 	      badvalue = 2;
40343203Sbostic 	      err(toobig);
40443203Sbostic 	    }
40543203Sbostic 	  p = errnode();
40643203Sbostic 	}
40743203Sbostic       break;
40843203Sbostic 
40943203Sbostic     case TYLOGICAL:
41043203Sbostic       if (badvalue <= 1)
41143203Sbostic 	{
41243203Sbostic 	  badvalue = 2;
41343203Sbostic 	  err(compat1);
41443203Sbostic 	}
41543203Sbostic       p = errnode();
41643203Sbostic       break;
41743203Sbostic 
41843203Sbostic     case TYCHAR:
41943203Sbostic       if ( !ftn66flag && badvalue == 0)
42043203Sbostic 	{
42143203Sbostic 	  badvalue = 1;
42243203Sbostic 	  warn(compat2);
42343203Sbostic 	}
42443203Sbostic 
42543203Sbostic     case TYHOLLERITH:
42643203Sbostic       longp = (long *) grabbytes(4, cp);
42743203Sbostic       p = (expptr) mkconst(TYREAL);
428*46301Sbostic       rp = (long *) &(p->constblock.constant.cd[0]);
42943203Sbostic       rp[0] = *longp;
43043203Sbostic       free((char *) longp);
43143203Sbostic       break;
43243203Sbostic 
43343203Sbostic     case TYERROR:
43443203Sbostic       p = errnode();
43543203Sbostic       break;
43643203Sbostic     }
43743203Sbostic 
43843203Sbostic   return (p);
43943203Sbostic }
44043203Sbostic 
44143203Sbostic 
44243203Sbostic 
44343203Sbostic LOCAL expptr
44443203Sbostic cdreal(cp)
44543203Sbostic Constp cp;
44643203Sbostic {
44743203Sbostic   static char *compat1 =
44843203Sbostic 	"logical datum assigned to a double precision variable";
44943203Sbostic   static char *compat2 =
45043203Sbostic 	"character datum assigned to a double precision variable";
45143203Sbostic 
45243203Sbostic   register expptr p;
45343203Sbostic   register long *longp;
45443203Sbostic   register long *rp;
45543203Sbostic 
45643203Sbostic   switch (cp->vtype)
45743203Sbostic     {
45843203Sbostic     case TYBITSTR:
45943203Sbostic       longp = (long *) grabbits(8, cp);
46043203Sbostic       p = (expptr) mkconst(TYDREAL);
461*46301Sbostic       rp = (long *) &(p->constblock.constant.cd[0]);
46243203Sbostic       rp[0] = longp[0];
46343203Sbostic       rp[1] = longp[1];
46443203Sbostic       free((char *) longp);
46543203Sbostic       break;
46643203Sbostic 
46743203Sbostic     case TYSHORT:
46843203Sbostic     case TYLONG:
46943203Sbostic       p = (expptr) mkconst(TYDREAL);
470*46301Sbostic       p->constblock.constant.cd[0] = cp->constant.ci;
47143203Sbostic       break;
47243203Sbostic 
47343203Sbostic     case TYREAL:
47443203Sbostic     case TYDREAL:
47543203Sbostic     case TYCOMPLEX:
47643203Sbostic     case TYDCOMPLEX:
47743203Sbostic       p = (expptr) mkconst(TYDREAL);
478*46301Sbostic       longp = (long *) &(cp->constant.cd[0]);
479*46301Sbostic       rp = (long *) &(p->constblock.constant.cd[0]);
48043203Sbostic       rp[0] = longp[0];
48143203Sbostic       rp[1] = longp[1];
48243203Sbostic       break;
48343203Sbostic 
48443203Sbostic     case TYLOGICAL:
48543203Sbostic       if (badvalue <= 1)
48643203Sbostic 	{
48743203Sbostic 	  badvalue = 2;
48843203Sbostic 	  err(compat1);
48943203Sbostic 	}
49043203Sbostic       p = errnode();
49143203Sbostic       break;
49243203Sbostic 
49343203Sbostic     case TYCHAR:
49443203Sbostic       if ( !ftn66flag && badvalue == 0 )
49543203Sbostic 	{
49643203Sbostic 	  badvalue = 1;
49743203Sbostic 	  warn(compat2);
49843203Sbostic 	}
49943203Sbostic 
50043203Sbostic     case TYHOLLERITH:
50143203Sbostic       longp = (long *) grabbytes(8, cp);
50243203Sbostic       p = (expptr) mkconst(TYDREAL);
503*46301Sbostic       rp = (long *) &(p->constblock.constant.cd[0]);
50443203Sbostic       rp[0] = longp[0];
50543203Sbostic       rp[1] = longp[1];
50643203Sbostic       free((char *) longp);
50743203Sbostic       break;
50843203Sbostic 
50943203Sbostic     case TYERROR:
51043203Sbostic       p = errnode();
51143203Sbostic       break;
51243203Sbostic     }
51343203Sbostic 
51443203Sbostic   return (p);
51543203Sbostic }
51643203Sbostic 
51743203Sbostic 
51843203Sbostic 
51943203Sbostic LOCAL expptr
52043203Sbostic ccomplex(cp)
52143203Sbostic Constp cp;
52243203Sbostic {
52343203Sbostic   static char *toobig = "data value too large";
52443203Sbostic   static char *compat1 = "logical datum assigned to a complex variable";
52543203Sbostic   static char *compat2 = "character datum assigned to a complex variable";
52643203Sbostic 
52743203Sbostic   register expptr p;
52843203Sbostic   register long *longp;
52943203Sbostic   register long *rp;
53043203Sbostic   register double *minp;
53143203Sbostic   register double *maxp;
53243203Sbostic   realvalue re, im;
53343203Sbostic   int overflow;
53443203Sbostic   float x;
53543203Sbostic 
53643203Sbostic   switch (cp->vtype)
53743203Sbostic     {
53843203Sbostic     case TYBITSTR:
53943203Sbostic       longp = (long *) grabbits(8, cp);
54043203Sbostic       p = (expptr) mkconst(TYCOMPLEX);
541*46301Sbostic       rp = (long *) &(p->constblock.constant.cd[0]);
54243203Sbostic       rp[0] = longp[0];
54343203Sbostic       rp[2] = longp[1];
54443203Sbostic       free((char *) longp);
54543203Sbostic       break;
54643203Sbostic 
54743203Sbostic     case TYSHORT:
54843203Sbostic     case TYLONG:
54943203Sbostic       p = (expptr) mkconst(TYCOMPLEX);
550*46301Sbostic       p->constblock.constant.cd[0] = cp->constant.ci;
55143203Sbostic       break;
55243203Sbostic 
55343203Sbostic     case TYREAL:
55443203Sbostic     case TYDREAL:
55543203Sbostic     case TYCOMPLEX:
55643203Sbostic     case TYDCOMPLEX:
55743203Sbostic       overflow = 0;
55843203Sbostic       minp = (double *) dminreal;
55943203Sbostic       maxp = (double *) dmaxreal;
560*46301Sbostic       rp = (long *) &(cp->constant.cd[0]);
56143203Sbostic       re.q.word1 = rp[0];
56243203Sbostic       re.q.word2 = rp[1];
56343203Sbostic       im.q.word1 = rp[2];
56443203Sbostic       im.q.word2 = rp[3];
56543203Sbostic       if (((re.f.sign == 0 || re.f.exp != 0) &&
56643203Sbostic 	   (re.d < *minp || re.d > *maxp))       ||
56743203Sbostic 	  ((im.f.sign == 0 || re.f.exp != 0) &&
56843203Sbostic 	   (im.d < *minp || re.d > *maxp)))
56943203Sbostic 	{
57043203Sbostic 	  if (badvalue <= 1)
57143203Sbostic 	    {
57243203Sbostic 	      badvalue = 2;
57343203Sbostic 	      err(toobig);
57443203Sbostic 	    }
57543203Sbostic 	  p = errnode();
57643203Sbostic 	}
57743203Sbostic       else
57843203Sbostic 	{
57943203Sbostic 	  p = (expptr) mkconst(TYCOMPLEX);
58043203Sbostic 	  if (re.f.sign == 1 && re.f.exp == 0)
58143203Sbostic 	    re.q.word2 = 0;
58243203Sbostic 	  else
58343203Sbostic 	    {
58443203Sbostic 	      x = re.d;
58543203Sbostic 	      re.d = x;
58643203Sbostic 	    }
58743203Sbostic 	  if (im.f.sign == 1 && im.f.exp == 0)
58843203Sbostic 	    im.q.word2 = 0;
58943203Sbostic 	  else
59043203Sbostic 	    {
59143203Sbostic 	      x = im.d;
59243203Sbostic 	      im.d = x;
59343203Sbostic 	    }
594*46301Sbostic 	  rp = (long *) &(p->constblock.constant.cd[0]);
59543203Sbostic 	  rp[0] = re.q.word1;
59643203Sbostic 	  rp[1] = re.q.word2;
59743203Sbostic 	  rp[2] = im.q.word1;
59843203Sbostic 	  rp[3] = im.q.word2;
59943203Sbostic 	}
60043203Sbostic       break;
60143203Sbostic 
60243203Sbostic     case TYLOGICAL:
60343203Sbostic       if (badvalue <= 1)
60443203Sbostic 	{
60543203Sbostic 	  badvalue = 2;
60643203Sbostic 	  err(compat1);
60743203Sbostic 	}
60843203Sbostic       break;
60943203Sbostic 
61043203Sbostic     case TYCHAR:
61143203Sbostic       if ( !ftn66flag && badvalue == 0)
61243203Sbostic 	{
61343203Sbostic 	  badvalue = 1;
61443203Sbostic 	  warn(compat2);
61543203Sbostic 	}
61643203Sbostic 
61743203Sbostic     case TYHOLLERITH:
61843203Sbostic       longp = (long *) grabbytes(8, cp);
61943203Sbostic       p = (expptr) mkconst(TYCOMPLEX);
620*46301Sbostic       rp = (long *) &(p->constblock.constant.cd[0]);
62143203Sbostic       rp[0] = longp[0];
62243203Sbostic       rp[2] = longp[1];
62343203Sbostic       free((char *) longp);
62443203Sbostic       break;
62543203Sbostic 
62643203Sbostic     case TYERROR:
62743203Sbostic       p = errnode();
62843203Sbostic       break;
62943203Sbostic     }
63043203Sbostic 
63143203Sbostic   return (p);
63243203Sbostic }
63343203Sbostic 
63443203Sbostic 
63543203Sbostic 
63643203Sbostic LOCAL expptr
63743203Sbostic cdcomplex(cp)
63843203Sbostic Constp cp;
63943203Sbostic {
64043203Sbostic   static char *compat1 = "logical datum assigned to a complex variable";
64143203Sbostic   static char *compat2 = "character datum assigned to a complex variable";
64243203Sbostic 
64343203Sbostic   register expptr p;
64443203Sbostic   register long *longp;
64543203Sbostic   register long *rp;
64643203Sbostic 
64743203Sbostic   switch (cp->vtype)
64843203Sbostic     {
64943203Sbostic     case TYBITSTR:
65043203Sbostic       longp = (long *) grabbits(16, cp);
65143203Sbostic       p = (expptr) mkconst(TYDCOMPLEX);
652*46301Sbostic       rp = (long *) &(p->constblock.constant.cd[0]);
65343203Sbostic       rp[0] = longp[0];
65443203Sbostic       rp[1] = longp[1];
65543203Sbostic       rp[2] = longp[2];
65643203Sbostic       rp[3] = longp[3];
65743203Sbostic       free((char *) longp);
65843203Sbostic       break;
65943203Sbostic 
66043203Sbostic     case TYSHORT:
66143203Sbostic     case TYLONG:
66243203Sbostic       p = (expptr) mkconst(TYDCOMPLEX);
663*46301Sbostic       p->constblock.constant.cd[0] = cp->constant.ci;
66443203Sbostic       break;
66543203Sbostic 
66643203Sbostic     case TYREAL:
66743203Sbostic     case TYDREAL:
66843203Sbostic     case TYCOMPLEX:
66943203Sbostic     case TYDCOMPLEX:
67043203Sbostic       p = (expptr) mkconst(TYDCOMPLEX);
671*46301Sbostic       longp = (long *) &(cp->constant.cd[0]);
672*46301Sbostic       rp = (long *) &(p->constblock.constant.cd[0]);
67343203Sbostic       rp[0] = longp[0];
67443203Sbostic       rp[1] = longp[1];
67543203Sbostic       rp[2] = longp[2];
67643203Sbostic       rp[3] = longp[3];
67743203Sbostic       break;
67843203Sbostic 
67943203Sbostic     case TYLOGICAL:
68043203Sbostic       if (badvalue <= 1)
68143203Sbostic 	{
68243203Sbostic 	  badvalue = 2;
68343203Sbostic 	  err(compat1);
68443203Sbostic 	}
68543203Sbostic       p = errnode();
68643203Sbostic       break;
68743203Sbostic 
68843203Sbostic     case TYCHAR:
68943203Sbostic       if ( !ftn66flag && badvalue == 0 )
69043203Sbostic 	{
69143203Sbostic 	  badvalue = 1;
69243203Sbostic 	  warn(compat2);
69343203Sbostic 	}
69443203Sbostic 
69543203Sbostic     case TYHOLLERITH:
69643203Sbostic       longp = (long *) grabbytes(16, cp);
69743203Sbostic       p = (expptr) mkconst(TYDCOMPLEX);
698*46301Sbostic       rp = (long *) &(p->constblock.constant.cd[0]);
69943203Sbostic       rp[0] = longp[0];
70043203Sbostic       rp[1] = longp[1];
70143203Sbostic       rp[2] = longp[2];
70243203Sbostic       rp[3] = longp[3];
70343203Sbostic       free((char *) longp);
70443203Sbostic       break;
70543203Sbostic 
70643203Sbostic     case TYERROR:
70743203Sbostic       p = errnode();
70843203Sbostic       break;
70943203Sbostic     }
71043203Sbostic 
71143203Sbostic   return (p);
71243203Sbostic }
71343203Sbostic 
71443203Sbostic 
71543203Sbostic 
71643203Sbostic LOCAL expptr
71743203Sbostic clogical(cp)
71843203Sbostic Constp cp;
71943203Sbostic {
72043203Sbostic   static char *compat1 = "numeric datum assigned to a logical variable";
72143203Sbostic   static char *compat2 = "character datum assigned to a logical variable";
72243203Sbostic 
72343203Sbostic   register expptr p;
72443203Sbostic   register long *longp;
72543203Sbostic   register short *shortp;
72643203Sbostic   register int size;
72743203Sbostic 
72843203Sbostic   size = typesize[tylogical];
72943203Sbostic 
73043203Sbostic   switch (cp->vtype)
73143203Sbostic     {
73243203Sbostic     case TYBITSTR:
73343203Sbostic       p = (expptr) mkconst(tylogical);
73443203Sbostic       if (tylogical == TYSHORT)
73543203Sbostic 	{
73643203Sbostic 	  shortp = (short *) grabbits(size, cp);
737*46301Sbostic 	  p->constblock.constant.ci = (int) *shortp;
73843203Sbostic 	  free((char *) shortp);
73943203Sbostic 	}
74043203Sbostic       else
74143203Sbostic 	{
74243203Sbostic 	  longp = (long *) grabbits(size, cp);
743*46301Sbostic 	  p->constblock.constant.ci = *longp;
74443203Sbostic 	  free((char *) longp);
74543203Sbostic 	}
74643203Sbostic       break;
74743203Sbostic 
74843203Sbostic     case TYSHORT:
74943203Sbostic     case TYLONG:
75043203Sbostic     case TYREAL:
75143203Sbostic     case TYDREAL:
75243203Sbostic     case TYCOMPLEX:
75343203Sbostic     case TYDCOMPLEX:
75443203Sbostic       if (badvalue <= 1)
75543203Sbostic 	{
75643203Sbostic 	  badvalue = 2;
75743203Sbostic 	  err(compat1);
75843203Sbostic 	}
75943203Sbostic       p = errnode();
76043203Sbostic       break;
76143203Sbostic 
76243203Sbostic     case TYLOGICAL:
76343203Sbostic       p = (expptr) cpexpr(cp);
76443203Sbostic       p->constblock.vtype = tylogical;
76543203Sbostic       break;
76643203Sbostic 
76743203Sbostic     case TYCHAR:
76843203Sbostic       if ( !ftn66flag && badvalue == 0 )
76943203Sbostic 	{
77043203Sbostic 	  badvalue = 1;
77143203Sbostic 	  warn(compat2);
77243203Sbostic 	}
77343203Sbostic 
77443203Sbostic     case TYHOLLERITH:
77543203Sbostic       p = (expptr) mkconst(tylogical);
77643203Sbostic       if (tylogical == TYSHORT)
77743203Sbostic 	{
77843203Sbostic 	  shortp = (short *) grabbytes(size, cp);
779*46301Sbostic 	  p->constblock.constant.ci = (int) *shortp;
78043203Sbostic 	  free((char *) shortp);
78143203Sbostic 	}
78243203Sbostic       else
78343203Sbostic 	{
78443203Sbostic 	  longp = (long *) grabbytes(4, cp);
785*46301Sbostic 	  p->constblock.constant.ci = *longp;
78643203Sbostic 	  free((char *) longp);
78743203Sbostic 	}
78843203Sbostic       break;
78943203Sbostic 
79043203Sbostic     case TYERROR:
79143203Sbostic       p = errnode();
79243203Sbostic       break;
79343203Sbostic     }
79443203Sbostic 
79543203Sbostic   return (p);
79643203Sbostic }
79743203Sbostic 
79843203Sbostic 
79943203Sbostic 
80043203Sbostic LOCAL expptr
80143203Sbostic cchar(len, cp)
80243203Sbostic int len;
80343203Sbostic Constp cp;
80443203Sbostic {
80543203Sbostic   static char *compat1 = "numeric datum assigned to a character variable";
80643203Sbostic   static char *compat2 = "logical datum assigned to a character variable";
80743203Sbostic 
80843203Sbostic   register expptr p;
80943203Sbostic   register char *value;
81043203Sbostic 
81143203Sbostic   switch (cp->vtype)
81243203Sbostic     {
81343203Sbostic     case TYBITSTR:
81443203Sbostic       value = grabbits(len, cp);
81543203Sbostic       p = (expptr) mkstrcon(len, value);
81643203Sbostic       free(value);
81743203Sbostic       break;
81843203Sbostic 
81943203Sbostic     case TYSHORT:
82043203Sbostic     case TYLONG:
82143203Sbostic     case TYREAL:
82243203Sbostic     case TYDREAL:
82343203Sbostic     case TYCOMPLEX:
82443203Sbostic     case TYDCOMPLEX:
82543203Sbostic       if (badvalue <= 1)
82643203Sbostic 	{
82743203Sbostic 	  badvalue = 2;
82843203Sbostic 	  err(compat1);
82943203Sbostic 	}
83043203Sbostic       p = errnode();
83143203Sbostic       break;
83243203Sbostic 
83343203Sbostic     case TYLOGICAL:
83443203Sbostic       if (badvalue <= 1)
83543203Sbostic 	{
83643203Sbostic 	  badvalue = 2;
83743203Sbostic 	  err(compat2);
83843203Sbostic 	}
83943203Sbostic       p = errnode();
84043203Sbostic       break;
84143203Sbostic 
84243203Sbostic     case TYCHAR:
84343203Sbostic     case TYHOLLERITH:
84443203Sbostic       value = grabbytes(len, cp);
84543203Sbostic       p = (expptr) mkstrcon(len, value);
84643203Sbostic       free(value);
84743203Sbostic       break;
84843203Sbostic 
84943203Sbostic     case TYERROR:
85043203Sbostic       p = errnode();
85143203Sbostic       break;
85243203Sbostic     }
85343203Sbostic 
85443203Sbostic   return (p);
85543203Sbostic }
85643203Sbostic 
85743203Sbostic 
85843203Sbostic 
85943203Sbostic expptr
860*46301Sbostic convconst(type, len, constant)
86143203Sbostic int type;
86243203Sbostic int len;
863*46301Sbostic Constp constant;
86443203Sbostic {
86543203Sbostic   register expptr p;
86643203Sbostic 
86743203Sbostic   switch (type)
86843203Sbostic     {
86943203Sbostic     case TYSHORT:
870*46301Sbostic       p = cshort(constant);
87143203Sbostic       break;
87243203Sbostic 
87343203Sbostic     case TYLONG:
874*46301Sbostic       p = clong(constant);
87543203Sbostic       break;
87643203Sbostic 
87743203Sbostic     case TYREAL:
878*46301Sbostic       p = creal(constant);
87943203Sbostic       break;
88043203Sbostic 
88143203Sbostic     case TYDREAL:
882*46301Sbostic       p = cdreal(constant);
88343203Sbostic       break;
88443203Sbostic 
88543203Sbostic     case TYCOMPLEX:
886*46301Sbostic       p = ccomplex(constant);
88743203Sbostic       break;
88843203Sbostic 
88943203Sbostic     case TYDCOMPLEX:
890*46301Sbostic       p = cdcomplex(constant);
89143203Sbostic       break;
89243203Sbostic 
89343203Sbostic     case TYLOGICAL:
894*46301Sbostic       p = clogical(constant);
89543203Sbostic       break;
89643203Sbostic 
89743203Sbostic     case TYCHAR:
898*46301Sbostic       p = cchar(len, constant);
89943203Sbostic       break;
90043203Sbostic 
90143203Sbostic     case TYERROR:
90243203Sbostic     case TYUNKNOWN:
90343203Sbostic       p = errnode();
90443203Sbostic       break;
90543203Sbostic 
90643203Sbostic     default:
90743203Sbostic       badtype("convconst", type);
90843203Sbostic     }
90943203Sbostic 
91043203Sbostic   return (p);
91143203Sbostic }
912