#ifndef _SPASS_SYMBOL_
#define _SPASS_SYMBOL_ 
#include "memory.h"
#include "array.h"
#include "strings.h"
typedef int TYPE;
typedef struct typesig {
  char *name;
  NAT length;
  int arity;
  TYPE *arguments;
} SYMBTYPESIG_NODE, *SYMBTYPESIG;
typedef TYPE *TYPING;
typedef void (*SYMBVALDEL)(MEMORY, intptr_t);
typedef BOOL (*SYMBVALEQUAL)(intptr_t, intptr_t);
typedef intptr_t (*SYMBVALCOPY)(MEMORY, intptr_t);
typedef void (*SYMBVALPRINT)(FILE*, intptr_t);
typedef intptr_t SYMBOL;
typedef enum {CONSTANT=1, VALUECONSTANT=2, FUNCTION=3, PREDICATE=4, OPERATOR=5, SYMBTBITS=3, SYMBTMASK=7
} SYMBTYPE;
typedef struct symbsig {
  char *name;
  NAT length;
  int index;
  int arity;
  intptr_t value;
  TYPE result;
  NAT mark;
  SYMBTYPE type;
  NAT precedence;
  NAT weight;
  union {
    TYPE *arguments;
    struct avalfunc {
      SYMBVALDEL delfunc;
      SYMBVALEQUAL equalfunc;
      SYMBVALCOPY copyfunc;
      SYMBVALPRINT printfunc;
    } avalfuncs;
  } tdinfo;
} SYMBSIG_NODE, *SYMBSIG;
typedef struct symbstate {
  MEMORY mem;
  SYMBTYPESIG typesig;
  unsigned typesigsize;
  unsigned typesiglength;
  SYMBSIG sig;
  unsigned sigsize;
  unsigned siglength;
  unsigned maxvars;
  unsigned svarcounter;
  unsigned ivarcounter;
  NAT symbmark;
  NAT *varmark;
  intptr_t *varvalue;
  NAT bindmark;
  BOOL bindphase;
  TYPE dummytype;
  SYMBOL dummyconstant;
  SYMBOL idleconstant;
} SYMBSTATE_NODE, *SYMBSTATE;
TYPE symbol_CreateTypeConstant(SYMBSTATE, const char *);
TYPE symbol_CreateTypeClass(SYMBSTATE, const char *, int);
TYPE symbol_GetDummyType(SYMBSTATE);
void symbol_ClassAddType(SYMBSTATE, TYPE, TYPE , int);
BOOL symbol_TypeClassContainsType(SYMBSTATE, TYPE, TYPE);
char* symbol_TypeName(SYMBSTATE, TYPE);
BOOL symbol_IsConstantType(SYMBSTATE, TYPE);
BOOL symbol_IsConstructorType(SYMBSTATE, TYPE);
BOOL symbol_IsClassType(SYMBSTATE, TYPE);
void symbol_PrintType(SYMBSTATE, TYPE);
SYMBSTATE symbol_Init(MEMORY, int, int, int);
void symbol_Free(SYMBSTATE);
SYMBSIG symbol_GetStateSig(SYMBSTATE);
MEMORY symbol_GetStateMemory(SYMBSTATE);
unsigned symbol_GetStateSigLength(SYMBSTATE);
SYMBOL symbol_CreateConstant(SYMBSTATE, TYPE, const char *);
SYMBOL symbol_CreateValueConstant(SYMBSTATE, TYPE, const char *, SYMBVALDEL, SYMBVALPRINT, SYMBVALCOPY, SYMBVALEQUAL);
SYMBOL symbol_CreatePredicate(SYMBSTATE, TYPE, const char *, int);
SYMBOL symbol_CreateFunction(SYMBSTATE, TYPE, const char *, int);
SYMBOL symbol_CreateOperator(SYMBSTATE, TYPE, const char *, int);
void symbol_SetArgumentType(SYMBSTATE, SYMBOL, TYPE, int);
void symbol_AdjustStateMaxVarsLimit(SYMBSTATE, unsigned);
intptr_t symbol_GetValue(SYMBSTATE, SYMBOL);
void symbol_SetValue(SYMBSTATE, SYMBOL, intptr_t);
void symbol_CleanAllValues(SYMBSTATE);
BOOL symbol_ValueUndefined(SYMBSTATE, SYMBOL);
int symbol_GetArity(SYMBSTATE, SYMBOL);
char * symbol_GetName(SYMBSTATE, SYMBOL);
void symbol_SetName(SYMBSTATE, SYMBOL, const char*);
TYPE symbol_GetResultType(SYMBSTATE, SYMBOL);
TYPE * symbol_GetArgumentTypes(SYMBSTATE, SYMBOL);
SYMBVALDEL symbol_GetDelFunc(SYMBSTATE, SYMBOL);
SYMBVALCOPY symbol_GetCopyFunc(SYMBSTATE, SYMBOL);
SYMBVALEQUAL symbol_GetEqualFunc(SYMBSTATE, SYMBOL);
SYMBVALPRINT symbol_GetPrintFunc(SYMBSTATE, SYMBOL);
SYMBOL symbol_GetDummyConstant(SYMBSTATE);
SYMBOL symbol_GetIdleConstant(SYMBSTATE);
void symbol_PrintSigDetailed(SYMBSTATE, SYMBOL);
void symbol_Print(SYMBSTATE, SYMBOL);
void symbol_FPrint(FILE*, SYMBSTATE, SYMBOL);
void symbol_FPrintTPTPVariable(FILE*, SYMBOL);
int symbol_GetMaxVars(SYMBSTATE);
int symbol_GetNextStandardVar(SYMBSTATE);
int symbol_MinimalStandardVar(void);
void symbol_ResetStandardVarCounterVariable(SYMBSTATE, SYMBOL);
void symbol_ResetStandardVarCounterNonZero(SYMBSTATE);
void symbol_ResetStandardVarCounter(SYMBSTATE);
void symbol_SetStandardVarCounter(SYMBSTATE, int);
int symbol_GetStandardVarCounter(SYMBSTATE);
BOOL symbol_IsVariable(SYMBSTATE, SYMBOL);
BOOL symbol_IsVariableFast(SYMBOL);
BOOL symbol_IsConstant(SYMBOL);
BOOL symbol_IsValueConstant(SYMBOL);
BOOL symbol_IsFunction(SYMBOL);
BOOL symbol_IsPredicate(SYMBOL);
BOOL symbol_IsOperator(SYMBOL);
BOOL symbol_IsSymbol(SYMBSTATE, SYMBOL);
BOOL symbol_IsSigSymbol(SYMBSTATE, SYMBOL);
BOOL symbol_Equal(SYMBOL, SYMBOL);
int symbol_Compare( SYMBOL, SYMBOL);
int symbol_CompareName(SYMBSTATE, SYMBOL, SYMBOL );
#if defined(SPASS_SYMBOL_INDEXVARS)
BOOL symbol_IsStandardVariable(SYMBSTATE, SYMBOL);
BOOL symbol_IsIndexVariable(SYMBSTATE, SYMBOL);
int symbol_GetNextIndexVar(SYMBSTATE);
#endif
NAT symbol_NewSigMark(SYMBSTATE, BOOL);
void symbol_SetSigMark(SYMBSTATE, SYMBOL, NAT);
NAT symbol_GetSigMark(SYMBSTATE, SYMBOL);
BOOL symbol_SigIsMarked(SYMBSTATE, SYMBOL, NAT);
unsigned symbol_GetIndex(SYMBOL);
SYMBOL symbol_IndexGetSymbol(SYMBSTATE, int);
SYMBOL symbol_SetIndexType(int, SYMBTYPE);
void symbol_StartBinding(SYMBSTATE);
void symbol_StopBinding(SYMBSTATE);
BOOL symbol_InBindingPhase(SYMBSTATE);
NAT symbol_NewMark(SYMBSTATE);
NAT symbol_OldMark(SYMBSTATE);
NAT symbol_NullMark(void);
void symbol_CreateBinding(SYMBSTATE symbstate, SYMBOL , NAT Mark);
void symbol_CreateValueBinding(SYMBSTATE, SYMBOL, NAT, intptr_t);
intptr_t symbol_BindingValue(SYMBSTATE, SYMBOL);
NAT symbol_GetBindingMark(SYMBSTATE, SYMBOL);
BOOL symbol_VarIsMarked(SYMBSTATE, SYMBOL, NAT);
void symbol_SetBindingMark(SYMBSTATE, SYMBOL, NAT);
void symbol_SetBindingValue(SYMBSTATE, SYMBOL, intptr_t);
TYPING symbol_CreateVarTyping(MEMORY, int);
unsigned symbol_VarTypingSize(TYPING);
TYPING symbol_CopyVarTyping(MEMORY, TYPING, int);
void symbol_DeleteVarTyping(MEMORY, TYPING);
void symbol_SetVarTyping(TYPING, SYMBOL, TYPE);
void symbol_ClearVarTyping(SYMBSTATE,TYPING, SYMBOL);
void symbol_ReplaceVarTyping(TYPING, TYPING, SYMBOL);
TYPING symbol_ExtendVarTyping(MEMORY, TYPING, int);
TYPE symbol_GetVarTypingType(TYPING, SYMBOL);
void symbol_PrintVarTypingType(SYMBSTATE,TYPE);
void symbol_PrintTyping(SYMBSTATE,TYPING);
BOOL symbol_PrecedenceGreater(SYMBSTATE, SYMBOL, SYMBOL);
BOOL symbol_PrecedenceSmaller(SYMBSTATE, SYMBOL, SYMBOL);
void symbol_SetPrecedence(SYMBSTATE, SYMBOL, NAT);
void symbol_SetWeight(SYMBSTATE, SYMBOL, NAT);
NAT symbol_GetWeight(SYMBSTATE, SYMBOL);
void symbol_SigSetPrecedenceWeight(SYMBSIG , unsigned, NAT, NAT);
BOOL symbol_SigIsConstant(SYMBSIG , unsigned);
#endif
