date and time created 90/06/17 18:08:09 by bostic
authorKeith Bostic <bostic@ucbvax.Berkeley.EDU>
Mon, 18 Jun 1990 09:08:09 +0000 (01:08 -0800)
committerKeith Bostic <bostic@ucbvax.Berkeley.EDU>
Mon, 18 Jun 1990 09:08:09 +0000 (01:08 -0800)
SCCS-vsn: usr.bin/f77/pass1.tahoe/conv.c 5.1

usr/src/usr.bin/f77/pass1.tahoe/conv.c [new file with mode: 0644]

diff --git a/usr/src/usr.bin/f77/pass1.tahoe/conv.c b/usr/src/usr.bin/f77/pass1.tahoe/conv.c
new file mode 100644 (file)
index 0000000..4a17631
--- /dev/null
@@ -0,0 +1,911 @@
+#include "defs.h"
+#include "conv.h"
+
+int badvalue;
+
+
+/*  The following constants are used to check the limits of  */
+/*  conversions.  Dmaxword is the largest double precision   */
+/*  number which can be converted to a two-byte integer      */
+/*  without overflow.  Dminword is the smallest double       */
+/*  precision value which can be converted to a two-byte     */
+/*  integer without overflow.  Dmaxint and dminint are the   */
+/*  analogous values for four-byte integers.                 */
+
+/* short array should be correct for both VAX and TAHOE */
+
+LOCAL short dmaxword[] = { 0x47ff, 0xfeff, 0xffff, 0xffff }; /* 32767.5 */
+LOCAL short dminword[] = { 0xc800, 0x007f, 0xffff, 0xffff }; /* -32768.499999999999 */
+
+LOCAL short dmaxint[]  = { 0x4fff, 0xffff, 0xfeff, 0xffff }; /* 2147483647.5 */
+LOCAL short dminint[]  = { 0xd000, 0x0000, 0x007f, 0xffff }; /* -2147483648.4999999 */
+
+LOCAL short dmaxreal[] = { 0x7fff, 0xffff, 0x7fff, 0xffff }; /* 1.7014117838986683e+38 */
+LOCAL short dminreal[] = { 0xffff, 0xffff, 0x7fff, 0xffff }; /* -1.7014117838986683e+38 */
+
+\f
+
+/*  The routines which follow are used to convert  */
+/*  constants into constants of other types.       */
+
+LOCAL char *
+grabbits(len, cp)
+int len;
+Constp cp;
+{
+
+  static char *toobig = "bit value too large";
+
+  register char *p;
+  register char *bits;
+  register int i;
+  register int k;
+  register int lenb;
+
+  bits = cp->const.ccp;
+  lenb = cp->vleng->constblock.const.ci;
+
+  p = (char *) ckalloc(len);
+
+  if (len >= lenb)
+    k = lenb;
+  else
+    {
+      k = len;
+      if ( badvalue == 0 )
+       {
+#if (HERE == PDP11 || HERE == VAX)
+         i = len;
+         while ( i < lenb && bits[i] == 0 )
+           i++;
+         if (i < lenb)
+           badvalue = 1;
+#else
+         i = lenb - len - 1;
+         while ( i >= 0 && bits[i] == 0)
+           i--;
+         if (i >= 0)
+           badvalue = 1;
+#endif
+         if (badvalue)
+           warn(toobig);
+       }
+    }
+
+#if (HERE == PDP11 || HERE == VAX)
+  i = 0;
+  while (i < k)
+    {
+      p[i] = bits[i];
+      i++;
+    }
+#else
+  i = lenb;
+  while (k > 0)
+    p[--k] = bits[--i];
+#endif
+
+  return (p);
+}
+
+\f
+
+LOCAL char *
+grabbytes(len, cp)
+int len;
+Constp cp;
+{
+  register char *p;
+  register char *bytes;
+  register int i;
+  register int k;
+  register int lenb;
+
+  bytes = cp->const.ccp;
+  lenb = cp->vleng->constblock.const.ci;
+
+  p = (char *) ckalloc(len);
+
+  if (len >= lenb)
+    k = lenb;
+  else
+    k = len;
+
+  i = 0;
+  while (i < k)
+    {
+      p[i] = bytes[i];
+      i++;
+    }
+
+  while (i < len)
+    p[i++] = BLANK;
+
+  return (p);
+}
+
+\f
+
+LOCAL expptr
+cshort(cp)
+Constp cp;
+{
+  static char *toobig = "data value too large";
+  static char *reserved = "reserved operand assigned to an integer";
+  static char *compat1 = "logical datum assigned to an integer variable";
+  static char *compat2 = "character datum assigned to an integer variable";
+
+  register expptr p;
+  register short *shortp;
+  register ftnint value;
+  register long *rp;
+  register double *minp;
+  register double *maxp;
+  realvalue x;
+
+  switch (cp->vtype)
+    {
+    case TYBITSTR:
+      shortp = (short *) grabbits(2, cp);
+      p = (expptr) mkconst(TYSHORT);
+      p->constblock.const.ci = *shortp;
+      free((char *) shortp);
+      break;
+
+    case TYSHORT:
+      p = (expptr) cpexpr(cp);
+      break;
+
+    case TYLONG:
+      value = cp->const.ci;
+      if (value >= MINWORD && value <= MAXWORD)
+       {
+         p = (expptr) mkconst(TYSHORT);
+         p->constblock.const.ci = value;
+       }
+      else
+       {
+         if (badvalue <= 1)
+           {
+             badvalue = 2;
+             err(toobig);
+           }
+         p = errnode();
+       }
+      break;
+
+    case TYREAL:
+    case TYDREAL:
+    case TYCOMPLEX:
+    case TYDCOMPLEX:
+      minp = (double *) dminword;
+      maxp = (double *) dmaxword;
+      rp = (long *) &(cp->const.cd[0]);
+      x.q.word1 = rp[0];
+      x.q.word2 = rp[1];
+      if (x.f.sign == 1 && x.f.exp == 0)
+       {
+         if (badvalue <= 1)
+           {
+             badvalue = 2;
+             err(reserved);
+           }
+         p = errnode();
+       }
+      else if (x.d >= *minp && x.d <= *maxp)
+       {
+         p = (expptr) mkconst(TYSHORT);
+         p->constblock.const.ci = x.d;
+       }
+      else
+       {
+         if (badvalue <= 1)
+           {
+             badvalue = 2;
+             err(toobig);
+           }
+         p = errnode();
+       }
+      break;
+
+    case TYLOGICAL:
+      if (badvalue <= 1)
+       {
+         badvalue = 2;
+         err(compat1);
+       }
+      p = errnode();
+      break;
+
+    case TYCHAR:
+      if ( !ftn66flag && badvalue == 0 )
+       {
+         badvalue = 1;
+         warn(compat2);
+       }
+
+    case TYHOLLERITH:
+      shortp = (short *) grabbytes(2, cp);
+      p = (expptr) mkconst(TYSHORT);
+      p->constblock.const.ci = *shortp;
+      free((char *) shortp);
+      break;
+
+    case TYERROR:
+      p = errnode();
+      break;
+    }
+
+  return (p);
+}
+
+\f
+
+LOCAL expptr
+clong(cp)
+Constp cp;
+{
+  static char *toobig = "data value too large";
+  static char *reserved = "reserved operand assigned to an integer";
+  static char *compat1 = "logical datum assigned to an integer variable";
+  static char *compat2 = "character datum assigned to an integer variable";
+
+  register expptr p;
+  register ftnint *longp;
+  register long *rp;
+  register double *minp;
+  register double *maxp;
+  realvalue x;
+
+  switch (cp->vtype)
+    {
+    case TYBITSTR:
+      longp = (ftnint *) grabbits(4, cp);
+      p = (expptr) mkconst(TYLONG);
+      p->constblock.const.ci = *longp;
+      free((char *) longp);
+      break;
+
+    case TYSHORT:
+      p = (expptr) mkconst(TYLONG);
+      p->constblock.const.ci = cp->const.ci;
+      break;
+
+    case TYLONG:
+      p = (expptr) cpexpr(cp);
+      break;
+
+    case TYREAL:
+    case TYDREAL:
+    case TYCOMPLEX:
+    case TYDCOMPLEX:
+      minp = (double *) dminint;
+      maxp = (double *) dmaxint;
+      rp = (long *) &(cp->const.cd[0]);
+      x.q.word1 = rp[0];
+      x.q.word2 = rp[1];
+      if (x.f.sign == 1 && x.f.exp == 0)
+       {
+         if (badvalue <= 1)
+           {
+             badvalue = 2;
+             err(reserved);
+           }
+         p = errnode();
+       }
+      else if (x.d >= *minp && x.d <= *maxp)
+       {
+         p = (expptr) mkconst(TYLONG);
+         p->constblock.const.ci = x.d;
+       }
+      else
+       {
+         if (badvalue <= 1)
+           {
+             badvalue = 2;
+             err(toobig);
+           }
+         p = errnode();
+       }
+      break;
+
+    case TYLOGICAL:
+      if (badvalue <= 1)
+       {
+         badvalue = 2;
+         err(compat1);
+       }
+      p = errnode();
+      break;
+
+    case TYCHAR:
+      if ( !ftn66flag && badvalue == 0 )
+       {
+         badvalue = 1;
+         warn(compat2);
+       }
+
+    case TYHOLLERITH:
+      longp = (ftnint *) grabbytes(4, cp);
+      p = (expptr) mkconst(TYLONG);
+      p->constblock.const.ci = *longp;
+      free((char *) longp);
+      break;
+
+    case TYERROR:
+      p = errnode();
+      break;
+    }
+
+  return (p);
+}
+
+\f
+
+LOCAL expptr
+creal(cp)
+Constp cp;
+{
+  static char *toobig = "data value too large";
+  static char *compat1 = "logical datum assigned to a real variable";
+  static char *compat2 = "character datum assigned to a real variable";
+
+  register expptr p;
+  register long *longp;
+  register long *rp;
+  register double *minp;
+  register double *maxp;
+  realvalue x;
+  float y;
+
+  switch (cp->vtype)
+    {
+    case TYBITSTR:
+      longp = (long *) grabbits(4, cp);
+      p = (expptr) mkconst(TYREAL);
+      rp = (long *) &(p->constblock.const.cd[0]);
+      rp[0] = *longp;
+      free((char *) longp);
+      break;
+
+    case TYSHORT:
+    case TYLONG:
+      p = (expptr) mkconst(TYREAL);
+      p->constblock.const.cd[0] = cp->const.ci;
+      break;
+
+    case TYREAL:
+    case TYDREAL:
+    case TYCOMPLEX:
+    case TYDCOMPLEX:
+      minp = (double *) dminreal;
+      maxp = (double *) dmaxreal;
+      rp = (long *) &(cp->const.cd[0]);
+      x.q.word1 = rp[0];
+      x.q.word2 = rp[1];
+      if (x.f.sign == 1 && x.f.exp == 0)
+       {
+         p = (expptr) mkconst(TYREAL);
+         rp = (long *) &(p->constblock.const.cd[0]);
+         rp[0] = x.q.word1;
+       }
+      else if (x.d >= *minp && x.d <= *maxp)
+       {
+         p = (expptr) mkconst(TYREAL);
+         y = x.d;
+         p->constblock.const.cd[0] = y;
+       }
+      else
+       {
+         if (badvalue <= 1)
+           {
+             badvalue = 2;
+             err(toobig);
+           }
+         p = errnode();
+       }
+      break;
+
+    case TYLOGICAL:
+      if (badvalue <= 1)
+       {
+         badvalue = 2;
+         err(compat1);
+       }
+      p = errnode();
+      break;
+
+    case TYCHAR:
+      if ( !ftn66flag && badvalue == 0)
+       {
+         badvalue = 1;
+         warn(compat2);
+       }
+
+    case TYHOLLERITH:
+      longp = (long *) grabbytes(4, cp);
+      p = (expptr) mkconst(TYREAL);
+      rp = (long *) &(p->constblock.const.cd[0]);
+      rp[0] = *longp;
+      free((char *) longp);
+      break;
+
+    case TYERROR:
+      p = errnode();
+      break;
+    }
+
+  return (p);
+}
+
+\f
+
+LOCAL expptr
+cdreal(cp)
+Constp cp;
+{
+  static char *compat1 =
+       "logical datum assigned to a double precision variable";
+  static char *compat2 =
+       "character datum assigned to a double precision variable";
+
+  register expptr p;
+  register long *longp;
+  register long *rp;
+
+  switch (cp->vtype)
+    {
+    case TYBITSTR:
+      longp = (long *) grabbits(8, cp);
+      p = (expptr) mkconst(TYDREAL);
+      rp = (long *) &(p->constblock.const.cd[0]);
+      rp[0] = longp[0];
+      rp[1] = longp[1];
+      free((char *) longp);
+      break;
+
+    case TYSHORT:
+    case TYLONG:
+      p = (expptr) mkconst(TYDREAL);
+      p->constblock.const.cd[0] = cp->const.ci;
+      break;
+
+    case TYREAL:
+    case TYDREAL:
+    case TYCOMPLEX:
+    case TYDCOMPLEX:
+      p = (expptr) mkconst(TYDREAL);
+      longp = (long *) &(cp->const.cd[0]);
+      rp = (long *) &(p->constblock.const.cd[0]);
+      rp[0] = longp[0];
+      rp[1] = longp[1];
+      break;
+
+    case TYLOGICAL:
+      if (badvalue <= 1)
+       {
+         badvalue = 2;
+         err(compat1);
+       }
+      p = errnode();
+      break;
+
+    case TYCHAR:
+      if ( !ftn66flag && badvalue == 0 )
+       {
+         badvalue = 1;
+         warn(compat2);
+       }
+
+    case TYHOLLERITH:
+      longp = (long *) grabbytes(8, cp);
+      p = (expptr) mkconst(TYDREAL);
+      rp = (long *) &(p->constblock.const.cd[0]);
+      rp[0] = longp[0];
+      rp[1] = longp[1];
+      free((char *) longp);
+      break;
+
+    case TYERROR:
+      p = errnode();
+      break;
+    }
+
+  return (p);
+}
+
+\f
+
+LOCAL expptr
+ccomplex(cp)
+Constp cp;
+{
+  static char *toobig = "data value too large";
+  static char *compat1 = "logical datum assigned to a complex variable";
+  static char *compat2 = "character datum assigned to a complex variable";
+
+  register expptr p;
+  register long *longp;
+  register long *rp;
+  register double *minp;
+  register double *maxp;
+  realvalue re, im;
+  int overflow;
+  float x;
+
+  switch (cp->vtype)
+    {
+    case TYBITSTR:
+      longp = (long *) grabbits(8, cp);
+      p = (expptr) mkconst(TYCOMPLEX);
+      rp = (long *) &(p->constblock.const.cd[0]);
+      rp[0] = longp[0];
+      rp[2] = longp[1];
+      free((char *) longp);
+      break;
+
+    case TYSHORT:
+    case TYLONG:
+      p = (expptr) mkconst(TYCOMPLEX);
+      p->constblock.const.cd[0] = cp->const.ci;
+      break;
+
+    case TYREAL:
+    case TYDREAL:
+    case TYCOMPLEX:
+    case TYDCOMPLEX:
+      overflow = 0;
+      minp = (double *) dminreal;
+      maxp = (double *) dmaxreal;
+      rp = (long *) &(cp->const.cd[0]);
+      re.q.word1 = rp[0];
+      re.q.word2 = rp[1];
+      im.q.word1 = rp[2];
+      im.q.word2 = rp[3];
+      if (((re.f.sign == 0 || re.f.exp != 0) &&
+          (re.d < *minp || re.d > *maxp))       ||
+         ((im.f.sign == 0 || re.f.exp != 0) &&
+          (im.d < *minp || re.d > *maxp)))
+       {
+         if (badvalue <= 1)
+           {
+             badvalue = 2;
+             err(toobig);
+           }
+         p = errnode();
+       }
+      else
+       {
+         p = (expptr) mkconst(TYCOMPLEX);
+         if (re.f.sign == 1 && re.f.exp == 0)
+           re.q.word2 = 0;
+         else
+           {
+             x = re.d;
+             re.d = x;
+           }
+         if (im.f.sign == 1 && im.f.exp == 0)
+           im.q.word2 = 0;
+         else
+           {
+             x = im.d;
+             im.d = x;
+           }
+         rp = (long *) &(p->constblock.const.cd[0]);
+         rp[0] = re.q.word1;
+         rp[1] = re.q.word2;
+         rp[2] = im.q.word1;
+         rp[3] = im.q.word2;
+       }
+      break;
+
+    case TYLOGICAL:
+      if (badvalue <= 1)
+       {
+         badvalue = 2;
+         err(compat1);
+       }
+      break;
+
+    case TYCHAR:
+      if ( !ftn66flag && badvalue == 0)
+       {
+         badvalue = 1;
+         warn(compat2);
+       }
+
+    case TYHOLLERITH:
+      longp = (long *) grabbytes(8, cp);
+      p = (expptr) mkconst(TYCOMPLEX);
+      rp = (long *) &(p->constblock.const.cd[0]);
+      rp[0] = longp[0];
+      rp[2] = longp[1];
+      free((char *) longp);
+      break;
+
+    case TYERROR:
+      p = errnode();
+      break;
+    }
+
+  return (p);
+}
+
+\f
+
+LOCAL expptr
+cdcomplex(cp)
+Constp cp;
+{
+  static char *compat1 = "logical datum assigned to a complex variable";
+  static char *compat2 = "character datum assigned to a complex variable";
+
+  register expptr p;
+  register long *longp;
+  register long *rp;
+
+  switch (cp->vtype)
+    {
+    case TYBITSTR:
+      longp = (long *) grabbits(16, cp);
+      p = (expptr) mkconst(TYDCOMPLEX);
+      rp = (long *) &(p->constblock.const.cd[0]);
+      rp[0] = longp[0];
+      rp[1] = longp[1];
+      rp[2] = longp[2];
+      rp[3] = longp[3];
+      free((char *) longp);
+      break;
+
+    case TYSHORT:
+    case TYLONG:
+      p = (expptr) mkconst(TYDCOMPLEX);
+      p->constblock.const.cd[0] = cp->const.ci;
+      break;
+
+    case TYREAL:
+    case TYDREAL:
+    case TYCOMPLEX:
+    case TYDCOMPLEX:
+      p = (expptr) mkconst(TYDCOMPLEX);
+      longp = (long *) &(cp->const.cd[0]);
+      rp = (long *) &(p->constblock.const.cd[0]);
+      rp[0] = longp[0];
+      rp[1] = longp[1];
+      rp[2] = longp[2];
+      rp[3] = longp[3];
+      break;
+
+    case TYLOGICAL:
+      if (badvalue <= 1)
+       {
+         badvalue = 2;
+         err(compat1);
+       }
+      p = errnode();
+      break;
+
+    case TYCHAR:
+      if ( !ftn66flag && badvalue == 0 )
+       {
+         badvalue = 1;
+         warn(compat2);
+       }
+
+    case TYHOLLERITH:
+      longp = (long *) grabbytes(16, cp);
+      p = (expptr) mkconst(TYDCOMPLEX);
+      rp = (long *) &(p->constblock.const.cd[0]);
+      rp[0] = longp[0];
+      rp[1] = longp[1];
+      rp[2] = longp[2];
+      rp[3] = longp[3];
+      free((char *) longp);
+      break;
+
+    case TYERROR:
+      p = errnode();
+      break;
+    }
+
+  return (p);
+}
+
+\f
+
+LOCAL expptr
+clogical(cp)
+Constp cp;
+{
+  static char *compat1 = "numeric datum assigned to a logical variable";
+  static char *compat2 = "character datum assigned to a logical variable";
+
+  register expptr p;
+  register long *longp;
+  register short *shortp;
+  register int size;
+
+  size = typesize[tylogical];
+
+  switch (cp->vtype)
+    {
+    case TYBITSTR:
+      p = (expptr) mkconst(tylogical);
+      if (tylogical == TYSHORT)
+       {
+         shortp = (short *) grabbits(size, cp);
+         p->constblock.const.ci = (int) *shortp;
+         free((char *) shortp);
+       }
+      else
+       {
+         longp = (long *) grabbits(size, cp);
+         p->constblock.const.ci = *longp;
+         free((char *) longp);
+       }
+      break;
+
+    case TYSHORT:
+    case TYLONG:
+    case TYREAL:
+    case TYDREAL:
+    case TYCOMPLEX:
+    case TYDCOMPLEX:
+      if (badvalue <= 1)
+       {
+         badvalue = 2;
+         err(compat1);
+       }
+      p = errnode();
+      break;
+
+    case TYLOGICAL:
+      p = (expptr) cpexpr(cp);
+      p->constblock.vtype = tylogical;
+      break;
+
+    case TYCHAR:
+      if ( !ftn66flag && badvalue == 0 )
+       {
+         badvalue = 1;
+         warn(compat2);
+       }
+
+    case TYHOLLERITH:
+      p = (expptr) mkconst(tylogical);
+      if (tylogical == TYSHORT)
+       {
+         shortp = (short *) grabbytes(size, cp);
+         p->constblock.const.ci = (int) *shortp;
+         free((char *) shortp);
+       }
+      else
+       {
+         longp = (long *) grabbytes(4, cp);
+         p->constblock.const.ci = *longp;
+         free((char *) longp);
+       }
+      break;
+
+    case TYERROR:
+      p = errnode();
+      break;
+    }
+
+  return (p);
+}
+
+\f
+
+LOCAL expptr
+cchar(len, cp)
+int len;
+Constp cp;
+{
+  static char *compat1 = "numeric datum assigned to a character variable";
+  static char *compat2 = "logical datum assigned to a character variable";
+
+  register expptr p;
+  register char *value;
+
+  switch (cp->vtype)
+    {
+    case TYBITSTR:
+      value = grabbits(len, cp);
+      p = (expptr) mkstrcon(len, value);
+      free(value);
+      break;
+
+    case TYSHORT:
+    case TYLONG:
+    case TYREAL:
+    case TYDREAL:
+    case TYCOMPLEX:
+    case TYDCOMPLEX:
+      if (badvalue <= 1)
+       {
+         badvalue = 2;
+         err(compat1);
+       }
+      p = errnode();
+      break;
+
+    case TYLOGICAL:
+      if (badvalue <= 1)
+       {
+         badvalue = 2;
+         err(compat2);
+       }
+      p = errnode();
+      break;
+
+    case TYCHAR:
+    case TYHOLLERITH:
+      value = grabbytes(len, cp);
+      p = (expptr) mkstrcon(len, value);
+      free(value);
+      break;
+
+    case TYERROR:
+      p = errnode();
+      break;
+    }
+
+  return (p);
+}
+
+\f
+
+expptr
+convconst(type, len, const)
+int type;
+int len;
+Constp const;
+{
+  register expptr p;
+
+  switch (type)
+    {
+    case TYSHORT:
+      p = cshort(const);
+      break;
+
+    case TYLONG:
+      p = clong(const);
+      break;
+
+    case TYREAL:
+      p = creal(const);
+      break;
+
+    case TYDREAL:
+      p = cdreal(const);
+      break;
+
+    case TYCOMPLEX:
+      p = ccomplex(const);
+      break;
+
+    case TYDCOMPLEX:
+      p = cdcomplex(const);
+      break;
+
+    case TYLOGICAL:
+      p = clogical(const);
+      break;
+
+    case TYCHAR:
+      p = cchar(len, const);
+      break;
+
+    case TYERROR:
+    case TYUNKNOWN:
+      p = errnode();
+      break;
+
+    default:
+      badtype("convconst", type);
+    }
+
+  return (p);
+}