/***********************************
  (C) Copyright 1992-1993; dit/upm
   Distributed under the conditions stated in the
   TOPO General Public License (see file LICENSE)
 ***********************************
 $Log: pecast.h,v $
 * Revision 1.16  1993/09/20  14:23:00  lotos
 * cut and ln (link) functions moved to EPS
 *
 * Revision 1.15  1993/06/10  14:00:13  lotos
 * new annotation CALL
 *
 * Revision 1.14  1993/03/29  18:09:10  lotos
 * add constructor verification/s
 *
 * Revision 1.13  1993/03/24  17:51:24  lotos
 * annotations lcd, and ldcinit go into ATable
 * unused attribute handling functions (now in glad)
 *
 * Revision 1.12  1993/01/18  18:12:15  lotos
 * distribution issues
 *
 * Revision 1.11  1992/12/02  10:56:54  lotos
 * new code to remove ldc and ldcinit annotations
 *
 * Revision 1.10  1992/11/17  18:40:50  lotos
 * parse annotation must be a single word
 * uses color c_cui, c_cso, and c_cop rather than c_ui, c_so, and c_op
 *
 * Revision 1.9  1992/10/14  17:42:16  lotos
 * fix error in macro definition (no debugging option)
 *
 * Revision 1.8  1992/09/02  15:44:42  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.7  92/05/06  18:48:43  lotos
 * minor bugs
 * 
 * Revision 1.6  92/01/14  15:25:05  lotos
 * distribution issues
 * 
 * Revision 1.5  92/01/13  19:24:14  lotos
 * adaptec to ophuscate
 * 
 * Revision 1.4  91/11/20  13:06:44  lotos
 * parse attribute added
 * 
 * Revision 1.3  91/10/02  16:48:45  lotos
 * color sort is now in the AT
 * 
 * Revision 1.2  91/04/11  18:30:41  lotos
 * remove bool and true [pre]definitions
 * 
 * Revision 1.1  91/02/06  20:12:26  lotos
 * Initial revision
 * 
 ***********************************/

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

     "pecast.h": cabecera de "pecast.o".

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

#ifndef PECAST_H
#define PECAST_H

#include "cast.hh"


#include "colours.h"
#define c_anyeq		100	/* Tiene ecuaciones. */
#define c_pvar		101	/* Puntero a una variable. */
#define c_eqno		102	/* Numero de ecuacion. */
#define c_oveq		103	/* Ecuacion en version original. */

/* Valores posibles del atributo "idclass". */
#define spec_id		 1
#define type_id		 2
#define sort_id		 3
#define opn_id		 4
#define proc_id		 5
#define gate_id		 6
#define value_id	 7

/* Valores posibles del atributo "class" segun el tipo de nodo. */
#define const_opn	0x5	/*    <operation>		*/
#define real_opn	0x7	/*	  "			*/


/* Devuelve el valor de un atributo. */
CLR_TYPE _attr_value();
#ifdef DESARROLLO
#  define attr_value(nodep, attr_name, attr_type) \
	    ((attr_type) _attr_value(nodep, attr_name))
#else
#  define attr_value(nodep, attr_name, attr_type) \
	    ((attr_type) find_attr((attr_name), (nodep))->value)
#endif

/* Devuelve el valor de un atributo ligado a un nodo. */
#define HWattr_value(nodep, attr_pos, attr_type) \
	  eval_si((nodep) != NULL, (attr_type) (nodep)->attr_pos)

/* Devuelve el valor del primer atributo ligado a un nodo. */
#define HWattr0_value(nodep, attr_type) \
	  HWattr_value(nodep, value0, attr_type)

/* Devuelve el valor del segundo atributo ligado a un nodo. */
#define HWattr1_value(nodep, attr_type) \
	  HWattr_value(nodep, value1, attr_type)

/* Si esta, devuelve el valor del atributo, si no, "not_found_value". */
CLR_TYPE _find_attr_value();
#define find_attr_value(nodep, attr_name, attr_type, not_found_value)  \
	  ((attr_type) _find_attr_value(nodep, attr_name,	       \
					(CLR_TYPE) (not_found_value)))

/* Anade un atributo con su valor. */
void _add_attr_value();
#ifdef DESARROLLO
#  define add_attr_value(nodep, attr_name, attr_value) \
	    _add_attr_value(nodep, attr_name, (CLR_TYPE) (attr_value))
#else
#  define add_attr_value(nodep, attr_name, attr_value)		\
	    ((void) (add_attr((attr_name), (nodep))->value=	\
		       (CLR_TYPE) (attr_value)))
#endif

