/* %Z%%M% %I% %E% */

/*
 * Copyright (c) 1990, 1991, 1992, 1995 by Wayne C. Gramlich.
 * All rights reserved.
 *
 * Permission to use, copy, modify, distribute, and sell this software
 * for any purpose is hereby granted without fee provided that the above
 * copyright notice and this permission are retained.  The author makes
 * no representations about the suitability of this software for any purpose.
 * It is provided "as is" without express or implied warranty.
 */

#ifndef TYPE_DEFS_H
#define TYPE_DEFS_H

#ifndef TYPE_EXPORTS_H
#include "type_exports.h"
#endif

/* The iterator macros: */
#define TYPE_NEEDS_LOOP(type_needs, type_need) \
	VEC_LOOP(Type_need, type_needs, type_need)
#define TYPE_REFS_LOOP(type_ref_list, type_ref) \
	VEC_LOOP(Type_ref, (type_ref_list)->type_refs, type_ref)
#define TYPE_SIGNALS_LOOP(type_signals, type_signal) \
	VEC_LOOP(Type_signal, type_signals, type_signal)

/* A signal prototype: */
struct Signal_struct {
	Type_refs	args;		/* Signal arguments */
	Str		comment;	/* Comment at end-of-line */
	Str		name;		/* Signal name */
};

/* This structure represents and enumeration type:*/
struct Type_enumeration_struct {
	Vec(Type_item)	items;		/* Items of enumeration */
};

/* This structure represents a field in either a variant or struct: */
struct Type_field_struct {
	Str		comment;	/* Comment at end-of-line */
	Str		name;		/* Field name */
	int		position;	/* Position of field */
	Type_ref	type_ref;	/* Type object */
};

/* This structure represents an enumeration item: */
struct Type_item_struct {
	Str		comment;	/* Comment at end-of-line */
	Str		name;		/* Item name */
	int		position;	/* Location in file */
	int		value;		/* Item value */
};

/* This structure represents a routine type declaration: */
struct Type_iterator_struct {
	Type_refs	returns;	/* Return  types */
	Type_refs	takes;		/* Argument types */
	Type_refs	yields;		/* Yield types */
};

/* A needs prototype: */
struct Type_need_struct {
	Str		name;		/* Name of need routine */
	Type_proto	proto;		/* Routine proto-type */
	Type_ref	type_ref;	/* Type of need routine */
};

/* A needs table; */
struct Type_need_table_struct {
	Heap		heap;		/* Heap used for allocating things */
	Type_need	need_key;	/* Temp. need key for lookup */
	Table(Type_need, Type_need) need_table;	/* Need table */
	Type_needs	needs_empty;	/* Empty need list */
	Type_needs	needs_key;	/* Temp. need list key for lookup */
	Table(Type_needs, Type_needs) needs_table; /* Need list table */
};

/*
 * A Type_proto object represents the prototype for a routine.
 * For a parameterized routine/iterator prototype with N parameters,
 * type references to the parameter types are represented as a Type_ref
 * where the name field is string containing an integer between 0 and N-1.
 */

/* A routine prototype: */
struct Type_proto_struct {
	int		generated;	/* 1=>already in output file */
	Type_proto_kind	kind;		/* Routine/iterator flag (key */
	Type_needs	needs;		/* Needs list (key */
	int		needed;		/* 1 => prototype needed */
	int		no_return;	/* 1=>routine does not return (key */
	Type_refs	params;		/* Parameter types (key */
	Type_refs	returns;	/* Return types (key */
	Type_signals	signals;	/* Signal values (key */	
	Type_refs	takes;		/* Arguement types (key */
	Type_ref	type_ref;	/* Procedure var. type ref. */
	Type_refs	yields;		/* Iterator yield types (key */
};

/* A table of prototypes: */
struct Type_proto_table_struct {
	Heap		heap;		/* Heap used for allocation */
	Type_proto	key;		/* Temporary key */
	Table(Type_proto, Type_proto) table; /* Table of all prototypes */
	Vec(Type_proto)	type_proto_list; /* All prototypes */
	Vec(Type_ref)	type_ref_list;	/* All corresponding type refs. */
};

/* This structure represents the fields in a structure: */
struct Type_record_struct {
	Type_fields	fields;		/* List of fields */
};

/* This structure represents a type reference: */
struct Type_ref_struct {
	int		generated;	/* 1 => already output into file */
	Str		name;		/* Type name */
	int		needed;		/* 1 => needed in output file */
	Type_refs	parameters;	/* Type parameters */
	Type_refs	type_refs;	/* List containing this type ref. */
};

/* This structure containes information about type references: */
struct Type_ref_table_struct {
	Type_refs	empty;		/* Empty type reference list */
	Heap		heap;		/* Heap used for table */
	int		multiple;	/* Multiple return type counter */
	Type_ref	type_ref_key;	/* Temp. type ref. key */
	Type_refs	type_refs_key;	/* Temp. type ref. list key */
	Table(Type_ref, Type_ref) ref_table; /* Type ref. table. */
	Table(Type_refs, Type_refs) refs_table;/* Type ref. list table */
};

/* A type reference list: */
struct Type_refs_struct {
	Vec(Type_ref)	type_refs;	/* Type reference list */
	int		list_generated;	/* 1=>type reference list generated */
	int		multiple;	/* Number of multiple type ref.
					 * -1 => not needed */
};

/* A signal prototype: */
struct Type_signal_struct {
	Str		name;		/* Signal name */
	Type_refs	type_refs;	/* Signal value list */
};

/* A signals table; */
struct Type_signal_table_struct {
	Heap		heap;		/* Heap used for allocating things */
	Type_signal	signal_key;	/* Temp. signal key for lookup */
	Table(Type_signal, Type_signal) signal_table; /* Signal table */
	Type_signals	signals_empty;	/* Empty signal list */
	Type_signals	signals_key;	/* Temp. signal list key for lookup */
	Table(Type_signals, Type_signals) signals_table; /* Signal list table */
};

/* A table of type tables: */
struct Type_tables_struct {
	Type_def_table		type_def_table;
	Type_need_table		type_need_table;
	Type_proto_table	type_proto_table;
	Type_ref_table		type_ref_table;
	Type_signal_table	type_signal_table;
};

/* This structure represents the fields in a variant: */
struct Type_variant_struct {
	Type_fields	fields;		/* List of fields */
	Type_field	tag_field;	/* Tag field */
};

/* This structure represents one of the various type variants: */
union Type_value_union {
	Type_enumeration enumeration;	/* Enumeration type */
	Type_proto	proto;		/* Proto type */
	int		simple;		/* Simple type */
	Type_record	record;		/* Struct type */
	Type_variant	variant;	/* Variant type */
	int		undefined;	/* Undefined type */
};

/* This structure represents a type definition: */
struct Type_def_struct {
	Str		comment;	/* Comment at end-of-line */
	int		imported;	/* 1=>imported; 0=>defined locally */
	Vec(Generate)	generates;	/* List of functions to generate */
	Type_kind	kind;		/* Struct/Variant/Enum etc... */
	Str		name;		/* Type name */
	int		position;	/* Location in file */
	Str		routine_name;	/* Routine name (for needs decl only */
	Vec(Routine_type) routine_types; /* Local routine types */
	int		structure_needed; /* 1 => generate structure def. */
	Type_ref	type_ref;	/* Assocaiated type reference */
	Type_value	value;		/* Struct/Variant/Enum etc... */
};

/* This structure contains all of the type definitions: */
struct Type_def_table_struct {
	Table(Str, Type_def)	table;	/* Table of type definitions: */
};

#endif /* TYPE_DEFS_H */

