# include "rag.hh"
# include "nodes.h"
# include "grc.h"

IAT* grnl= NULL;

# include "swbus.h"

PRIVATE void
PROCESINI (r)
    TNODE* r;
{
  TNODE* h[33];
  /* KJT 20/01/23: added "int" type */
  register int i;
  int nr;
  int* grl;

  while (r != NULL) {
    h[0]= r;
    heval (r, h);
    grl= grnl->data[(int)(r->value0)];
    for (i= 0; grl[i] != 0; i++) {
     nr= grl[i];
     switch (nr) {
      case _type_definition_1:
	 adclr (-c_dec, h[0], 1);
	 break;
      case _p_expression_1:
	 if (h[0] != NULL)
	  adclr (-c_type_class, h[0], 2);
	 if (h[0] != NULL)
	  adclr (-c_typexr, h[0], 3);
	 break;
      case _p_expression_2:
	 adclr (-c_lib_used, h[1], 4);
	 adclr (-c_type_class, h[0], 5);
	 adclr (-c_typexr, h[0], 6);
	 break;
      case _p_expression_3:
	 adclr (-c_lib_used, h[1], 7);
	 adclr (-c_type_class, h[0], 8);
	 adclr (-c_typexr, h[0], 9);
	 break;
      case _type_union_1:
	 h[3]= h[1];
	 h[4]= gt_rb (h[3]);
	 while (h[3] != NULL) {
	  adclr (-c_lib_used, h[3], 10);
	  h[3]= h[4];
	  h[4]= gt_rb (h[4]);
	 }
	 if (h[1] != NULL)
	  adclr (-c_typexr, h[1], 11);
	 h[3]= h[1];
	 h[4]= gt_rb (h[3]);
	 while (h[4] != NULL) {
	  adclr (-c_typexr, h[4], 12);
	  h[3]= h[4];
	  h[4]= gt_rb (h[4]);
	 }
	 if (h[0] != NULL)
	  adclr (-c_typexr, h[0], 13);
	 break;
      default:
	 assert ((1 <= nr) && (nr <= LAST_RULE));
      }
    } /* end of while (ngr != NULL) */
    r= succ (r, PREORDER);
  } /* end of while (r != NULL) */
} /* end of PROCESINI */