/* Anade el valor de un atributo ligado a un nodo. */
#define add_HWattr_value(nodep, attr_pos, attr_value)		\
	  eval_si((nodep) != NULL && (nodep)->attr_pos == NULL,	\
		  (void) ((nodep)->attr_pos=			\
			    (CLR_TYPE) (attr_value)))

/* Anade el valor del primer atributo ligado a un nodo. */
#define add_HWattr0_value(nodep, attr_value) \
	  add_HWattr_value(nodep, value0, attr_value)

/* Anade el valor del segundo atributo ligado a un nodo. */
#define add_HWattr1_value(nodep, attr_value) \
	  add_HWattr_value(nodep, value1, attr_value)

/* Elimina un atributo con su valor. */
void _del_attr_value();
#ifdef DESARROLLO
#  define del_attr_value(nodep, attr_name) \
	    _del_attr_value(nodep, attr_name)
#else
#  define del_attr_value(nodep, attr_name) \
	    free_attr(take_attr((attr_name), (nodep)))
#endif

/* Elimina un atributo, si existe, con su valor. */
void _fdel_attr_value();
#define fdel_attr_value(nodep, attr_name) \
	  _fdel_attr_value(nodep, attr_name)

#ifndef lint
#define PTR_ERR		((void *) 1)
#define STR_ERR		((char *) 1)
#define TND_ERR		((TNODE *) 1)
#else
#define PTR_ERR		NULL
#define STR_ERR		NULL
#define TND_ERR		NULL
#endif

typedef struct
{ AT *AT;	/* Tabla de atributos. */
  IAT *GRNL;	/* Tabla de listas de reglas gramaticales. */
  ST *LL;	/* Tabla de simbolos. */
} TSTBL;	/* Tipo para manejar tablas de una especificacion. */

/* Atributos con las tablas de la especificacion. */
#define CSTBL	c_at, c_grnl, c_ll

extern TSTBL _stbl;		/* Tablas de la especificacion. */

/* Indica si una tabla de la especificacion esta inicializada. */
#define is_stbl_init(name)	(_stbl.name != NULL)

/* Devuelve un puntero a una tabla de la especificacion. */
#define stbl_ptr(name)	eval_si(is_stbl_init(name), _stbl.name)

/* Indica si es un elemento de una tabla de la especificacion. */
#define is_stbl_entry(name, ndx)	\
	 (is_stbl_init(name) &&		\
	  0 <= (ndx) &&			\
	  (ndx) < _stbl.name->size)

/* Devuelve un elemento de una tabla de la especificacion. */
#define stbl_entry(name, ndx) \
	  eval_si(is_stbl_entry(name, ndx), _stbl.name->data + ndx)

/* Igual que "attr_value()", pero para la tabla de atributos. */
CLR_TYPE _AT_attr_value();
#ifdef DESARROLLO
#  define AT_attr_value(ndx, attr_name, attr_type) \
	    ((attr_type) _AT_attr_value(ndx, attr_name))
#else
#  define AT_attr_value(ndx, attr_name, attr_type) \
	    ((attr_type) ATfind(_stbl.AT, ndx, attr_name)->value)
#endif

/* Igual que "HWattr_value()", pero para la tabla de atributos. */
#define AT_HWattr_value(ndx, attr_pos, attr_type)		\
	  eval_si(is_stbl_entry(AT, ndx),			\
		  (attr_type) _stbl.AT->data[ndx].attr_pos)

/* Igual que "HWattr0_value()", pero para la tabla de atributos. */
#define AT_HWattr0_value(ndx, attr_type) \
	  AT_HWattr_value(ndx, value0, attr_type)

/* Igual que "HWattr1_value()", pero para la tabla de atributos. */
#define AT_HWattr1_value(ndx, attr_type) \
	  AT_HWattr_value(ndx, value1, attr_type)

/* Igual que "find_attr_value()", pero para la tabla de atributos. */
CLR_TYPE _AT_find_attr_value();
#define AT_find_attr_value(ndx, attr_name, attr_type, not_found_value) \
	  ((attr_type) _AT_find_attr_value(ndx, attr_name,	       \
					   (CLR_TYPE)		       \
					   (not_found_value)))

/* Igual que "add_attr_value()", pero para la tabla de atributos. */
void _AT_add_attr_value();
#ifdef DESARROLLO
#  define AT_add_attr_value(ndx, attr_name, attr_value) \
	    _AT_add_attr_value(ndx, attr_name, (CLR_TYPE) (attr_value))
#else
#  define AT_add_attr_value(ndx, attr_name, attr_value)		\
	    ((void) (ATadd(_stbl.AT, ndx, attr_name)->value=	\
		       (CLR_TYPE) (attr_value)))
