/***********************************
  (C) Copyright 1992-1993; dit/upm
   Distributed under the conditions stated in the
   TOPO General Public License (see file LICENSE)
 ***********************************
 $Log: gendecl.c,v $
 * Revision 1.17  1995/01/17  09:49:51  lotos
 * new entry in intermediate language: number of declarations
 *
 * Revision 1.16  1993/06/10  14:00:13  lotos
 * new annotation CALL
 *
 * Revision 1.15  1993/05/28  10:41:43  lotos
 * opcion -c tiene niveles
 *
 * Revision 1.14  1993/05/25  10:59:09  lotos
 * ldcend y ldcinit pasan al principio
 *
 * Revision 1.13  1993/03/24  17:51:24  lotos
 * initial ldc annotation goes into ATable
 * new annotation 'infix'
 *
 * Revision 1.12  1993/01/18  18:12:15  lotos
 * distribution issues
 *
 * Revision 1.11  1992/11/17  18:42:43  lotos
 * parse annotation must be a single word
 *
 * Revision 1.10  1992/10/14  17:49:56  lotos
 * fix error in ldc annotation when using libraries
 *
 * Revision 1.9  1992/10/14  17:43:21  lotos
 * forget about ophuscation
 *
 * Revision 1.8  1992/09/11  16:46:21  lotos
 * bug fixing
 *
 * Revision 1.7  1992/09/02  15:44:46  lotos
 * new option to remove externa annotations
 * new option to print and label the equations
 * new debugging options: save modified CAST
 * overall debugging and improvements
 *
 * Revision 1.6  92/01/14  15:25:10  lotos
 * distribution issues
 * 
 * Revision 1.5  92/01/13  19:24:28  lotos
 * adaptec to ophuscate
 * 
 * Revision 1.4  91/11/20  13:15:01  lotos
 * parse annotation added
 * 
 * Revision 1.3  91/10/02  16:49:21  lotos
 * color sort is now in the AT
 * 
 * Revision 1.2  91/04/11  18:32:30  lotos
 * cosmetics
 * 
 * Revision 1.1  91/02/06  20:13:10  lotos
 * Initial revision
 * 
 ***********************************/

#ifndef lint
static char rcsid[]= "$Id: gendecl.c,v 1.17 1995/01/17 09:49:51 lotos Exp $";
#endif

/***********************************************************************

     "gendecl.o": modulo generador de la declaracion del tipo de datos.

***********************************************************************/

#include <stdio.h>
#include "idle.h"
#include "tabop.h"
#include "LDM.h"
#include "gendecl.h"


static int GenAnotReglas()
/* Genera las anotaciones acerca de las reglas. */
{ EstManOp *OpAct;
  EstManEc *PrimEc, *EcAct;
  int HayEc= FALSE;

  for (OpAct= PrimOpTab(); OpAct != NULL; OpAct= OpAct->Sig)
  { if (OpAct->Tipo == OpSinArg)
      PrimEc= OpAct->u.LisEc.EcOrig;
    else
      PrimEc= OpAct->u.MatEc.EcOrig;
    if (PrimEc == NULL)
      continue;
    HayEc= TRUE;
    EcAct= PrimEc;
    do
    { EcAct= EcAct->SigEc;
      EscAnotRegla(EcAct);
    } while (EcAct != PrimEc);
  }
  return HayEc;
}

