/*
    mmorph, MULTEXT morphology tool
    Version 2.3, October 1995
    Copyright (c) 1994,1995 ISSCO/SUISSETRA, Geneva, Switzerland
    Dominique Petitpierre, <petitp@divsun.unige.ch>
*/
#ifndef symbols_h
#define symbols_h

#include <values.h>
#define MAXVAL BITS(t_value)

#ifndef lint
typedef enum {
    Attribute = 0,
#define FIRST_SYM_KIND  Attribute
    Pair,
    Rule,
    Spelling,
    Type,
    Value,
#define SYM_TABLES_NUMBER Value
    Variable,
    Surface_Letter,
    Lexical_Letter,
    Pair_Letter,
    Surface_Class,
    Lexical_Class,
    Pair_Class,
    Lexicon,
    Alphabet,
    _last_symbol_kind
}           e_symbol_kind;

#else
/* use defines to shutup lint */
#define Attribute	    0
#define FIRST_SYM_KIND	    Attribute
#define Pair		    1
#define Rule		    2
#define Spelling	    3
#define Type		    4
#define Value		    5
#define SYM_TABLES_NUMBER   Value
#define Variable	    6
#define Surface_Letter	    7
#define Lexical_Letter	    8
#define Pair_Letter	    9
#define Surface_Class	    10
#define Lexical_Class	    11
#define Pair_Class	    12
#define Lexicon		    13
#define Alphabet	    14
#define _last_symbol_kind   15
typedef int e_symbol_kind;

#endif	/* !lint */

#define SURFACE_IS_CLASS    (1L)
#define LEXICAL_IS_CLASS    (1L << 1)
#define BOTH_LETTERS	    (0L)
#define BOTH_CLASSES	    (SURFACE_IS_CLASS|LEXICAL_IS_CLASS)

typedef struct symbol_s {
    e_symbol_kind kind;	/* kind of the symbol; not strictly necessary */
    t_str       name;
    t_card      ordinal;
    union data_u *data;
}           s_symbol;

typedef struct {
    e_symbol_kind kind;	/* kind of the symbol; not strictly necessary */
    t_card      card;	/* cardinality of the symbol set */
    s_symbol   *table;	/* associated symbol table */
    s_symbol  **ref;	/* associated array of all symbols */
}           s_symbol_set;

typedef struct {
    s_symbol_set value_set;
}           s_attribute;

typedef struct pair_s {
    t_flag      pair_flags;
    t_letter   *surface;
    t_letter   *lexical;
    struct pair_s *next;
}           s_pair;

/* s_class should be of exactly the same structure as s_pair */
typedef struct class_s {
    t_flag      pair_flags;
    s_bitmap   *surface;
    s_bitmap   *lexical;
    struct pair_s *next;
}           s_class;

typedef struct {
    s_symbol_set variable_set;
    s_rule_instance *instance;
}           s_rule;

typedef struct {
    s_spell_instance *instance;
    s_rule     *constraint;
}           s_spelling;

typedef struct {
    t_card      card;
    s_symbol  **attribute_ref;	/* list of references to attributes */
    t_card      project_card;	/* last attribute to keep in the end */
}           s_type;

typedef struct {
    s_symbol   *attribute_link;	/* backward pointer to the attribute */
}           s_value;

typedef struct {
    s_symbol   *attribute_link;	/* attribute the variable is for */
    t_index     tfs_index[3];	/* att index in the tfs: lhs, first second */
}           s_variable;

typedef union data_u {
    s_attribute attribute;
    s_pair      pair;
    s_rule      rule;
    s_spelling  spelling;
    s_type      type;
    s_value     value;
    s_variable  variable;
    s_class     class;
}           u_data;

extern s_symbol_set symbol_set[SYM_TABLES_NUMBER];	/* independant symbols */
extern t_str symbol_kind_str[];
extern e_symbol_kind defined_kind;
extern s_symbol **new_symbol( /* t_str name, s_symbol **table */ );
extern s_symbol **find_symbol( /* t_str name, s_symbol **table */ );
extern void init_symbol();
extern void init_symbol_set();
extern void print_symbols_by_ref();
extern void print_symbol_table();
extern void make_symbol_reference();
extern void ref_is_item();
extern t_ptr *new_ref();
extern void link_attribute();
extern void add_pair();
extern s_tfs *new_tfs();
extern void fill_tfs_with_variables();
extern void ident_var_map();
extern void free_tfs();
extern void print_tfs1();
extern void print_tfs();
extern void print_tfs_proj();
extern void print_tfs_proj_tbl();
extern int  reference_position();
extern void adjust_var_map();

#endif	/* symbols_h */