PUBLIC CLR_TYPE
eval (nar, r)
    int nar;
    TNODE* r;
{
  TNODE* h[33];

  if (r == NULL) return (CLR_TYPE)NULL;
  switch (nar) {
  case 1:
    h[0]= r;
    heval (h[0], h);

     if (find_attr (c_is_lib, h[0]) != NULL) {
       if (!NotIn ((int)fdclr (c_iddec,h[1], nar), tusedroot)) {
	  return (CLR_TYPE)
	   puttypexr ((char*)SLTable->data[(int)SATable->data[(int)fdclr (c_iddec,h[1], nar)].value1],
		      (int)fdclr (c_iddec,h[1], nar),
		      (int)fdclr (c_line,h[1], nar),
		      (TYPEDEPEND*)fdclr (c_typexr,h[2], nar),
		      (int)fdclr (c_type_class,h[2], nar));
       }
       else  return (CLR_TYPE) NULL;
     }
     else {
       visit (h[0]);
	return (CLR_TYPE)
	 puttypexr ((char*)SLTable->data[(int)SATable->data[(int)fdclr (c_iddec,h[1], nar)].value1],
		    (int)fdclr (c_iddec,h[1], nar),
		    (int)fdclr (c_line,h[1], nar),
		    (TYPEDEPEND*)fdclr (c_typexr,h[2], nar),
		    (int)fdclr (c_type_class,h[2], nar));
     };
  case 2:
    h[0]= r;
    heval (h[0], h);
   return (CLR_TYPE) UNION;
  case 3:
    h[0]= r;
    heval (h[0], h);

      return (CLR_TYPE) ((h[1] != NULL) ? fdclr (c_typexr,h[1], nar) : NULL);
  case 4:
    h[0]= gt_ft (r);
    heval (h[0], h);

      return (CLR_TYPE) ((find_attr (c_is_lib, h[1]) != NULL) ? TRUE : FALSE);
  case 5:
    h[0]= r;
    heval (h[0], h);
   return (CLR_TYPE) ACTUALIZED;
  case 6:
    h[0]= r;
    heval (h[0], h);

  {
     TYPEDEPEND *aux;
     aux = (TYPEDEPEND*) emalloc (sizeof (TYPEDEPEND));
     aux->name = (char*)SLTable->data[(int)SATable->data[(int)fdclr (c_idref,h[1], nar)].value1];
     aux->iddec = (int)fdclr (c_idref,h[1], nar);
     aux->next = (TYPEDEPEND*)fdclr (c_typexr,h[2], nar);
      return (CLR_TYPE) aux;
  }
  case 7:
    h[0]= gt_ft (r);
    heval (h[0], h);

      return (CLR_TYPE) ((find_attr (c_is_lib, h[1]) != NULL) ? TRUE : FALSE);
  case 8:
    h[0]= r;
    heval (h[0], h);
   return (CLR_TYPE) RENAMED;
  case 9:
    h[0]= r;
    heval (h[0], h);

  {
     TYPEDEPEND *aux;
     aux = (TYPEDEPEND*) emalloc (sizeof (TYPEDEPEND));
     aux->name = (char*)SLTable->data[(int)SATable->data[(int)fdclr (c_idref,h[1], nar)].value1];
     aux->iddec = (int)fdclr (c_idref,h[1], nar);
     aux->next = NULL;
      return (CLR_TYPE) aux;
  }
  case 10:
    h[0]= gt_ft (r);
    h[1]= gt_fs (h[0]);
    h[3]= r;
    h[4]= gt_rb (h[3]);
    h[5]= gt_ls (h[0]);

      return (CLR_TYPE) ((find_attr (c_is_lib, h[3]) != NULL) ? TRUE : FALSE);
  case 11:
    h[0]= gt_ft (r);
    h[1]= gt_fs (h[0]);
    h[5]= gt_ls (h[0]);

  {
     TYPEDEPEND *aux;
     aux = (TYPEDEPEND*) emalloc (sizeof (TYPEDEPEND));
     aux->name = (char*)SLTable->data[(int)SATable->data[(int)fdclr (c_idref,h[1], nar)].value1];
     aux->iddec = (int)fdclr (c_idref,h[1], nar);
     aux->next = NULL;
      return (CLR_TYPE) aux;
  }
  case 12:
    h[0]= gt_ft (r);
    h[1]= gt_fs (h[0]);
    h[4]= r;
    h[3]= gt_lb (h[4]);
    h[5]= gt_ls (h[0]);

  {
     TYPEDEPEND *aux;
     aux = (TYPEDEPEND*) emalloc (sizeof (TYPEDEPEND));
     aux->name = (char*)SLTable->data[(int)SATable->data[(int)fdclr (c_idref,h[4], nar)].value1];
     aux->iddec = (int)fdclr (c_idref,h[4], nar);
     aux->next = (TYPEDEPEND*)fdclr (c_typexr,h[3], nar);
      return (CLR_TYPE) aux;
  }
  case 13:
    h[0]= r;
    h[1]= gt_fs (h[0]);
    h[5]= gt_ls (h[0]);

	    return (CLR_TYPE)  fdclr (c_typexr,h[5], nar);
     }
  return (CLR_TYPE)NULL;
}






PUBLIC void
visit (r)
	TNODE*	r;
{
	TNODE*	h[33];
	int	nar;

  if (r == NULL) return;
  nar= *(grnl->data[(int)(r->value0)]);
  switch (nar) {

   case _type_definition_1 :
    h[0]= r;
    heval (h[0], h);
	{
	 visit (h[2]);
	}
	break;

   case _p_expression_1 :
    h[0]= r;
    heval (h[0], h);
	{
	 if (h[1] != NULL);
	 visit (h[1]);
	}
	break;

   case _p_expression_2 :
    h[0]= r;
    heval (h[0], h);
	{
	 visit (h[1]);
	 visit (h[2]);
	}
	break;

   case _p_expression_3 :
    h[0]= r;
    heval (h[0], h);
	{
	 visit (h[1]);
	}
	break;

   case _type_union_1 :
    h[0]= r;
    h[1]= gt_fs (h[0]);
    h[5]= gt_ls (h[0]);
	{
	 TNODE* aux;
	 for (aux = h[1]; aux != NULL; aux= gt_rb(aux))
	 visit (aux);
	}
	break;

   case _type_identifier_1 :
    h[0]= r;
    heval (h[0], h);
	{
	 if (find_attr (c_idref, h[0]) != NULL)
	 /* It is not a declaration */
	 addonetype ((int)fdclr (c_idref,h[0], nar));
	}
	break;
  }
}

PUBLIC void
rag (r)
    TNODE* r;
{
  PROCESINI (r);
  if (ragerrors == 0)
    todo (r);
} /* end of rag */