void GenDeclTipo()
/* Genera la declaracion del tipo de datos. */
{ char *c;
  EstManOp *p;
  TNODE *q, *r;
  int i;
  int EsExt;

  /* Anotaciones acerca de las reglas. */
  if (OpcProg.EtiqReg)
    if (GenAnotReglas())
      (void) printf("\n");
  /* Anotacion "ldc" inicial. */
  c= ldc(v_spec(RaizEspec()));
  if (c != NULL)
  { EscAnot(LDC_ANNOTATION, "", c);
    (void) printf("\n");
  }
  /* Anotacion "ldcinit". */
  c= ldcinit(v_spec(RaizEspec()));
  if (c != NULL)
  { EscAnot(LDCINIT_ANNOTATION, "", c);
    (void) printf("\n");
  }
  /* Anotacion "ldc" final. */
  c= ldc(v_endspec(RaizEspec()));
  if (c != NULL)
  { EscAnot(LDCEND_ANNOTATION, "", c);
    (void) printf("\n");
  }
  /* Declaracion de clases. */
  Sangra();
  (void) printf("%s", BEGIN_SORTS_DECL);
  for (p= PrimClTab(), i= 0; p != NULL; p= p->Sig)
    ++i;
  (void) printf(" %d\n", i);
  IncSang();
  for (p= PrimClTab(); p != NULL; p= p->Sig)
  { if (OpcProg.InsCom > 0)
    { Sangra();
      EscComCl(p->Nodo);
    }
    Sangra();
    (void) printf("%s ", SORT_DECL);
    c= name(iddec(p->Nodo));
    if (c == NULL)
      c= lexv(iddec(p->Nodo));
    (void) printf("%s %d %s ", p->Id, p->Num, c);
    EsExt= v_extern(iddec(p->Nodo)) != STR_ERR;
    if (EsExt)
      (void) printf("%s", IMPORTED);
    else
      (void) printf("%s", DEFINED);
    (void) printf("\n");
    if (EsExt)
    { if ((c= v_free(iddec(p->Nodo))) != NULL)
	EscAnot(FREE_ANNOTATION, "", c);
      if ((c= v_equal(iddec(p->Nodo))) != NULL)
	EscAnot(EQUAL_ANNOTATION, "", c);
      if ((c= v_draw(iddec(p->Nodo))) != NULL)
	EscAnot(DRAW_ANNOTATION, "", c);
      if ((c= v_parse(iddec(p->Nodo))) != NULL)
	EscAnot(PARSE_ANNOTATION, "", c);
    }
  }
  DecSang();
  Sangra();
  (void) printf("%s\n\n", END_SORTS_DECL);
  /* Declaracion de operaciones. */
  Sangra();
  (void) printf("%s", BEGIN_OPERATIONS_DECL);
  for (p= PrimOpTab(), i= 0; p != NULL; p= p->Sig)
    ++i;
  (void) printf(" %d\n", i);
  IncSang();
  for (p= PrimOpTab(); p != NULL; p= p->Sig)
  { if (OpcProg.InsCom > 0)
    { Sangra();
      EscComOp(p->Nodo);
    }
    Sangra();
    (void) printf("%s ", OPERATION_DECL);
    c= name(iddec(p->Nodo));
    if (c == NULL)
      c= lexv(iddec(p->Nodo));
    (void) printf("%s %d %s ", p->Id, p->Num, c);
    if (v_extern(iddec(p->Nodo)) == STR_ERR)
      (void) printf("%s", DEFINED);
    else
      (void) printf("%s", IMPORTED);
    (void) printf(" %d ", ClTab(sort(iddec(p->Nodo)))->Num);
    q= gt_rb(gt_ft(gt_ft(p->Nodo)));
    if (q->type == targument_list)
    { for (r= gt_fs(q), i= 1;; ++i)
      { r= gt_rb(r);
	if (r == NULL)
	  break;
      }
      (void) printf("%d", i);
      for (r= gt_fs(q);;)
      { (void) printf(" %d", ClTab(idref(r))->Num);
	r= gt_rb(r);
	if (r == NULL)
	  break;
      }
    }
    else
      (void) printf("0");
    if (infix(iddec(p->Nodo)) == 0)
      (void) printf(" %s %s", ANNOTATION, INFIX_ANNOTATION);
    (void) printf("\n");
    /* Anotacion "call". */
    c= call(iddec(p->Nodo));
    if (c != NULL)
      EscAnot(CALL_ANNOTATION, "", c);
  }
  DecSang();
  Sangra();
  (void) printf("%s\n", END_OPERATIONS_DECL);
}
