/* @(#)Copyright (c), 1987, 1993 StatSci, Inc.  All rights reserved. */

#ifndef _S_TRANSLATE_H_ /*(*/
#define _S_TRANSLATE_H_

#include <sccs.h>
SCCS_ID_C(0036,@(#)i_translat.h 3.11 last edit 3/5/93 StatSci)

/* defines for translating S code into C */
/* some of the necessary info is already in S.h, and plausibly someday */
/* it all will be, or at least all that humans (as opposed to translating
/* programs) need */

/* structures for basic S data types */
/* these replicate defines in S.h */
/* because of the different use of mode, length, translate.h cannot */
/* be mixed with S.h.  Would be nice to change the use of mode, length */
/* in S.h, since that is not user-visible */

#define logical_mode 1
#define integer_mode 2
#define single_mode 3
#define numeric_mode 4
#define character_mode 5
#define list_mode 6
#define recursive_mode list_mode
#define complex_mode 7
#define any_mode 11
#define has_attr_mode 21

/* following duplicate defines in S.h */
#define TRUE 1
#define FALSE 0
#define CHECK_IT		63
#define MAX_ATOMIC 20
#define atomic_type(t) ((t) <= MAX_ATOMIC ? atomic_types[t] : FALSE)
extern int atomic_types[];

#define MESSAGE		sprintf(error_buf,
#define PROBLEM		sprintf(error_buf,
#define WARNING(x)	), Warning(error_buf, x)
#define RECOVER(x)	), Recover(error_buf, x)
#define TERMINATE	), S_terminate(error_buf)
#define PRINT_IT	), fprintf(stderr,"%s\n",error_buf)
#define END_MESSAGE	)
#define ERROR_BUF_LENGTH 4096
extern char error_buf[];

typedef struct {
	double re, im;
} complex;
typedef union s_pointer pointer;

union s_pointer {
	long *Long;
	float *Float;
	char **Char;
	double *Double;
	complex *Complex;
	char *name;
	struct s_object **tree;
};
/* end of duplications from S.h */

struct s_object {
	int Type;
	char *name;
	int Mode;
	long Length;
	pointer value;
	union {
		struct s_object *frame;
		struct s_object *next;	/* for lists */
	} x;
	long nalloc;
	long status; 
};
#define data_Mode(p)		((atomic_type(p->Mode))?p->Mode : Data_mode(p))
#define data_Length(p)		((atomic_type(p->Mode))?p->Length : Data_length(p))

typedef struct s_object *object;
typedef double numeric;
typedef char *character;
typedef long integer;
typedef long logical;

#define length(x) data_Length(x)
#define mode(x) data_Mode(x)
#define numeric_data(x) ((x)->Mode==numeric_mode ? (x)->value.Double : coe_vec(x, numeric_mode, 1, CHECK_IT)->value.Double)
#define character_data(x) ((x)->Mode==character_mode ? (x)->value.Char : coe_vec(x, character_mode, 1, CHECK_IT)->value.Char)
#define logical_data(x) ((x)->Mode==logical_mode ? (x)->value.Long : coe_vec(x, logical_mode, 1, CHECK_IT)->value.Long)
#define integer_data(x) ((x)->Mode==integer_mode ? (x)->value.Long : coe_vec(x, integer_mode, 1, CHECK_IT)->value.Long)
#define complex_data(x) ((x)->Mode==complex_mode ? (x)->value.Complex : coe_vec(x, complex_mode, 1, CHECK_IT)->value.Complex)
#define list_data(x) ((x)->Mode==list_mode ? (x)->value.tree : coe_vec(x, list_mode, 1, CHECK_IT)->value.tree)
#define recursive_data(x) ((x)->Mode==recursive_mode ? (x)->value.tree : coe_vec(x, recursive_mode, 1, CHECK_IT)->value.tree)

#define length_gets(x, n) set_length2(x, (long)n)
#define mode_gets_string(x, p) set_mode2(x, mode_lookup((char *)p), (char *)p)
#define mode_gets(x, n) set_mode2(x, (int)n, "")
#define attr_gets(x, n, value) ATTR_GETS(x, (char *)n, value)

#define on_exit(f) add_exit(f, Nframe)

#define new_numeric(n) alcvec(numeric_mode,n)
#define new_double(n) alcvec(numeric_mode,n)
#define new_logical(n) alcvec(logical_mode,n)
#define new_integer(n) alcvec(integer_mode,n)
#define new_complex(n) alcvec(complex_mode,n)
#define new_character(n) alcvec(character_mode,n)
#define new_list(n) alcvec(list_mode,n)

#define attr(x,what) (x->Mode == has_attr_mode ? xact_comp(x, what) : 0)
#define dim(x) (x->Mode == has_attr_mode ? xact_comp(x, ".Dim") : 0)
#define dimnames(x) (x->Mode == has_attr_mode ? xact_comp(x, ".Dimnames") : 0)
#define colnames(x) get_dimnames_el(x,1)
#define rownames(x) get_dimnames_el(x,0)
#define levels(x) (x->Mode == has_attr_mode ? xact_comp(x, ".Label") : 0)
#define tsp(x) (x->Mode == has_attr_mode ? xact_comp(x, ".Tsp") : 0)
#define names(x) GET_NAMES(x)
#define class(x) (x->Mode == has_attr_mode ? xact_comp(x, "class") : 0)
#define el(x,i,mode) (x->value.mode)[i]
#define as_vector(x) coe_vec(x, any_mode, 1, CHECK_IT)
#define as_list(x) coe_vec(x, list_mode, 1, CHECK_IT)
#define as_character(x) coe_vec(x, character_mode, 1, CHECK_IT)
#define as_numeric(x) coe_vec(x, numeric_mode, 1, CHECK_IT)
#define as_integer(x) coe_vec(x, integer_mode, 1, CHECK_IT)
#define is_numeric(x) (d__mode = data_Mode(x), d__mode>=logical_mode && d__mode <= numeric_mode)
#define is_logical(x)  (data_Mode(x)==logical_mode)
#define is_integer(x)  (data_Mode(x)==integer_mode)
#define is_character(x)  (data_Mode(x)==character_mode)
#define is_atomic(x) (d__mode = data_Mode(x), atomic_type(d__mode))
#define is_recursive(x) (d__mode = data_Mode(x), NOT_RECURSIVE(d__mode))
#define writeable(x) (PRECIOUS(x) ? x = copy_data(x, 0) : x)
extern object NO_NAME(), CALL_4(), CALL_3(), CALL_2(), CALL_1(), CALL_0(),
	CALL_2_F(), CALL_1_F(), CALL_0_F(), ADD_ARG(),
	*STRING_VECTOR(), NUMERIC_VECTOR(), GET_NAMES();
extern object NO_NAME(), get_dimnames_el(), alcvec(), coe_vec(), xact_comp(),
	eval(), copy_data();
extern void ATTR_GETS(), ELEMENT_GETS(), set_mode2(), set_length2();
extern int d__mode, Data_mode();
extern long Data_length(), Nframe;

#endif /* !_S_TRANSLATE_H_ )*/
