/***********************************
  (C) Copyright 1992-1993; dit/upm
   Distributed under the conditions stated in the
   TOPO General Public License (see file LICENSE)
 ***********************************
 $Log: pecast.c,v $
 * Revision 1.11  1993/09/20  14:23:00  lotos
 * cut and ln (link) functions moved to EPS
 *
 * Revision 1.10  1993/03/29  18:09:10  lotos
 * add constructor verification/s
 *
 * Revision 1.9  1993/03/24  17:51:24  lotos
 * ldc and ldcinit go into ATable
 *
 * Revision 1.8  1993/01/18  18:12:15  lotos
 * distribution issues
 *
 * Revision 1.7  1992/10/14  17:43:50  lotos
 * forget about ophuscation
 *
 * Revision 1.6  1992/09/02  15:15:23  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.5  92/05/06  18:51:03  lotos
 * no se
 * 
 * Revision 1.4  92/01/14  15:25:23  lotos
 * distribution issues
 * 
 * Revision 1.3  92/01/13  19:24:56  lotos
 * adaptec to ophuscate
 * 
 * Revision 1.2  91/11/20  13:19:15  lotos
 * ATable is read from a separate file
 * 
 * Revision 1.1  91/02/06  20:16:02  lotos
 * Initial revision
 * 
 ***********************************/

#ifndef lint
static char rcsid[]= "$Id: pecast.c,v 1.11 1993/09/20 14:23:00 lotos Exp $";
#endif

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

     "pecast.o": parametrizacion y extension de "cast".

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

#include <stdio.h>
#include "idle.h"


/* Definicion de los colores utilizados en el AST. */
TIOCOLOURS iocolours[]= {
#include "colours.c"
			  "anyeq",   c_anyeq,   IO_ign,	/* IO_int */
			  "pvar",    c_pvar,    IO_ign,	/* IO_TND */
			  "eqno",    c_eqno,    IO_ign,	/* IO_int */
			  "oveq",    c_oveq,    IO_ign,	/* IO_TND */
			  NULL,      others,    IO_ign
			};


CLR_TYPE _attr_value(nodep, attr)
/* Devuelve el valor de un atributo. */
TNODE *nodep;
int attr;
{ TATTR *p;

  p= find_attr(attr, nodep);
  aborta_si(p == NULL)
  return p->value;
}

CLR_TYPE _find_attr_value(nodep, attr, not_found_value)
/* Si esta, devuelve el valor del atributo, si no, "not_found_value". */
TNODE *nodep;
int attr;
CLR_TYPE not_found_value;
{ TATTR *p;

  aborta_si(nodep == NULL)
  p= find_attr(attr, nodep);
  if (p == NULL)
    return not_found_value;
  else
    return p->value;
}

void _add_attr_value(nodep, attr, val)
/* Anade un atributo con su valor. */
TNODE *nodep;
int attr;
CLR_TYPE val;
{ TATTR *p;

  p= add_attr(attr, nodep);
  aborta_si(p == NULL)
  p->value= val;
}

void _del_attr_value(nodep, attr)
/* Elimina un atributo con su valor. */
TNODE *nodep;
int attr;
{ TATTR *p;

  p= take_attr(attr, nodep);
  aborta_si(p == NULL)
  free_attr(p);
}

void _fdel_attr_value(nodep, attr)
/* Elimina un atributo, si existe, con su valor. */
TNODE *nodep;
int attr;
{ TATTR *p;

  aborta_si(nodep == NULL)
  p= take_attr(attr, nodep);
  if (p != NULL)
    free_attr(p);
}


/* Tablas de la especificacion. */
TSTBL _stbl= { NULL, NULL, NULL };

#undef class	/* Permite usar el miembro "class" de las tablas */

CLR_TYPE _AT_attr_value(i, attr)
/* Igual que "_attr_value()", pero para la tabla de atributos. */
int i;
int attr;
{ TATTR *p;

  aborta_si(!is_stbl_entry(AT, i))
  p= ATfind(_stbl.AT, i, attr);
  aborta_si(p == NULL)
  return p->value;
}

CLR_TYPE _AT_find_attr_value(i, attr, not_found_value)
/* Igual que "_find_attr_value()", pero para la tabla de atributos. */
int i;
int attr;
CLR_TYPE not_found_value;
{ TATTR *p;

  aborta_si(!is_stbl_entry(AT, i))
  p= ATfind(_stbl.AT, i, attr);
  if (p == NULL)
    return not_found_value;
  else
    return p->value;
}

void _AT_add_attr_value(i, attr, val)
/* Igual que "_add_attr_value()", pero para la tabla de atributos. */
int i;
int attr;
CLR_TYPE val;
{ TATTR *p;

  p= ATadd(_stbl.AT, i, attr);
  aborta_si(p == NULL)
  p->value= val;
}

void _AT_del_attr_value(i, attr)
/* Igual que "_del_attr_value()", pero para la tabla de atributos. */
int i;
int attr;
{ TATTR *p;

  aborta_si(!is_stbl_entry(AT, i))
  p= ATtake(_stbl.AT, i, attr);
  aborta_si(p == NULL)
  free_attr(p);
}

void _AT_fdel_attr_value(i, attr)
/* Igual que "_fdel_attr_value()", pero para la tabla de atributos. */
int i;
int attr;
{ TATTR *p;

  aborta_si(!is_stbl_entry(AT, i))
  p= ATtake(_stbl.AT, i, attr);
  if (p != NULL)
    free_attr(p);
}

TNODE *load_spec(sfp, tfp)
/* Carga el AST de una especificacion. */
FILE *sfp;
FILE *tfp;
{ TNODE *spec;

  aborta_si(is_stbl_init(AT) ||
	    is_stbl_init(GRNL) ||
	    is_stbl_init(LL))
  cast_init(iocolours);
  spec= restore(sfp);
  if (tfp != NULL)
  { TNODE *tbls;
    static int ctbl[]= { CSTBL };
    int i, imax;

    tbls= restore(tfp);
    aborta_si(tbls == NULL)
    for (i= 0, imax= sizeof(ctbl) / sizeof(ctbl[0]); i < imax; ++i)
    { TATTR *p;

      p= take_attr(ctbl[i], tbls);
      if (p == NULL)
	continue;
      set_attr(ctbl[i], spec, p->value);
      p->value= NULL;
      free_attr(p);
    }
    aborta_si(tbls->value0 != NULL)
    aborta_si(tbls->value1 != NULL)
    copyattrs(spec, tbls);
    kill_tree(tbls);
  }
  _stbl.AT= at(spec);
  _stbl.GRNL= grnl(spec);
  _stbl.LL= ll(spec);
  _stbl.LL->incr= 16;		/* expansion a tacos */
  _stbl.LL->class= 1;		/* sin duplicados */
  _stbl.LL->ecase= FALSE;	/* mayusculas == minusculas */
  {
    int id, lid, tmp;

    lid= id= luid(spec);
    tmp= v_spec(spec);
    if (tmp >= id)
      id= tmp + 1;
    tmp= v_endspec(spec);
    if (tmp >= id)
      id= tmp + 1;
    if (id > lid)
    { del_luid(spec);
      add_luid(spec, id);
    }
    aborta_si(luid(spec) != _stbl.AT->size)
  }
  return spec;
}

void save_spec(fp, spec)
/* Almacena el AST de una especificacion. */
FILE *fp;
TNODE *spec;
{
  aborta_si(!is_stbl_init(AT) ||
	    !is_stbl_init(GRNL) ||
	    !is_stbl_init(LL))
  save_tree(fp, spec);
}
