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