
/************************************************************************
;                                                                       *
;       APLX.H - APLX Auxiliary Processor Header File         			*
;                                                                       *
;************************************************************************
;                                                                       *
;               Copyright (c) MicroAPL Ltd  1991,2001                   *
;                   All Rights Reserved Worldwide                       *
;                                                                       *
;************************************************************************
; 
; 26/10/01	First release for APLX, based on previous apl68000.h
;
; View with tab stops = 4
;
;*/

/***** APL Error Codes *****/

#define APL_NOMESSAGE  -4 		/* No message */
#define APL_GOOD		0		/* No error */
#define	APL_WSFULL		4		/* WS full */
#define	APL_SYNTERR		8		/* Syntax error */
#define	APL_DOMERR		12		/* Domain error */
#define	APL_RANKERR		16		/* Rank error */
#define APL_LENERR		20		/* Length error */
#define APL_NONCERR		24		/* Nonce error */
#define APL_VALERR		28		/* Value error */
#define APL_INDERR		32		/* Index error */
#define APL_ACCESS 		36		/* Unauthorized file access */
#define APL_NOTFOUND	40		/* File not in system */
#define APL_COMPONENT	44		/* Component not in file */
#define APL_FALLOC  	48		/* File allocation exceeded */
#define APL_HELD    	52		/* File or component held */
#define APL_MAINT   	56		/* File maintenance in progress */
#define APL_UALLOC  	60		/* User allocation exceeded */
#define APL_EXISTS  	64		/* File in existence */
#define	APL_IOERR		68		/* File I/O error */
#define	APL_FULL 		72		/* Disk full */
#define	APL_USER 		76		/* User not in system */
#define	APL_DAMAGE 		80		/* Data damaged */
#define	APL_LOCKED		84		/* File locked */
#define	APL_LUNF		88		/* Logical unit not found */
#define	APL_VALENCE     92		/* Valence error */
#define	APL_AXIS		96		/* Axis error */
#define	APL_SYSTEM		100		/* System error */
#define	APL_LIMIT		104		/* Limit error */
#define	APL_SYMTAB		108		/* Symbol table full */
#define	APL_DEFN		112		/* Definition error */
#define	APL_UNKNOWN		116		/* Unknown error */
#define	APL_INTERRUPT	120		/* Interrupt */
#define	APL_COMMAND		124		/* Incorrect command */


/***** APL Data Types (we_type) *****/
#define DT_BIN		0x5		/* Binary data */
#define DT_INT		0x7		/* Integer data */
#define DT_FLT		0x9		/* Float data */
#define DT_CHR		0xb		/* Character data */
#define DT_COM		0xd		/* Complex data */
#define DT_NST		0xf		/* Nested data */


/***** APL Data Ranks (we_rank) *****/
#define DR_SCL		0		/* Scalar */
#define DR_VEC		4		/* Vector */
#define DR_MAT		8		/* Matrix */


/****** Common APL Variable Type/Rank values (we_type_rank) *****/

#if defined LITTLE_ENDIAN

/* Little-endian version for x86 (Windows, x86 Linux) */ 
#define BIN_SCL		0x00000005	/* Binary scalar */
#define BIN_VEC		0x00040005	/* Binary vector */
#define BIN_MAT		0x00080005	/* Binary matrix */
#define INT_SCL		0x00000007	/* Integer scalar */
#define INT_VEC		0x00040007	/* Integer vector */
#define INT_MAT		0x00080007	/* Integer matrix */
#define FLT_SCL		0x00000009	/* Float scalar */
#define FLT_VEC		0x00040009	/* Float vector */
#define FLT_MAT		0x00080009	/* Float matrix */
#define CHR_SCL		0x0000000B	/* Character scalar */
#define CHR_VEC		0x0004000B	/* Character vector */
#define CHR_MAT		0x0008000B	/* Character matrix */
#define NST_SCL		0x0000000F	/* Nested scalar */
#define NST_VEC		0x0004000F	/* Nested vector */
#define NST_MAT		0x0008000F	/* Nested matrix */