#endif

/* Igual que "add_HWattr_value()", pero para la tabla de atributos. */
#define AT_add_HWattr_value(ndx, attr_pos, attr_value)		\
	  eval_si(is_stbl_entry(AT, ndx) &&			\
		  stbl_entry(AT, ndx)->attr_pos == NULL,	\
		  (void) (stbl_entry(AT, ndx)->attr_pos=	\
			    (CLR_TYPE) (attr_value)))

/* Igual que "add_HWattr0_value()", pero para la tabla de atributos. */
#define AT_add_HWattr0_value(ndx, attr_value) \
	  AT_add_HWattr_value(ndx, value0, attr_value)

/* Igual que "add_HWattr1_value()", pero para la tabla de atributos. */
#define AT_add_HWattr1_value(ndx, attr_value) \
	  AT_add_HWattr_value(ndx, value1, attr_value)

/* Igual que "del_attr_value()", pero para la tabla de atributos. */
void _AT_del_attr_value();
#ifdef DESARROLLO
#  define AT_del_attr_value(ndx, attr_name) \
	    _AT_del_attr_value(ndx, attr_name)
#else
#  define AT_del_attr_value(ndx, attr_name) \
	    free_attr(ATtake(_stbl.AT, ndx, attr_name))
#endif

/* Igual que "fdel_attr_value()", pero para la tabla de atributos. */
void _AT_fdel_attr_value();
#define AT_fdel_attr_value(ndx, attr_name) \
	  _AT_fdel_attr_value(ndx, attr_name)

/* Devuelve el valor del atributo "at". */
#define at(nodep)	attr_value(nodep, c_at, AT *)

/* Devuelve el valor del atributo "grnl". */
#define grnl(nodep)	attr_value(nodep, c_grnl, IAT *)

/* Devuelve el valor del atributo "ll". */
#define ll(nodep)	attr_value(nodep, c_ll, ST *)

/* Devuelve el valor del atributo "lexv". */
#define ask_lexv(idn)	AT_HWattr1_value(idn, int)

/* Devuelve el valor del pseudo-atributo "lexv". */
#define lexv(idn)	(*stbl_entry(LL, ask_lexv(idn)))

/* Anade el atributo "lexv" con su valor. */
#define add_lexv(idn, val)	AT_add_HWattr1_value(idn, val)

/* Devuelve el valor del atributo "line". */
#define ask_line(nodep)	attr_value(nodep, c_line, int *)

/* Devuelve el valor del pseudo-atributo "file". */
#define file(nodep)	(*stbl_entry(LL, ask_line(nodep)[1]))

/* Devuelve el valor del pseudo-atributo "line". */
#define line(nodep)	(ask_line(nodep)[0])

/* Anade el atributo "line" con su valor. */
#define add_line(nodep, val)	add_attr_value(nodep, c_line, val)

/* Devuelve el valor del atributo "grn". */
#define ask_grn(nodep)	HWattr0_value(nodep, int)

/* Devuelve el valor del pseudo-atributo "grn". */
#define grn(nodep)	(*stbl_entry(GRNL, ask_grn(nodep)))

/* Anade el atributo "grn" con su valor. */
#define add_grn(nodep, val)	add_HWattr0_value(nodep, val)

/* Devuelve el valor del atributo "class". */
#define class(nodep)	HWattr1_value(nodep, int)

/* Anade el atributo "class" con su valor. */
#define add_class(nodep, val)	add_HWattr1_value(nodep, val)

/* Devuelve el valor del atributo "draw". */
#define v_draw(idn) \
	  AT_find_attr_value(idn, c_draw, char *, NULL)

/* Devuelve el valor del atributo "parse". */
#define v_parse(idn) \
	  AT_find_attr_value(idn, c_parse, char *, NULL)

/* Devuelve el valor del atributo "equal". */
#define v_equal(idn) \
	  AT_find_attr_value(idn, c_equal, char *, NULL)

/* Devuelve el valor del atributo "extern". */
#define v_extern(idn) \
	  AT_find_attr_value(idn, c_extern, char *, STR_ERR)

/* Devuelve el valor del atributo "free". */
#define v_free(idn) \
	  AT_find_attr_value(idn, c_free, char *, NULL)

/* Devuelve el valor del atributo "idclass". */
#define idclass(idn)	AT_HWattr0_value(idn, int)

/* Anade el atributo "idclass" con su valor. */
#define add_idclass(idn, val)	AT_add_HWattr0_value(idn, val)

/* Devuelve el valor del atributo "iddec". */
#define iddec(nodep)	attr_value(nodep, c_iddec, int)

