#include "stdnil.h"
#include "listp.h"
#include "li.h"

typedef struct shape_record_struct shape_record;
typedef struct shape_variant_struct shape_variant;
typedef struct shape_table_struct shape_table;
typedef struct shape_polymorph_struct shape_polymorph;
typedef struct shape_program_struct shape_program;
typedef struct shape_callmessage_struct shape_callmessage;

typedef union shapecell_union
{
  shape_record *record;
  shape_variant *variant;
  shape_table *table;
  shape_polymorph *polymorph;
  shape_callmessage *callmessage;
  shape_program *program;
} shapecell;

typedef struct shape_struct {
  datarep *tsdr;         /* basically used only to denote what type class
                            we're in */

  shapecell value;      /* 'value' of the shape; i.e. the instance independant
                           information about this type.  Usually a pointer
                           to the struct containing the actual information */
} shapeobj, *shapep;

typedef struct shape_table_struct {
  dfd_table *tbl;      /* pointer to info of table we're looking at */
  shapeobj elt_shape;    /* shape of elements */
  counter size;        /* if size is 0, then tbl points to a dfd_table with */
                       /* an unreliable tsdr.  If size > 0, then tbl points */
                       /* to a complete tsdr. */
  /* elt_shape.tsdr will be &dr_bottom if we don't know the shape of the
     elements yet, or if the table is a charstring.  If the table is a 
     charstring, and size is > 0, it is possible that tbl->tsdr will be
     different from elt_shape.tsdr */
} /* shape_table */;

typedef struct shape_variant_struct {
  variant_info variant_case;    /* the case of the variant */
  shapeobj contents_shape;   /* pointer to shape of contents */
  shape_variant *next;  /* pointer to next case in the list */
} /* shape_variant */;

typedef struct shape_callmessage_struct {
  counter size;          /* number of fields in callmessage */
  shapeobj data[ARBSIZE];  /* shapes of the fields */
} /* shape_callmessage */;

typedef struct shape_record_struct {
  counter size;          /* number of fields in record */
  shapeobj data[ARBSIZE];  /* shapes of the fields */
} /* shape_record */ ;

typedef struct shape_program_struct {
  counter size;
  shapeobj data[ARBSIZE];
} /* shape_program */;

typedef struct shape_polymorph_struct {
  shapeobj typename;  /* shape of the typename structure */
  shapeobj typestate; /* shape of typestate */
  shapeobj obj;       /* shape of object.  Always set to bottom first */
} /* shape_polymorph */;