#else

/* Big-endian version for PowerPC (MacOS, RS/6000) */
#define BIN_SCL		0x05000000	/* Binary scalar */
#define BIN_VEC		0x05000004	/* Binary vector */
#define BIN_MAT		0x05000008	/* Binary matrix */
#define INT_SCL		0x07000000	/* Integer scalar */
#define INT_VEC		0x07000004	/* Integer vector */
#define INT_MAT		0x07000008	/* Integer matrix */
#define FLT_SCL		0x09000000	/* Float scalar */
#define FLT_VEC		0x09000004	/* Float vector */
#define FLT_MAT		0x09000008	/* Float matrix */
#define CHR_SCL		0x0b000000	/* Character scalar */
#define CHR_VEC		0x0b000004	/* Character vector */
#define CHR_MAT		0x0b000008	/* Character matrix */
#define NST_SCL		0x0f000000	/* Nested scalar */
#define NST_VEC		0x0f000004	/* Nested vector */
#define NST_MAT		0x0f000008	/* Nested matrix */

#endif


/***** Auxiliary processor functions *****/
#define AP_LOADED		1		/* Auxiliary processor loaded */
#define AP_UNLOADED		2		/* Auxiliary processor unloaded */
#define AP_SPECIFIED	3		/* Auxiliary processor specified */
#define AP_REFERENCED	4		/* Auxiliary processor referenced */



/* -- Structures for looking at workspace entries in various ways -- 
;
; This is a bit tricky because the positions of the data portions depend on the
; rank.  The following is intended to allow convenient access to the most
; common cases of scalar/vector/matrix, including the common parts (we_len)
; and the length or row/col counts for vectors and matrices.
;
; The length of the data arrays such as we_vec_cdata are of course not to be taken too
; literally, as the size varies.  C/C++ won't let us define these as variable-length arrays, 
; but they are still useful for things like:
;
;	char *p;
;   p = &array_ptr->we_vec_cdata[0];
;
; Also by saying they are fixed size arrays, debuggers should show the first few elements.
; We can rely on C not checking array bounds.
;
; Unfortunately some compilers (such as gcc) do not allow these anonymous 
; structures.  See below for alternative definition which gets round this.
;
;*/

#ifndef __GNUC__

typedef struct {
	long	we_reserved;						// we_flags etc, private to APL. Plug 0 here
	long 	we_len;								// Length
	union {
		struct {
			char	we_type;					// Type DT_xxx
			char	dummy2;
			short	we_rank;					// Rank DR_xxx (0, 4, ...)
		};
		long we_type_rank;						// Type/Rank as one - see INT_SCL etc
	};
	
	union {
		union {
			// Fields to use for SCALARS
			char we_scl_cdata;					  	// Scalar character value
			long  we_scl_idata;					    // Scalar integer (or binary, top bit has the value)
			// Can't do float case because not 8-byte aligned - cast pointer if necessary
		};
		
		struct {
			// Fields to use for VECTORS
			int	we_vec_length;						// Length of vector
			union {
				char we_vec_cdata[64];				// Vector character data (variable size)
				long  we_vec_idata[16];				// Vector integer data (or binary) (")
				// Can't do float case because not 8-byte aligned - cast pointer if necessary
			};	
		};

		struct {
			// Fields to use for MATRICES
			long	we_mat_rows;					// Number of rows
			long	we_mat_cols;					// Number of cols
			union {
				char we_mat_cdata[64];				// Matrix character data (variable size)
				long  we_mat_idata[16];				// Matrix integer data (or binary) (")
				// Can't do float case because not 8-byte aligned - cast pointer if necessary
			};	
		};
	};
	
} WS_Entry; 

#else
//  -- GCC VERSION --