/* Devuelve el valor del atributo "ldc". */
#define ldc(idn)	AT_find_attr_value(idn, c_ldc, char *, NULL)

/* Devuelve el valor del atributo "ldcinit". */
#define ldcinit(idn)	AT_find_attr_value(idn, c_ldcinit, char *, NULL)

/* Devuelve el valor del atributo "idref". */
#define idref(nodep)	attr_value(nodep, c_idref, int)

/* Anade el atributo "idref" con su valor. */
#define add_idref(nodep, val)	add_attr_value(nodep, c_idref, val)

/* Elimina el atributo "idref" con su valor . */
#define del_idref(nodep)	del_attr_value(nodep, c_idref)

/* Devuelve el valor del atributo "infix". */
#define infix(idn)	AT_find_attr_value(idn, c_infix, int, -1)

/* Devuelve el valor del atributo "name". */
#define name(idn)	AT_find_attr_value(idn, c_name, char *, NULL)

/* Devuelve el valor del atributo "call". */
#define call(idn)	AT_find_attr_value(idn, c_call, char *, NULL)

/* Devuelve el valor del atributo "nonconstructor". */
#define nonconstructor(idn) \
	  AT_find_attr_value(idn, c_nonconstructor, char *, STR_ERR)

/* Devuelve el valor del atributo "partial". */
#define partial(idn)	AT_find_attr_value(idn, c_partial, char *, NULL)

/* Devuelve el valor del atributo "sort". */
#define sort(idn)	AT_attr_value(idn, c_sort, int)

/* Anade el atributo "sort" con su valor. */
#define add_sort(idn, val)	AT_add_attr_value(idn, c_sort, val)

/* Devuelve el valor del atributo "cui". */
#define v_cui(idn)	AT_attr_value(idn, c_cui, int)

/* Devuelve el valor del atributo "ui". */
#define v_ui(idn)	AT_attr_value(idn, c_ui, int)

/* Anade el atributo "ui" con su valor. */
#define add_ui(idn, val)	AT_add_attr_value(idn, c_ui, val)

/* Elimina el atributo "ui" con su valor . */
#define del_ui(idn)	AT_del_attr_value(idn, c_ui)

/* Devuelve el valor del atributo "cso". */
#define v_cso(nodep)	attr_value(nodep, c_cso, int)

/* Devuelve el valor del atributo "cop". */
#define v_cop(nodep)	attr_value(nodep, c_cop, int)

/* Devuelve el valor del atributo "va". */
#define v_va(nodep)	attr_value(nodep, c_va, int)

/* Devuelve el valor del atributo "luid". */
#define luid(nodep)	attr_value(nodep, c_luid, int)

/* Anade el atributo "luid" con su valor. */
#define add_luid(nodep, val)	add_attr_value(nodep, c_luid, val)

/* Elimina el atributo "luid" con su valor . */
#define del_luid(nodep)	del_attr_value(nodep, c_luid)

/* Devuelve el valor del atributo "spec". */
#define v_spec(nodep)	attr_value(nodep, c_spec, int)

/* Devuelve el valor del atributo "endspec". */
#define v_endspec(nodep)	attr_value(nodep, c_endspec, int)

/* Devuelve el valor del atributo "anyeq". */
#define anyeq(idn)	AT_find_attr_value(idn, c_anyeq, int, -1)

/* Anade el atributo "anyeq" con su valor. */
#define add_anyeq(idn, val)	AT_add_attr_value(idn, c_anyeq, val)

/* Devuelve el valor del atributo "pvar". */
#define pvar(nodep)	attr_value(nodep, c_pvar, TNODE *)

/* Anade el atributo "pvar" con su valor. */
#define add_pvar(nodep, val)	add_attr_value(nodep, c_pvar, val)

/* Devuelve el valor del atributo "eqno". */
#define eqno(nodep)	attr_value(nodep, c_eqno, int)

/* Anade el atributo "eqno" con su valor. */
#define add_eqno(nodep, val)	add_attr_value(nodep, c_eqno, val)

/* Devuelve el valor del atributo "oveq". */
#define oveq(nodep)	find_attr_value(nodep, c_oveq, TNODE *, TND_ERR)

/* Anade el atributo "oveq" con su valor. */
#define add_oveq(nodep, val)	add_attr_value(nodep, c_oveq, val)

#define attr2name(attr)	(type2clr(attr)->keyword)
/* Obtiene y devuelve el nombre de un atributo a partir de su codigo. */

TNODE *load_spec();
/* Carga el AST de una especificacion. */

void save_spec();
/* Almacena el AST de una especificacion. */

#endif
