/*def.h - def file parser*/
#ifndef def_H
#define def_H

#ifndef types_H
   #include "oslib/types.h"
#endif

#define def_ID_LIMIT 255  /* max number of names of types */

#define def_C_PLUS_PLUS_LIMIT 1023

#define def_STRUCT_LIMIT 64 /* max number of members in in a single struct */
#define def_UNION_LIMIT  64 /* max number of members in in a single union */

#define def_DESCRIPTION_LIMIT 255 /* max number of chars in a description */

#define def_FLAGS 15 /*number to be used signifying returned flags*/

typedef enum
        { def_VALUE_REGISTER,
          def_VALUE_FIXED,
          def_VALUE_VARIABLE  /* structure contains ellipsis */
        }
        def_value;

typedef
   struct def_c
   {  int value;
      struct def_t *type;

      char *description;
   }
   *def_c;

typedef
   enum
   {  def_TYPE_INT,
      def_TYPE_SHORT,
      def_TYPE_BYTE,
      def_TYPE_CHAR,
      def_TYPE_BITS,
      def_TYPE_BYTES,
      def_TYPE_BOOL,
      def_TYPE_REF,
      def_TYPE_STRING,
      def_TYPE_ASM,
      def_TYPE_DATA,
      def_TYPE_STRUCT,
      def_TYPE_UNION,
      def_TYPE_LIST,
      def_TYPE_ROW,
      def_TYPE_VOID,
      def_TYPE_ID,
      def_TYPE_ABSTRACT
   }
   def_type;

typedef enum{ def_OP_DISJOINS,
              def_OP_CONJOINS,
              def_OP_ADDS,
              def_OP_EXCLUSIVELY_DISJOINS
            } def_op;


/* structure created when parser encounters a type definition */
typedef
   struct def_t
   {  def_type tag;     /* type of entry */
      char *name;       /* type name, if any */
      def_value value;  /* register type? */
      char *description;/* NULL if empty, else pointer to description */

      union
      {  /*INT, SHORT, BYTE, CHAR, BITS, BYTES, BOOL*/

         /*REF*/
         struct def_t *ref;

         /*STRING, ASM, DATA*/

         /*STRUCT, UNION, LIST*/
         struct
         {  int count;          /* number of members */
            osbool ellipsis;    /* definition contains ellipsis */
            struct def_t *base; /* pointer to base type definition, if present */
            struct def_t *members [def_STRUCT_LIMIT + def_UNION_LIMIT];
                                /* array of pointers to members */
         }
         list;

         /*ROW*/
         struct
         {  int count;
            struct def_t *base;
         }
         row;

         /*VOID*/

         /*ID*/
         char id [def_ID_LIMIT + 1];
      } data;
   }
   *def_t;

#define def_sizeof_TYPE(t) \
   (  offsetof (struct def_t, data) + \
      (  t == def_TYPE_REF? \
            sizeof ((def_t) NULL)->data AS ref: \
         t == def_TYPE_STRUCT || t == def_TYPE_UNION || t == def_TYPE_LIST? \
            sizeof ((def_t) NULL)->data AS list: \
         t == def_TYPE_ROW? \
            sizeof ((def_t) NULL)->data AS row: \
         t == def_TYPE_ID? \
            sizeof ((def_t) NULL)->data AS id: \
            0 \
      ) \
   )


/* structure created when parser encounters a SWI definition */
typedef
   struct def_s
   {  int swi; /*SWI number*/
      bits  i, /*set of input registers*/
            o, /*set of output registers*/
            c, /*set of corrupted registers*/
            k; /*set of constant input registers*/
      osbool  f_in  /*want flags on input?*/,
              f_out /*output?*/;

      struct def_t *inputs [10]; /*typed_vars for input args (if i set)*/
      struct def_t *outputs [10]; /*typed_vars for output args (if o set)*/
      int constants [10]; /*values to load constants with (if k set)*/
      bits ri, ro; /*true if REFERENCES rather than CONTAINS*/

      osbool starred_swi; /*TRUE if swi = (NUMBER NUM*, ...)*/
      osbool starred_constants [10]; /*TRUE if ENTRY (REG CONSTANT NUM*, ...)*/

      osbool absent; /*swi definition is absent*/

      def_op op [10]; /*operation for register*/

      bits value; /*if register R is to be returned as a value (in the non-X
         form), bit R is set*/

      char *description;
   }
   *def_s;

/* copy the char string at s1 into s0
** in the form "ModuleName_FOO_BAR" */
extern void def_as_macro (char *s0, const char *s1);

/* copy the char string at s1 into s0
** in the form "ModuleName_foo_bar" */
extern void def_as_extern (char *s0, const char *s1);

/* copy the char string at s1 into s0
** in the form "ModuleName" */
extern void def_as_prefix( char* s0, char* s1 );

extern void def_as_c_plus_plus (char *, char *, def_s);

extern osbool def_using_block (def_s);

extern int def_bit_index (bits i, int arg);
   /*the index of the |arg|'th set bit of |i|.*/

/* create a copy of string s on the heap
**  return a pointer to the heap block
**  defined in defmod.y */
extern char *qstrdup (const char *);

extern osbool def_inlinable (def_s);

#endif
