xref: /csrg-svn/usr.bin/f77/pass1.vax/conv.c (revision 22800)
1*22800Smckusick /*
2*22800Smckusick  * Copyright (c) 1980 Regents of the University of California.
3*22800Smckusick  * All rights reserved.  The Berkeley software License Agreement
4*22800Smckusick  * specifies the terms and conditions for redistribution.
5*22800Smckusick  */
6*22800Smckusick 
7*22800Smckusick #ifndef lint
8*22800Smckusick static char sccsid[] = "@(#)conv.c	5.1 (Berkeley) 06/07/85";
9*22800Smckusick #endif not lint
10*22800Smckusick 
11*22800Smckusick /*
12*22800Smckusick  * conv.c
13*22800Smckusick  *
14*22800Smckusick  * Routines for type conversions, f77 compiler pass 1.
15*22800Smckusick  *
16*22800Smckusick  * University of Utah CS Dept modification history:
17*22800Smckusick  *
18*22800Smckusick  * $Log:	conv.c,v $
19*22800Smckusick  * Revision 2.2  85/06/07  21:09:29  root
20*22800Smckusick  * Add copyright
21*22800Smckusick  *
22*22800Smckusick  * Revision 2.1  84/07/19  12:02:29  donn
23*22800Smckusick  * Changed comment headers for UofU.
24*22800Smckusick  *
25*22800Smckusick  * Revision 1.2  84/04/13  01:07:02  donn
26*22800Smckusick  * Fixed value of dminreal to be -1.7e38 + epsilon instead of -2.59e33, per
27*22800Smckusick  * Bob Corbett's approval.
28*22800Smckusick  *
29*22800Smckusick  */
30*22800Smckusick 
31*22800Smckusick #include "defs.h"
32*22800Smckusick #include "conv.h"
33*22800Smckusick 
34*22800Smckusick int badvalue;
35*22800Smckusick 
36*22800Smckusick 
37*22800Smckusick /*  The following constants are used to check the limits of  */
38*22800Smckusick /*  conversions.  Dmaxword is the largest double precision   */
39*22800Smckusick /*  number which can be converted to a two-byte integer      */
40*22800Smckusick /*  without overflow.  Dminword is the smallest double       */
41*22800Smckusick /*  precision value which can be converted to a two-byte     */
42*22800Smckusick /*  integer without overflow.  Dmaxint and dminint are the   */
43*22800Smckusick /*  analogous values for four-byte integers.                 */
44*22800Smckusick 
45*22800Smckusick 
46*22800Smckusick LOCAL long dmaxword[] = { 0xfeff47ff, 0xffffffff };
47*22800Smckusick LOCAL long dminword[] = { 0x00ffc800, 0xffffffff };
48*22800Smckusick 
49*22800Smckusick LOCAL long dmaxint[]  = { 0xffff4fff, 0xfffffeff };
50*22800Smckusick LOCAL long dminint[]  = { 0x0000d000, 0xffff00ff };
51*22800Smckusick 
52*22800Smckusick LOCAL long dmaxreal[] = { 0xffff7fff, 0xffff7fff };
53*22800Smckusick LOCAL long dminreal[] = { 0xffffffff, 0xffff7fff };
54*22800Smckusick 
55*22800Smckusick 
56*22800Smckusick 
57*22800Smckusick /*  The routines which follow are used to convert  */
58*22800Smckusick /*  constants into constants of other types.       */
59*22800Smckusick 
60*22800Smckusick LOCAL char *
61*22800Smckusick grabbits(len, cp)
62*22800Smckusick int len;
63*22800Smckusick Constp cp;
64*22800Smckusick {
65*22800Smckusick 
66*22800Smckusick   static char *toobig = "bit value too large";
67*22800Smckusick 
68*22800Smckusick   register char *p;
69*22800Smckusick   register char *bits;
70*22800Smckusick   register int i;
71*22800Smckusick   register int k;
72*22800Smckusick   register int lenb;
73*22800Smckusick 
74*22800Smckusick   bits = cp->const.ccp;
75*22800Smckusick   lenb = cp->vleng->constblock.const.ci;
76*22800Smckusick 
77*22800Smckusick   p = (char *) ckalloc(len);
78*22800Smckusick 
79*22800Smckusick   if (len >= lenb)
80*22800Smckusick     k = lenb;
81*22800Smckusick   else
82*22800Smckusick     {
83*22800Smckusick       k = len;
84*22800Smckusick       if ( badvalue == 0 )
85*22800Smckusick 	{
86*22800Smckusick #if (TARGET == PDP11 || TARGET == VAX)
87*22800Smckusick 	  i = len;
88*22800Smckusick 	  while ( i < lenb && bits[i] == 0 )
89*22800Smckusick 	    i++;
90*22800Smckusick 	  if (i < lenb)
91*22800Smckusick 	    badvalue = 1;
92*22800Smckusick #else
93*22800Smckusick 	  i = lenb - len - 1;
94*22800Smckusick 	  while ( i >= 0 && bits[i] == 0)
95*22800Smckusick 	    i--;
96*22800Smckusick 	  if (i >= 0)
97*22800Smckusick 	    badvalue = 1;
98*22800Smckusick #endif
99*22800Smckusick 	  if (badvalue)
100*22800Smckusick 	    warn(toobig);
101*22800Smckusick 	}
102*22800Smckusick     }
103*22800Smckusick 
104*22800Smckusick #if (TARGET == PDP11 || TARGET == VAX)
105*22800Smckusick   i = 0;
106*22800Smckusick   while (i < k)
107*22800Smckusick     {
108*22800Smckusick       p[i] = bits[i];
109*22800Smckusick       i++;
110*22800Smckusick     }
111*22800Smckusick #else
112*22800Smckusick   i = lenb;
113*22800Smckusick   while (k > 0)
114*22800Smckusick     p[--k] = bits[--i];
115*22800Smckusick #endif
116*22800Smckusick 
117*22800Smckusick   return (p);
118*22800Smckusick }
119*22800Smckusick 
120*22800Smckusick 
121*22800Smckusick 
122*22800Smckusick LOCAL char *
123*22800Smckusick grabbytes(len, cp)
124*22800Smckusick int len;
125*22800Smckusick Constp cp;
126*22800Smckusick {
127*22800Smckusick   register char *p;
128*22800Smckusick   register char *bytes;
129*22800Smckusick   register int i;
130*22800Smckusick   register int k;
131*22800Smckusick   register int lenb;
132*22800Smckusick 
133*22800Smckusick   bytes = cp->const.ccp;
134*22800Smckusick   lenb = cp->vleng->constblock.const.ci;
135*22800Smckusick 
136*22800Smckusick   p = (char *) ckalloc(len);
137*22800Smckusick 
138*22800Smckusick   if (len >= lenb)
139*22800Smckusick     k = lenb;
140*22800Smckusick   else
141*22800Smckusick     k = len;
142*22800Smckusick 
143*22800Smckusick   i = 0;
144*22800Smckusick   while (i < k)
145*22800Smckusick     {
146*22800Smckusick       p[i] = bytes[i];
147*22800Smckusick       i++;
148*22800Smckusick     }
149*22800Smckusick 
150*22800Smckusick   while (i < len)
151*22800Smckusick     p[i++] = BLANK;
152*22800Smckusick 
153*22800Smckusick   return (p);
154*22800Smckusick }
155*22800Smckusick 
156*22800Smckusick 
157*22800Smckusick 
158*22800Smckusick LOCAL expptr
159*22800Smckusick cshort(cp)
160*22800Smckusick Constp cp;
161*22800Smckusick {
162*22800Smckusick   static char *toobig = "data value too large";
163*22800Smckusick   static char *reserved = "reserved operand assigned to an integer";
164*22800Smckusick   static char *compat1 = "logical datum assigned to an integer variable";
165*22800Smckusick   static char *compat2 = "character datum assigned to an integer variable";
166*22800Smckusick 
167*22800Smckusick   register expptr p;
168*22800Smckusick   register short *shortp;
169*22800Smckusick   register ftnint value;
170*22800Smckusick   register long *rp;
171*22800Smckusick   register double *minp;
172*22800Smckusick   register double *maxp;
173*22800Smckusick   realvalue x;
174*22800Smckusick 
175*22800Smckusick   switch (cp->vtype)
176*22800Smckusick     {
177*22800Smckusick     case TYBITSTR:
178*22800Smckusick       shortp = (short *) grabbits(2, cp);
179*22800Smckusick       p = (expptr) mkconst(TYSHORT);
180*22800Smckusick       p->constblock.const.ci = *shortp;
181*22800Smckusick       free((char *) shortp);
182*22800Smckusick       break;
183*22800Smckusick 
184*22800Smckusick     case TYSHORT:
185*22800Smckusick       p = (expptr) cpexpr(cp);
186*22800Smckusick       break;
187*22800Smckusick 
188*22800Smckusick     case TYLONG:
189*22800Smckusick       value = cp->const.ci;
190*22800Smckusick       if (value >= MINWORD && value <= MAXWORD)
191*22800Smckusick 	{
192*22800Smckusick 	  p = (expptr) mkconst(TYSHORT);
193*22800Smckusick 	  p->constblock.const.ci = value;
194*22800Smckusick 	}
195*22800Smckusick       else
196*22800Smckusick 	{
197*22800Smckusick 	  if (badvalue <= 1)
198*22800Smckusick 	    {
199*22800Smckusick 	      badvalue = 2;
200*22800Smckusick 	      err(toobig);
201*22800Smckusick 	    }
202*22800Smckusick 	  p = errnode();
203*22800Smckusick 	}
204*22800Smckusick       break;
205*22800Smckusick 
206*22800Smckusick     case TYREAL:
207*22800Smckusick     case TYDREAL:
208*22800Smckusick     case TYCOMPLEX:
209*22800Smckusick     case TYDCOMPLEX:
210*22800Smckusick       minp = (double *) dminword;
211*22800Smckusick       maxp = (double *) dmaxword;
212*22800Smckusick       rp = (long *) &(cp->const.cd[0]);
213*22800Smckusick       x.q.word1 = rp[0];
214*22800Smckusick       x.q.word2 = rp[1];
215*22800Smckusick       if (x.f.sign == 1 && x.f.exp == 0)
216*22800Smckusick 	{
217*22800Smckusick 	  if (badvalue <= 1)
218*22800Smckusick 	    {
219*22800Smckusick 	      badvalue = 2;
220*22800Smckusick 	      err(reserved);
221*22800Smckusick 	    }
222*22800Smckusick 	  p = errnode();
223*22800Smckusick 	}
224*22800Smckusick       else if (x.d >= *minp && x.d <= *maxp)
225*22800Smckusick 	{
226*22800Smckusick 	  p = (expptr) mkconst(TYSHORT);
227*22800Smckusick 	  p->constblock.const.ci = x.d;
228*22800Smckusick 	}
229*22800Smckusick       else
230*22800Smckusick 	{
231*22800Smckusick 	  if (badvalue <= 1)
232*22800Smckusick 	    {
233*22800Smckusick 	      badvalue = 2;
234*22800Smckusick 	      err(toobig);
235*22800Smckusick 	    }
236*22800Smckusick 	  p = errnode();
237*22800Smckusick 	}
238*22800Smckusick       break;
239*22800Smckusick 
240*22800Smckusick     case TYLOGICAL:
241*22800Smckusick       if (badvalue <= 1)
242*22800Smckusick 	{
243*22800Smckusick 	  badvalue = 2;
244*22800Smckusick 	  err(compat1);
245*22800Smckusick 	}
246*22800Smckusick       p = errnode();
247*22800Smckusick       break;
248*22800Smckusick 
249*22800Smckusick     case TYCHAR:
250*22800Smckusick       if ( !ftn66flag && badvalue == 0 )
251*22800Smckusick 	{
252*22800Smckusick 	  badvalue = 1;
253*22800Smckusick 	  warn(compat2);
254*22800Smckusick 	}
255*22800Smckusick 
256*22800Smckusick     case TYHOLLERITH:
257*22800Smckusick       shortp = (short *) grabbytes(2, cp);
258*22800Smckusick       p = (expptr) mkconst(TYSHORT);
259*22800Smckusick       p->constblock.const.ci = *shortp;
260*22800Smckusick       free((char *) shortp);
261*22800Smckusick       break;
262*22800Smckusick 
263*22800Smckusick     case TYERROR:
264*22800Smckusick       p = errnode();
265*22800Smckusick       break;
266*22800Smckusick     }
267*22800Smckusick 
268*22800Smckusick   return (p);
269*22800Smckusick }
270*22800Smckusick 
271*22800Smckusick 
272*22800Smckusick 
273*22800Smckusick LOCAL expptr
274*22800Smckusick clong(cp)
275*22800Smckusick Constp cp;
276*22800Smckusick {
277*22800Smckusick   static char *toobig = "data value too large";
278*22800Smckusick   static char *reserved = "reserved operand assigned to an integer";
279*22800Smckusick   static char *compat1 = "logical datum assigned to an integer variable";
280*22800Smckusick   static char *compat2 = "character datum assigned to an integer variable";
281*22800Smckusick 
282*22800Smckusick   register expptr p;
283*22800Smckusick   register ftnint *longp;
284*22800Smckusick   register long *rp;
285*22800Smckusick   register double *minp;
286*22800Smckusick   register double *maxp;
287*22800Smckusick   realvalue x;
288*22800Smckusick 
289*22800Smckusick   switch (cp->vtype)
290*22800Smckusick     {
291*22800Smckusick     case TYBITSTR:
292*22800Smckusick       longp = (ftnint *) grabbits(4, cp);
293*22800Smckusick       p = (expptr) mkconst(TYLONG);
294*22800Smckusick       p->constblock.const.ci = *longp;
295*22800Smckusick       free((char *) longp);
296*22800Smckusick       break;
297*22800Smckusick 
298*22800Smckusick     case TYSHORT:
299*22800Smckusick       p = (expptr) mkconst(TYLONG);
300*22800Smckusick       p->constblock.const.ci = cp->const.ci;
301*22800Smckusick       break;
302*22800Smckusick 
303*22800Smckusick     case TYLONG:
304*22800Smckusick       p = (expptr) cpexpr(cp);
305*22800Smckusick       break;
306*22800Smckusick 
307*22800Smckusick     case TYREAL:
308*22800Smckusick     case TYDREAL:
309*22800Smckusick     case TYCOMPLEX:
310*22800Smckusick     case TYDCOMPLEX:
311*22800Smckusick       minp = (double *) dminint;
312*22800Smckusick       maxp = (double *) dmaxint;
313*22800Smckusick       rp = (long *) &(cp->const.cd[0]);
314*22800Smckusick       x.q.word1 = rp[0];
315*22800Smckusick       x.q.word2 = rp[1];
316*22800Smckusick       if (x.f.sign == 1 && x.f.exp == 0)
317*22800Smckusick 	{
318*22800Smckusick 	  if (badvalue <= 1)
319*22800Smckusick 	    {
320*22800Smckusick 	      badvalue = 2;
321*22800Smckusick 	      err(reserved);
322*22800Smckusick 	    }
323*22800Smckusick 	  p = errnode();
324*22800Smckusick 	}
325*22800Smckusick       else if (x.d >= *minp && x.d <= *maxp)
326*22800Smckusick 	{
327*22800Smckusick 	  p = (expptr) mkconst(TYLONG);
328*22800Smckusick 	  p->constblock.const.ci = x.d;
329*22800Smckusick 	}
330*22800Smckusick       else
331*22800Smckusick 	{
332*22800Smckusick 	  if (badvalue <= 1)
333*22800Smckusick 	    {
334*22800Smckusick 	      badvalue = 2;
335*22800Smckusick 	      err(toobig);
336*22800Smckusick 	    }
337*22800Smckusick 	  p = errnode();
338*22800Smckusick 	}
339*22800Smckusick       break;
340*22800Smckusick 
341*22800Smckusick     case TYLOGICAL:
342*22800Smckusick       if (badvalue <= 1)
343*22800Smckusick 	{
344*22800Smckusick 	  badvalue = 2;
345*22800Smckusick 	  err(compat1);
346*22800Smckusick 	}
347*22800Smckusick       p = errnode();
348*22800Smckusick       break;
349*22800Smckusick 
350*22800Smckusick     case TYCHAR:
351*22800Smckusick       if ( !ftn66flag && badvalue == 0 )
352*22800Smckusick 	{
353*22800Smckusick 	  badvalue = 1;
354*22800Smckusick 	  warn(compat2);
355*22800Smckusick 	}
356*22800Smckusick 
357*22800Smckusick     case TYHOLLERITH:
358*22800Smckusick       longp = (ftnint *) grabbytes(4, cp);
359*22800Smckusick       p = (expptr) mkconst(TYLONG);
360*22800Smckusick       p->constblock.const.ci = *longp;
361*22800Smckusick       free((char *) longp);
362*22800Smckusick       break;
363*22800Smckusick 
364*22800Smckusick     case TYERROR:
365*22800Smckusick       p = errnode();
366*22800Smckusick       break;
367*22800Smckusick     }
368*22800Smckusick 
369*22800Smckusick   return (p);
370*22800Smckusick }
371*22800Smckusick 
372*22800Smckusick 
373*22800Smckusick 
374*22800Smckusick LOCAL expptr
375*22800Smckusick creal(cp)
376*22800Smckusick Constp cp;
377*22800Smckusick {
378*22800Smckusick   static char *toobig = "data value too large";
379*22800Smckusick   static char *compat1 = "logical datum assigned to a real variable";
380*22800Smckusick   static char *compat2 = "character datum assigned to a real variable";
381*22800Smckusick 
382*22800Smckusick   register expptr p;
383*22800Smckusick   register long *longp;
384*22800Smckusick   register long *rp;
385*22800Smckusick   register double *minp;
386*22800Smckusick   register double *maxp;
387*22800Smckusick   realvalue x;
388*22800Smckusick   float y;
389*22800Smckusick 
390*22800Smckusick   switch (cp->vtype)
391*22800Smckusick     {
392*22800Smckusick     case TYBITSTR:
393*22800Smckusick       longp = (long *) grabbits(4, cp);
394*22800Smckusick       p = (expptr) mkconst(TYREAL);
395*22800Smckusick       rp = (long *) &(p->constblock.const.cd[0]);
396*22800Smckusick       rp[0] = *longp;
397*22800Smckusick       free((char *) longp);
398*22800Smckusick       break;
399*22800Smckusick 
400*22800Smckusick     case TYSHORT:
401*22800Smckusick     case TYLONG:
402*22800Smckusick       p = (expptr) mkconst(TYREAL);
403*22800Smckusick       p->constblock.const.cd[0] = cp->const.ci;
404*22800Smckusick       break;
405*22800Smckusick 
406*22800Smckusick     case TYREAL:
407*22800Smckusick     case TYDREAL:
408*22800Smckusick     case TYCOMPLEX:
409*22800Smckusick     case TYDCOMPLEX:
410*22800Smckusick       minp = (double *) dminreal;
411*22800Smckusick       maxp = (double *) dmaxreal;
412*22800Smckusick       rp = (long *) &(cp->const.cd[0]);
413*22800Smckusick       x.q.word1 = rp[0];
414*22800Smckusick       x.q.word2 = rp[1];
415*22800Smckusick       if (x.f.sign == 1 && x.f.exp == 0)
416*22800Smckusick 	{
417*22800Smckusick 	  p = (expptr) mkconst(TYREAL);
418*22800Smckusick 	  rp = (long *) &(p->constblock.const.cd[0]);
419*22800Smckusick 	  rp[0] = x.q.word1;
420*22800Smckusick 	}
421*22800Smckusick       else if (x.d >= *minp && x.d <= *maxp)
422*22800Smckusick 	{
423*22800Smckusick 	  p = (expptr) mkconst(TYREAL);
424*22800Smckusick 	  y = x.d;
425*22800Smckusick 	  p->constblock.const.cd[0] = y;
426*22800Smckusick 	}
427*22800Smckusick       else
428*22800Smckusick 	{
429*22800Smckusick 	  if (badvalue <= 1)
430*22800Smckusick 	    {
431*22800Smckusick 	      badvalue = 2;
432*22800Smckusick 	      err(toobig);
433*22800Smckusick 	    }
434*22800Smckusick 	  p = errnode();
435*22800Smckusick 	}
436*22800Smckusick       break;
437*22800Smckusick 
438*22800Smckusick     case TYLOGICAL:
439*22800Smckusick       if (badvalue <= 1)
440*22800Smckusick 	{
441*22800Smckusick 	  badvalue = 2;
442*22800Smckusick 	  err(compat1);
443*22800Smckusick 	}
444*22800Smckusick       p = errnode();
445*22800Smckusick       break;
446*22800Smckusick 
447*22800Smckusick     case TYCHAR:
448*22800Smckusick       if ( !ftn66flag && badvalue == 0)
449*22800Smckusick 	{
450*22800Smckusick 	  badvalue = 1;
451*22800Smckusick 	  warn(compat2);
452*22800Smckusick 	}
453*22800Smckusick 
454*22800Smckusick     case TYHOLLERITH:
455*22800Smckusick       longp = (long *) grabbytes(4, cp);
456*22800Smckusick       p = (expptr) mkconst(TYREAL);
457*22800Smckusick       rp = (long *) &(p->constblock.const.cd[0]);
458*22800Smckusick       rp[0] = *longp;
459*22800Smckusick       free((char *) longp);
460*22800Smckusick       break;
461*22800Smckusick 
462*22800Smckusick     case TYERROR:
463*22800Smckusick       p = errnode();
464*22800Smckusick       break;
465*22800Smckusick     }
466*22800Smckusick 
467*22800Smckusick   return (p);
468*22800Smckusick }
469*22800Smckusick 
470*22800Smckusick 
471*22800Smckusick 
472*22800Smckusick LOCAL expptr
473*22800Smckusick cdreal(cp)
474*22800Smckusick Constp cp;
475*22800Smckusick {
476*22800Smckusick   static char *compat1 =
477*22800Smckusick 	"logical datum assigned to a double precision variable";
478*22800Smckusick   static char *compat2 =
479*22800Smckusick 	"character datum assigned to a double precision variable";
480*22800Smckusick 
481*22800Smckusick   register expptr p;
482*22800Smckusick   register long *longp;
483*22800Smckusick   register long *rp;
484*22800Smckusick 
485*22800Smckusick   switch (cp->vtype)
486*22800Smckusick     {
487*22800Smckusick     case TYBITSTR:
488*22800Smckusick       longp = (long *) grabbits(8, cp);
489*22800Smckusick       p = (expptr) mkconst(TYDREAL);
490*22800Smckusick       rp = (long *) &(p->constblock.const.cd[0]);
491*22800Smckusick       rp[0] = longp[0];
492*22800Smckusick       rp[1] = longp[1];
493*22800Smckusick       free((char *) longp);
494*22800Smckusick       break;
495*22800Smckusick 
496*22800Smckusick     case TYSHORT:
497*22800Smckusick     case TYLONG:
498*22800Smckusick       p = (expptr) mkconst(TYDREAL);
499*22800Smckusick       p->constblock.const.cd[0] = cp->const.ci;
500*22800Smckusick       break;
501*22800Smckusick 
502*22800Smckusick     case TYREAL:
503*22800Smckusick     case TYDREAL:
504*22800Smckusick     case TYCOMPLEX:
505*22800Smckusick     case TYDCOMPLEX:
506*22800Smckusick       p = (expptr) mkconst(TYDREAL);
507*22800Smckusick       longp = (long *) &(cp->const.cd[0]);
508*22800Smckusick       rp = (long *) &(p->constblock.const.cd[0]);
509*22800Smckusick       rp[0] = longp[0];
510*22800Smckusick       rp[1] = longp[1];
511*22800Smckusick       break;
512*22800Smckusick 
513*22800Smckusick     case TYLOGICAL:
514*22800Smckusick       if (badvalue <= 1)
515*22800Smckusick 	{
516*22800Smckusick 	  badvalue = 2;
517*22800Smckusick 	  err(compat1);
518*22800Smckusick 	}
519*22800Smckusick       p = errnode();
520*22800Smckusick       break;
521*22800Smckusick 
522*22800Smckusick     case TYCHAR:
523*22800Smckusick       if ( !ftn66flag && badvalue == 0 )
524*22800Smckusick 	{
525*22800Smckusick 	  badvalue = 1;
526*22800Smckusick 	  warn(compat2);
527*22800Smckusick 	}
528*22800Smckusick 
529*22800Smckusick     case TYHOLLERITH:
530*22800Smckusick       longp = (long *) grabbytes(8, cp);
531*22800Smckusick       p = (expptr) mkconst(TYDREAL);
532*22800Smckusick       rp = (long *) &(p->constblock.const.cd[0]);
533*22800Smckusick       rp[0] = longp[0];
534*22800Smckusick       rp[1] = longp[1];
535*22800Smckusick       free((char *) longp);
536*22800Smckusick       break;
537*22800Smckusick 
538*22800Smckusick     case TYERROR:
539*22800Smckusick       p = errnode();
540*22800Smckusick       break;
541*22800Smckusick     }
542*22800Smckusick 
543*22800Smckusick   return (p);
544*22800Smckusick }
545*22800Smckusick 
546*22800Smckusick 
547*22800Smckusick 
548*22800Smckusick LOCAL expptr
549*22800Smckusick ccomplex(cp)
550*22800Smckusick Constp cp;
551*22800Smckusick {
552*22800Smckusick   static char *toobig = "data value too large";
553*22800Smckusick   static char *compat1 = "logical datum assigned to a complex variable";
554*22800Smckusick   static char *compat2 = "character datum assigned to a complex variable";
555*22800Smckusick 
556*22800Smckusick   register expptr p;
557*22800Smckusick   register long *longp;
558*22800Smckusick   register long *rp;
559*22800Smckusick   register double *minp;
560*22800Smckusick   register double *maxp;
561*22800Smckusick   realvalue re, im;
562*22800Smckusick   int overflow;
563*22800Smckusick   float x;
564*22800Smckusick 
565*22800Smckusick   switch (cp->vtype)
566*22800Smckusick     {
567*22800Smckusick     case TYBITSTR:
568*22800Smckusick       longp = (long *) grabbits(8, cp);
569*22800Smckusick       p = (expptr) mkconst(TYCOMPLEX);
570*22800Smckusick       rp = (long *) &(p->constblock.const.cd[0]);
571*22800Smckusick       rp[0] = longp[0];
572*22800Smckusick       rp[2] = longp[1];
573*22800Smckusick       free((char *) longp);
574*22800Smckusick       break;
575*22800Smckusick 
576*22800Smckusick     case TYSHORT:
577*22800Smckusick     case TYLONG:
578*22800Smckusick       p = (expptr) mkconst(TYCOMPLEX);
579*22800Smckusick       p->constblock.const.cd[0] = cp->const.ci;
580*22800Smckusick       break;
581*22800Smckusick 
582*22800Smckusick     case TYREAL:
583*22800Smckusick     case TYDREAL:
584*22800Smckusick     case TYCOMPLEX:
585*22800Smckusick     case TYDCOMPLEX:
586*22800Smckusick       overflow = 0;
587*22800Smckusick       minp = (double *) dminreal;
588*22800Smckusick       maxp = (double *) dmaxreal;
589*22800Smckusick       rp = (long *) &(cp->const.cd[0]);
590*22800Smckusick       re.q.word1 = rp[0];
591*22800Smckusick       re.q.word2 = rp[1];
592*22800Smckusick       im.q.word1 = rp[2];
593*22800Smckusick       im.q.word2 = rp[3];
594*22800Smckusick       if (((re.f.sign == 0 || re.f.exp != 0) &&
595*22800Smckusick 	   (re.d < *minp || re.d > *maxp))       ||
596*22800Smckusick 	  ((im.f.sign == 0 || re.f.exp != 0) &&
597*22800Smckusick 	   (im.d < *minp || re.d > *maxp)))
598*22800Smckusick 	{
599*22800Smckusick 	  if (badvalue <= 1)
600*22800Smckusick 	    {
601*22800Smckusick 	      badvalue = 2;
602*22800Smckusick 	      err(toobig);
603*22800Smckusick 	    }
604*22800Smckusick 	  p = errnode();
605*22800Smckusick 	}
606*22800Smckusick       else
607*22800Smckusick 	{
608*22800Smckusick 	  p = (expptr) mkconst(TYCOMPLEX);
609*22800Smckusick 	  if (re.f.sign == 1 && re.f.exp == 0)
610*22800Smckusick 	    re.q.word2 = 0;
611*22800Smckusick 	  else
612*22800Smckusick 	    {
613*22800Smckusick 	      x = re.d;
614*22800Smckusick 	      re.d = x;
615*22800Smckusick 	    }
616*22800Smckusick 	  if (im.f.sign == 1 && im.f.exp == 0)
617*22800Smckusick 	    im.q.word2 = 0;
618*22800Smckusick 	  else
619*22800Smckusick 	    {
620*22800Smckusick 	      x = im.d;
621*22800Smckusick 	      im.d = x;
622*22800Smckusick 	    }
623*22800Smckusick 	  rp = (long *) &(p->constblock.const.cd[0]);
624*22800Smckusick 	  rp[0] = re.q.word1;
625*22800Smckusick 	  rp[1] = re.q.word2;
626*22800Smckusick 	  rp[2] = im.q.word1;
627*22800Smckusick 	  rp[3] = im.q.word2;
628*22800Smckusick 	}
629*22800Smckusick       break;
630*22800Smckusick 
631*22800Smckusick     case TYLOGICAL:
632*22800Smckusick       if (badvalue <= 1)
633*22800Smckusick 	{
634*22800Smckusick 	  badvalue = 2;
635*22800Smckusick 	  err(compat1);
636*22800Smckusick 	}
637*22800Smckusick       break;
638*22800Smckusick 
639*22800Smckusick     case TYCHAR:
640*22800Smckusick       if ( !ftn66flag && badvalue == 0)
641*22800Smckusick 	{
642*22800Smckusick 	  badvalue = 1;
643*22800Smckusick 	  warn(compat2);
644*22800Smckusick 	}
645*22800Smckusick 
646*22800Smckusick     case TYHOLLERITH:
647*22800Smckusick       longp = (long *) grabbytes(8, cp);
648*22800Smckusick       p = (expptr) mkconst(TYCOMPLEX);
649*22800Smckusick       rp = (long *) &(p->constblock.const.cd[0]);
650*22800Smckusick       rp[0] = longp[0];
651*22800Smckusick       rp[2] = longp[1];
652*22800Smckusick       free((char *) longp);
653*22800Smckusick       break;
654*22800Smckusick 
655*22800Smckusick     case TYERROR:
656*22800Smckusick       p = errnode();
657*22800Smckusick       break;
658*22800Smckusick     }
659*22800Smckusick 
660*22800Smckusick   return (p);
661*22800Smckusick }
662*22800Smckusick 
663*22800Smckusick 
664*22800Smckusick 
665*22800Smckusick LOCAL expptr
666*22800Smckusick cdcomplex(cp)
667*22800Smckusick Constp cp;
668*22800Smckusick {
669*22800Smckusick   static char *compat1 = "logical datum assigned to a complex variable";
670*22800Smckusick   static char *compat2 = "character datum assigned to a complex variable";
671*22800Smckusick 
672*22800Smckusick   register expptr p;
673*22800Smckusick   register long *longp;
674*22800Smckusick   register long *rp;
675*22800Smckusick 
676*22800Smckusick   switch (cp->vtype)
677*22800Smckusick     {
678*22800Smckusick     case TYBITSTR:
679*22800Smckusick       longp = (long *) grabbits(16, cp);
680*22800Smckusick       p = (expptr) mkconst(TYDCOMPLEX);
681*22800Smckusick       rp = (long *) &(p->constblock.const.cd[0]);
682*22800Smckusick       rp[0] = longp[0];
683*22800Smckusick       rp[1] = longp[1];
684*22800Smckusick       rp[2] = longp[2];
685*22800Smckusick       rp[3] = longp[3];
686*22800Smckusick       free((char *) longp);
687*22800Smckusick       break;
688*22800Smckusick 
689*22800Smckusick     case TYSHORT:
690*22800Smckusick     case TYLONG:
691*22800Smckusick       p = (expptr) mkconst(TYDCOMPLEX);
692*22800Smckusick       p->constblock.const.cd[0] = cp->const.ci;
693*22800Smckusick       break;
694*22800Smckusick 
695*22800Smckusick     case TYREAL:
696*22800Smckusick     case TYDREAL:
697*22800Smckusick     case TYCOMPLEX:
698*22800Smckusick     case TYDCOMPLEX:
699*22800Smckusick       p = (expptr) mkconst(TYDCOMPLEX);
700*22800Smckusick       longp = (long *) &(cp->const.cd[0]);
701*22800Smckusick       rp = (long *) &(p->constblock.const.cd[0]);
702*22800Smckusick       rp[0] = longp[0];
703*22800Smckusick       rp[1] = longp[1];
704*22800Smckusick       rp[2] = longp[2];
705*22800Smckusick       rp[3] = longp[3];
706*22800Smckusick       break;
707*22800Smckusick 
708*22800Smckusick     case TYLOGICAL:
709*22800Smckusick       if (badvalue <= 1)
710*22800Smckusick 	{
711*22800Smckusick 	  badvalue = 2;
712*22800Smckusick 	  err(compat1);
713*22800Smckusick 	}
714*22800Smckusick       p = errnode();
715*22800Smckusick       break;
716*22800Smckusick 
717*22800Smckusick     case TYCHAR:
718*22800Smckusick       if ( !ftn66flag && badvalue == 0 )
719*22800Smckusick 	{
720*22800Smckusick 	  badvalue = 1;
721*22800Smckusick 	  warn(compat2);
722*22800Smckusick 	}
723*22800Smckusick 
724*22800Smckusick     case TYHOLLERITH:
725*22800Smckusick       longp = (long *) grabbytes(16, cp);
726*22800Smckusick       p = (expptr) mkconst(TYDCOMPLEX);
727*22800Smckusick       rp = (long *) &(p->constblock.const.cd[0]);
728*22800Smckusick       rp[0] = longp[0];
729*22800Smckusick       rp[1] = longp[1];
730*22800Smckusick       rp[2] = longp[2];
731*22800Smckusick       rp[3] = longp[3];
732*22800Smckusick       free((char *) longp);
733*22800Smckusick       break;
734*22800Smckusick 
735*22800Smckusick     case TYERROR:
736*22800Smckusick       p = errnode();
737*22800Smckusick       break;
738*22800Smckusick     }
739*22800Smckusick 
740*22800Smckusick   return (p);
741*22800Smckusick }
742*22800Smckusick 
743*22800Smckusick 
744*22800Smckusick 
745*22800Smckusick LOCAL expptr
746*22800Smckusick clogical(cp)
747*22800Smckusick Constp cp;
748*22800Smckusick {
749*22800Smckusick   static char *compat1 = "numeric datum assigned to a logical variable";
750*22800Smckusick   static char *compat2 = "character datum assigned to a logical variable";
751*22800Smckusick 
752*22800Smckusick   register expptr p;
753*22800Smckusick   register long *longp;
754*22800Smckusick   register short *shortp;
755*22800Smckusick   register int size;
756*22800Smckusick 
757*22800Smckusick   size = typesize[tylogical];
758*22800Smckusick 
759*22800Smckusick   switch (cp->vtype)
760*22800Smckusick     {
761*22800Smckusick     case TYBITSTR:
762*22800Smckusick       p = (expptr) mkconst(tylogical);
763*22800Smckusick       if (tylogical == TYSHORT)
764*22800Smckusick 	{
765*22800Smckusick 	  shortp = (short *) grabbits(size, cp);
766*22800Smckusick 	  p->constblock.const.ci = (int) *shortp;
767*22800Smckusick 	  free((char *) shortp);
768*22800Smckusick 	}
769*22800Smckusick       else
770*22800Smckusick 	{
771*22800Smckusick 	  longp = (long *) grabbits(size, cp);
772*22800Smckusick 	  p->constblock.const.ci = *longp;
773*22800Smckusick 	  free((char *) longp);
774*22800Smckusick 	}
775*22800Smckusick       break;
776*22800Smckusick 
777*22800Smckusick     case TYSHORT:
778*22800Smckusick     case TYLONG:
779*22800Smckusick     case TYREAL:
780*22800Smckusick     case TYDREAL:
781*22800Smckusick     case TYCOMPLEX:
782*22800Smckusick     case TYDCOMPLEX:
783*22800Smckusick       if (badvalue <= 1)
784*22800Smckusick 	{
785*22800Smckusick 	  badvalue = 2;
786*22800Smckusick 	  err(compat1);
787*22800Smckusick 	}
788*22800Smckusick       p = errnode();
789*22800Smckusick       break;
790*22800Smckusick 
791*22800Smckusick     case TYLOGICAL:
792*22800Smckusick       p = (expptr) cpexpr(cp);
793*22800Smckusick       p->constblock.vtype = tylogical;
794*22800Smckusick       break;
795*22800Smckusick 
796*22800Smckusick     case TYCHAR:
797*22800Smckusick       if ( !ftn66flag && badvalue == 0 )
798*22800Smckusick 	{
799*22800Smckusick 	  badvalue = 1;
800*22800Smckusick 	  warn(compat2);
801*22800Smckusick 	}
802*22800Smckusick 
803*22800Smckusick     case TYHOLLERITH:
804*22800Smckusick       p = (expptr) mkconst(tylogical);
805*22800Smckusick       if (tylogical == TYSHORT)
806*22800Smckusick 	{
807*22800Smckusick 	  shortp = (short *) grabbytes(size, cp);
808*22800Smckusick 	  p->constblock.const.ci = (int) *shortp;
809*22800Smckusick 	  free((char *) shortp);
810*22800Smckusick 	}
811*22800Smckusick       else
812*22800Smckusick 	{
813*22800Smckusick 	  longp = (long *) grabbytes(4, cp);
814*22800Smckusick 	  p->constblock.const.ci = *longp;
815*22800Smckusick 	  free((char *) longp);
816*22800Smckusick 	}
817*22800Smckusick       break;
818*22800Smckusick 
819*22800Smckusick     case TYERROR:
820*22800Smckusick       p = errnode();
821*22800Smckusick       break;
822*22800Smckusick     }
823*22800Smckusick 
824*22800Smckusick   return (p);
825*22800Smckusick }
826*22800Smckusick 
827*22800Smckusick 
828*22800Smckusick 
829*22800Smckusick LOCAL expptr
830*22800Smckusick cchar(len, cp)
831*22800Smckusick int len;
832*22800Smckusick Constp cp;
833*22800Smckusick {
834*22800Smckusick   static char *compat1 = "numeric datum assigned to a character variable";
835*22800Smckusick   static char *compat2 = "logical datum assigned to a character variable";
836*22800Smckusick 
837*22800Smckusick   register expptr p;
838*22800Smckusick   register char *value;
839*22800Smckusick 
840*22800Smckusick   switch (cp->vtype)
841*22800Smckusick     {
842*22800Smckusick     case TYBITSTR:
843*22800Smckusick       value = grabbits(len, cp);
844*22800Smckusick       p = (expptr) mkstrcon(len, value);
845*22800Smckusick       free(value);
846*22800Smckusick       break;
847*22800Smckusick 
848*22800Smckusick     case TYSHORT:
849*22800Smckusick     case TYLONG:
850*22800Smckusick     case TYREAL:
851*22800Smckusick     case TYDREAL:
852*22800Smckusick     case TYCOMPLEX:
853*22800Smckusick     case TYDCOMPLEX:
854*22800Smckusick       if (badvalue <= 1)
855*22800Smckusick 	{
856*22800Smckusick 	  badvalue = 2;
857*22800Smckusick 	  err(compat1);
858*22800Smckusick 	}
859*22800Smckusick       p = errnode();
860*22800Smckusick       break;
861*22800Smckusick 
862*22800Smckusick     case TYLOGICAL:
863*22800Smckusick       if (badvalue <= 1)
864*22800Smckusick 	{
865*22800Smckusick 	  badvalue = 2;
866*22800Smckusick 	  err(compat2);
867*22800Smckusick 	}
868*22800Smckusick       p = errnode();
869*22800Smckusick       break;
870*22800Smckusick 
871*22800Smckusick     case TYCHAR:
872*22800Smckusick     case TYHOLLERITH:
873*22800Smckusick       value = grabbytes(len, cp);
874*22800Smckusick       p = (expptr) mkstrcon(len, value);
875*22800Smckusick       free(value);
876*22800Smckusick       break;
877*22800Smckusick 
878*22800Smckusick     case TYERROR:
879*22800Smckusick       p = errnode();
880*22800Smckusick       break;
881*22800Smckusick     }
882*22800Smckusick 
883*22800Smckusick   return (p);
884*22800Smckusick }
885*22800Smckusick 
886*22800Smckusick 
887*22800Smckusick 
888*22800Smckusick expptr
889*22800Smckusick convconst(type, len, const)
890*22800Smckusick int type;
891*22800Smckusick int len;
892*22800Smckusick Constp const;
893*22800Smckusick {
894*22800Smckusick   register expptr p;
895*22800Smckusick 
896*22800Smckusick   switch (type)
897*22800Smckusick     {
898*22800Smckusick     case TYSHORT:
899*22800Smckusick       p = cshort(const);
900*22800Smckusick       break;
901*22800Smckusick 
902*22800Smckusick     case TYLONG:
903*22800Smckusick       p = clong(const);
904*22800Smckusick       break;
905*22800Smckusick 
906*22800Smckusick     case TYREAL:
907*22800Smckusick       p = creal(const);
908*22800Smckusick       break;
909*22800Smckusick 
910*22800Smckusick     case TYDREAL:
911*22800Smckusick       p = cdreal(const);
912*22800Smckusick       break;
913*22800Smckusick 
914*22800Smckusick     case TYCOMPLEX:
915*22800Smckusick       p = ccomplex(const);
916*22800Smckusick       break;
917*22800Smckusick 
918*22800Smckusick     case TYDCOMPLEX:
919*22800Smckusick       p = cdcomplex(const);
920*22800Smckusick       break;
921*22800Smckusick 
922*22800Smckusick     case TYLOGICAL:
923*22800Smckusick       p = clogical(const);
924*22800Smckusick       break;
925*22800Smckusick 
926*22800Smckusick     case TYCHAR:
927*22800Smckusick       p = cchar(len, const);
928*22800Smckusick       break;
929*22800Smckusick 
930*22800Smckusick     case TYERROR:
931*22800Smckusick     case TYUNKNOWN:
932*22800Smckusick       p = errnode();
933*22800Smckusick       break;
934*22800Smckusick 
935*22800Smckusick     default:
936*22800Smckusick       badtype("convconst", type);
937*22800Smckusick     }
938*22800Smckusick 
939*22800Smckusick   return (p);
940*22800Smckusick }
941