/* ---------------------------------------------------------------------- */
/*                   Copyright (C) 1991 by NatЃrlich!                     */
/*                      This file is copyrighted!                         */
/*                Refer to the documentation for details.                 */
/* ---------------------------------------------------------------------- */
#ifndef _STRUCTS_
#define _STRUCTS_

typedef struct buffer_
{
   struct buffer_ huge *next,
                  huge *before;     /* links for input buffer chain */
   byte           huge  *buflist,
                  huge  *p;         /* pointers to actual buffer        */
   char                 *name;      /* buffer "name"                    */
   union
   {
      struct lexpr_ huge *list;     /* for macros                       */
      char              *unused;    /* for other uses                   */
   } parms;
   lword                remain, 
                        oremain;    /* bytes left in file , total len   */
   word                 line;       /* line counter                     */
   int                  _aux1;      /* used for FDs and macro counts    */
   unsigned short       _aux2,      /* used for lookahead chars         */
                        type;
#ifdef __NSTDC__
   union
   {
      void              (*fill)( struct buffer_ *); /* see non __STDC__  */
      struct macro_ huge *dad;                     /* for comments      */
   } multi;
   void                 (*done)( struct buffer_ *);
   int                  (*get )( void);
#else
   union
   {
      void              (*fill)();  /* refill buffer routine            */
      struct macro_ huge *dad;      /* address of macro definition      */
   } multi;
   void                 (*done)();  /* Called before buffer is killed   */
   int                  (*get)();   /* Input routine to get token       */
#endif
} buffer;


typedef struct ref_
{
   struct ref_ huge     *next;
   struct expr_ huge    *ref;    /* Pointer to value that needs fixing */
#if ! LINKER
   unsigned             no;
   unsigned             line;
#else
   unsigned             hacked;
#endif
} ref;


#if LINKER || LIBRARIAN
# define EXPRSIZE 20
typedef struct expr_
{
   word                 val,
                        aux, label;    /*  6 bytes */
   byte                 op, fix;       /*  8 bytes */
   struct expr_ huge    *l,            /* 12 bytes */
                huge    *r;            /* 16 bytes */
   union
   {
      struct fix_ huge  *fixp;
      struct expr_ huge *t;            /* 20 bytes */
   } zonk;
#if ! VERSION
   word                 hacked;        /* (22) bytes */
#undef EXPRSIZE
#define EXPRSIZE  22
#endif   
} expr;

#else

typedef struct expr_
{
   struct label_ huge   *label;        /*  4 bytes */
   word                 no, val, aux;  /* 10 bytes */
   byte                 op, fix;       /* 12 bytes */
   struct expr_ huge    *l,            /* 16 bytes */
                huge    *r;            /* 20 bytes */
   union
   {
      struct fix_ huge  *fixp;
      struct expr_ huge *t;            /* 24 bytes */
   } zonk;
} expr;
# define EXPRSIZE 24
#endif

typedef struct label_
{
   struct label_ huge   *next,
                 huge   *before;
   lword                hash;
   word                 val,          /* must be in second position       */
                        type;         /* see "expr.c":  recalc()          */
   char                 *name;        /* ^^^ I sure hope this is obsolete */
   struct ref_ huge     *refs;
#if ! LINKER
   word                 no;
#endif
} label;


typedef struct lexpr_
{
   struct lexpr_ huge   *next;
   char                 *string;
   struct expr_ huge    *expr;
} lexpr;


typedef struct memo_
{
   struct expr_ huge    *p;
   struct memo_ huge    *next;
} memo;


typedef struct macro_
{
   lword                hash;
   word                 inuse;
   char                 *name;
   struct buffer_ huge  *buf;             /* Pretty circular */
   struct macro_ huge   *next,
                        *before;
} macro;


typedef struct exp_m_
{
   int                  free;
   expr huge            *tab;
   struct exp_m_ huge   *before;
} exp_m;


typedef struct seg_
{
   struct seg_ huge     *next;         /* pointer to next seg  */
   int                  type;          /* type of the seg      */
   word                 index,         /* __program[ index]    */
                        size;          /* --> .DS  and .ALIGN  */
#if ! LINKER
   word                 no;
#else
   word                 offset;        /* real offset PC wise  */
#endif
} seg;


typedef struct imm_
{
   struct imm_ huge     *next;
   struct seg_ huge     *block;
   word                 type,
                        offset,
                        val;
#if ! LINKER
   word                 no;
#endif
} imm;


typedef struct fix_
{
   union
   {
      struct seg_ huge     *block;
      struct label_ huge   *label;
   } poof;
   struct imm_ huge        *imm;
   word                    index;
#if ! LINKER
   word                    no;
#else
   word                    hacked;
#endif
} fix;

#endif