/*
 * Symbol table structures
 */

typedef struct var_t Var;
typedef struct type_t Type;

enum typeclass
{
	Struct,
	Typedef,
	Scalar,
	Array,
	CArray,
	Pointer,
	Void
};

enum sc_size
{
	NoType = -1,
	Char,
	Short,
	Long,
	LongLong,
	Float,
	Double
};

struct type_t
{
	enum typeclass tclass;
	union
	{
		Var 	*struct_i;
		struct
		{
			Type *t;
			char *n;
		} typedef_i;
		struct
		{
			enum sc_size size;
			int	Unsigned;
		} scalar_i;
		Type	*array_i;
		Type	*pointer_i;
		struct
		{
			Type *type;
			unsigned size;
		} carray_i;
	} i;
	Type		*name;		/* Pointer to nameing typedef */
	unsigned	anon:1;		/* Had no defined name */
	unsigned	nocode:1;	/* No code to be generated */
	unsigned	nohdr:1;	/* No header generated */
	unsigned	demand:1;	/* Generate code as needed */
	unsigned	norep:1;	/* No serial representation */
	unsigned 	indir:1;	/* Use a level of indirection */
	unsigned	coded:3;	/* En/Decode func generated */
};

struct var_t
{
	char	*name;
	Type	*type;
	Var	*next;
	Var	*prev;
};

extern Var *global;	/* Global symbol table */
extern Var *structures;	/* Global structure table */

void init_symtab(void);

Var *lookup(Var *, const char *);
Var *add(Var *, Var *);
Var *addl(Var *, Var *);
Var *preadd(Var *, Var *);

Type *mktype(void);
Type *mkstruct(Var *);
Type *mkpointer(Type *);
Type *mkarray(Type *);
Type *mkcarray(Type *, unsigned int);
Type *mkscalar(enum sc_size, int);
Type *mkvoid(void);

Var *mkvar(Type *, char *);
Var *mktypedef(Type *, char *);
Var *mkincl(const char *);

Var *name_types(Var *);

Type *realtype(Type *);

/* Standard types */
extern Type *Ulonglong_type;
extern Type *Ulong_type;
extern Type *Ushort_type;
extern Type *Uchar_type;
extern Type *longlong_type;
extern Type *long_type;
extern Type *short_type;
extern Type *char_type;
extern Type *void_type;
extern Type *float_type;
extern Type *double_type;