//  gcc doesn't support the anonymous structure approach.
typedef struct {
	long	we_reserved;						// we_flags etc, private to APL. Plug 0 here
	long 	we_len;								// Length
	union {
		struct {
			char	we_type;					// Type DT_xxx
			char	dummy2;
			short	we_rank;					// Rank DR_xxx (0, 4, ...)
		} s1;
		long we_type_rank;						// Type/Rank as one - see INT_SCL etc
	} u2;
	
	union {
		union {
			// Fields to use for SCALARS
			char we_scl_cdata;					  	// Scalar character value
			long  we_scl_idata;					    // Scalar integer (or binary, top bit has the value)
			// Can't do float case because not 8-byte aligned
		} u3;
		
		struct {
			// Fields to use for VECTORS
			int	we_vec_length;						// Length of vector
			union {
				char we_vec_cdata[64];				// Vector character data (variable size)
				long  we_vec_idata[16];				// Vector integer data (or binary) (")
				// Can't do float case because not 8-byte aligned
			} u4;	
		} s5;

		struct {
			// Fields to use for MATRICES
			long	we_mat_rows;					// Number of rows
			long	we_mat_cols;					// Number of cols
			union {
				char we_mat_cdata[64];				// Matrix character data (variable size)
				long  we_mat_idata[16];				// Matrix integer data (or binary) (")
				// Can't do float case because not 8-byte aligned
			} u6;	
		} s7;
	} u8;
	
} WS_Entry; 

#define we_type			u2.s1.we_type
#define we_rank			u2.s1.we_rank
#define we_type_rank	u2.we_type_rank

#define we_scl_cdata	u8.u3.we_scl_cdata
#define we_scl_idata	u8.u3.we_scl_idata

#define we_vec_length	u8.s5.we_vec_length
#define we_vec_cdata	u8.s5.u4.we_vec_cdata
#define we_vec_idata	u8.s5.u4.we_vec_idata

#define we_mat_rows		u8.s7.we_mat_rows
#define we_mat_cols		u8.s7.we_mat_cols
#define we_mat_cdata	u8.s7.u6.we_mat_cdata
#define we_mat_idata	u8.s7.u6.we_mat_idata


#endif


/***** Structure to hold pointers to routines in APL which the AP can call *****/
typedef struct _ExportedProcs {
	int		count;							/* Number of exports supported by this version of APL */
	char	(*fontin)(char font_char);		/* Translate font (extended ASCII) character to APL internal */
	char	(*fontout)(char apl_char);		/* Translate APL internal character to font (extended ASCII)  */
	int		(*check_event_attention)(void);	/* Handle events. Returns 1 if attention pending, 0 otherwise */
	int		(*cget)(void);					/* Get one keystroke from session window */
	int 	(*csend) (int character);		/* Send one character to session window */
	void	(*apl_line_send)(char *string);	/* Send string (in internal representation) to session window */
	void	(*ascii_line_send)(char *string);/* Send string (in extended ASCII) to session window */
	int		(*quadcc)(int code);			/* Carry out Quad-CC function (excluding cursor address, get char) */
	int		(*cursor_add) (int xpos, int ypos);/* Cursor addressing, index origin 0 */

} ExportedProcs;




/* Prototype for the Auxiliary Processor interface. */
int processor (
		int			op,				/* Operation code AP_xxx */
		WS_Entry	*data,			/* Pointer to APL data specified, or where to put result */
		int			wsfree,			/* Free workspace (in bytes) on AP referenced */
		void		*scratch,		/* Pointer to 256-byte scratch area for use by the AP */
		void		*wsbase,		/* Pointer to base of workspace */
		WS_Entry	*last_var,		/* On reference, pointer to header of last variable
									   specified, or NULL if last data was a constant */
		int			tie,			/* An internal tie number uniquely identifying shared var */
		ExportedProcs *exports		/* Structure holding pointers to functions the AP can call */							   
);

/* Note: On op == AP_LOADED, the 'data' parameter is a 'char *' pointer to the shared variable name */
