Google
 

Trailing-Edge - PDP-10 Archives - SRI_NIC_PERM_FS_1_19910112 - c/old/kc/cc53.c
There are no other files named cc53.c in the archive.
/* cc53.c -- Type checking and automatic coercions. */
/*		(C) 1981   K. Chen		    */

#define	    sc extern
#include    "cc.h"


node typecheck(n)
struct NODE *n;
{
  int    compare;
  struct TY   *t;
  struct NODE *l;

  compare = 0;

  switch (n->nop) {
  case LEQ:
  case GEQ:
  case LESS:
  case GREAT:
       t = n->ntype;
       if ((t->ttype == PTR || t->ttype == ARRAY) &&
            t->tptr->ttype == CHAR) pcoerce(n);
       /* fall through */
  case NEQ:
  case EQUAL:
       compare = 1;
       n->ntype = deftype;	/* result of boolean is int */
       break;
  case LAND:
  case LOR:
       n->ntype = deftype;      /* result is int */
       l = n->left->ntype;
       if (&types[UNSIGNED-INT] >= l || l->ttype == PTR) {
           l = n->right;
	   if (&types[UNSIGNED-INT] >= l || l->ttype == PTR) {
               return;
           }
       }
  }

  switch (n->left->ntype->ttype) {
  case PTR:
  case ARRAY:
  case STRUCT:
       return checktype(n, 0, compare);
  default:
       return checktype(n, 1, compare);
  }
}

node checktype(n, lr, compare)
struct NODE *n;
{
  struct TY   *ltype, *rtype;
  struct NODE *c;
  int    lscalar, rscalar, err, ptrptr, size;
  
  if (lr == 0) {
      ltype = n->left->ntype;
      rtype = n->right->ntype;
  }
  else {
      rtype = n->left->ntype;
      ltype = n->right->ntype;
  }

  lscalar = ltype->ttype;
  rscalar = rtype->ttype;

  /* first order checking of pointer/array/struct arithmetic */

  ptrptr = 0;
  switch (lscalar) {
  case PTR:
       switch (rscalar) {
       case ARRAY:
       case PTR:
       case STRUCT:
            ptrptr = 1;
            err = (ltype == rtype) && !compare ;
	    pcoerce(n);
	    n->ntype = deftype;
	    break;
       default:
            err = 0;
       }
       if (err) {
	  error(EPARITH);
	  return n;
       }
       break;

  case ARRAY:
  case STRUCT:
       switch (rscalar) {
       case PTR:
            ptrptr = 1;
            err = (rtype->tptr == ltype);
	    break;
       case ARRAY:
       case STRUCT:
            ptrptr = 1;
            err = (rtype == ltype);
	    break;
       default:
            err = 0;
       }
       if (err) {
	  error(EPARITH);
	  return n;
       }
       break;

  default:
       /* when float is installed, coerce here */
       return n;
  }

  /* pointer/array/struct arithmetic */

  switch (n->nop) {
  case PLUS:
       if (ptrptr) {
           error(EPARITH);	/* pointer-pointer adds not allowed */
	   return n;
       }
       /* fall through */
  case MINUS:
       if (ptrptr) { /* need to check for char array and struct sizes here */
           return n;
       }
       if ((size = tsize(ltype->tptr)) > 1) {
	   c = defnode(N2, ICONST, deftype, 0, NULL);
	   c->niconst = size;
	   c = defnode(N3, MPLY, n->ntype, 0, NULL, c);
           if (lr == 0) {
	       c->left = n->right;
	       n->right = c;
	   }
	   else {
	       c->left = n->left;
	       n->left = c;
	   }
       }
       break;
  case NEQ:
  case LEQ:
  case GEQ:
  case LESS:
  case EQUAL:
  case GREAT:
       break;	/* pointer comparisons, ok */
  default:
       error(EPARITH);
  }
  return n;
}

/* ----------------------------------------------------- */
/*	coerce char pointers to be an ordered index      */
/* ----------------------------------------------------- */

pcoerce(n)
struct NODE *n;
{
  struct NODE *l, *r;
  int    tt, rt;

  l = n->left;
  rt = (charpointer(l->ntype)) ? PC_PC : NOCOER;
  tt = l->ntype->ttype;
  if (tt == PTR || tt == ARRAY) {
      r = defnode(N3, COERCE, deftype, l->nflag, l, NULL);
      r->nc = rt;
      n->left = r;
  }
  l = n->right;
  rt = (charpointer(l->ntype)) ? PC_PC : NOCOER;
  tt = l->ntype->ttype;
  if (tt == PTR || tt == ARRAY) {
      r = defnode(N3, COERCE, deftype, l->nflag, l, NULL);
      r->nc = rt;
      n->right = r;
  }
}