/* zelk.h zilla 19aug91 - extensions to elk
 * modified
 * 12nov
 * 20sep
 * 6apr         farray->shape,ndim
 */

/* ZELK is defined in the config system file */
#ifdef ZELK  /*%%%%%%%%%%%%%%%%*/

#ifndef ZELK_H        /* do not include twice */
#define ZELK_H

/* some additional prototypes? no-let elk declare them */
/*#include <elk_protos.h>*/

/*%%%% these options are configured in config/system %%%%*/

/*#define ELKVECTOR        /+ include vector primitives? (requires ANSI C) */

/*#define ZILLAONLY        /+ include graphics extensions? */

/* see math.c.  Elk math has several characteristics which are altered
 * as follows:
 *- (/ x y) when both x,y are integer is treated as if x,y are both
 *  real, e.g. (/ 5 3) => 1.6666.  Xscheme and Scm also act this way;
 *  vscm has (/ 5 3) => 1 (integer).
 *  ZELK_INTEGER_DIV changed this so that (/ 5 3) => 1 (as in C).
 */
#define ZELK_INTEGER_DIV 0

/*- Real numbers equal to integers become integers, 
 *  e.g. (/ 6. 3.) => 2 (integer); (type 2.0) => integer
 *  ZELK_CONTAGIOUS_FLT makes floats 'contagious'.
 */
#define ZELK_CONTAGIOUS_FLT 1

/*%%%% end of configure %%%%*/

#define ELKV2 1         /* elk version 2+? */

#if (!ZILLAONLY)
# define str_cat strcat
# define str_cpy strcpy
# define str_len strlen
# define str_eq(a,b) (strcmp(a,b)==0)
#endif

#if ZILLAONLY
/* this will not be used unless zelk is included e.g. in print.c */
/*# undef FLONUM_FORMAT*/
/*# define FLONUM_FORMAT "%g"*/
# undef HEAP_SIZE
# define HEAP_SIZE 2048
#endif

#ifndef THEUSUAL_H
# include <theusual.h>
  /* some of the zelk extensions use proc as a synonym for void, 
     whereas some of the elk sources use proc as a variable name.
     wrap this inside 'ifndef THEUSUAL_H': all zelk source
     which will later need proc should include theusual.h before
     including scheme.h.
     For Elk source, scheme.h is included & THEUSUAL_H is not defined
     until now.  Use this to #undef proc at the end of this file,
     to prevent conflicts.
   */
# define undo_proc /*see end of this file */
#endif /*theusual.h*/

/* foreign functions */
#include <rtlpkg.h>

/* T_Double.
 * this is not a real elk type--it is used only by foreign functions
 * which (with ansi C) now need to distinguish passing float vs doubles.
 * This const is used only in the foreign argspec in-memory representaion.
 * The external form of foreign argument specs ("ARF") get translated
 * to lisp types, so F->T_Flonum, D->T_Double.  Unless T_Double is #defined
 * the distinction is not made (everything passed as double).
 *
 * Currently fvector.c is compiled with gcc (since one of the macros
 * is ansi). 
 */
#ifndef __GNUC__
#if Esparc
# if Eansi
  :error examine float/double issue zelk.h
# endif
#endif
#endif

#if Esgi
# define T_Double 253
#endif

/**** native function table.  similar non-global structure in prim.c */
struct primdef {
  Object (*fun)();
  char *name;
  int minargs,maxargs;
  enum discipline disc;
};

/**** misc. internal functions ****/

/* zelk.c */
void Init_zelk(Zvoid);
char *Get_Cstring P_((Object)); /* convert elk string to static c string */
Dfloat Get_Flonum P_((Object));
Object P_float P_((Object));
void ZLprimdeftab P_((struct primdef *));

/* forfunc.c */
void Init_foreign P_((Zvoid));
void Define_Foreign P_((char *name,vfunction *,char *args));
void Define_Fortab P_((struct fordef *));
void ZLforudeftab P_((struct fordef_usage *));
char *ZLforproto P_((unsigned char *));
Object Pforeignprototype P_((Object));
Object ZLforcall P_((char *name,function *,unsigned char *proto,
                         int,Object *));

/* forpkg.c */
void Init_pkg(Zvoid);
Object P_LoadPkg P_((int, Object *));
bool Zforpkglink P_((SYMTAB *,char *));
void Zforpkginit P_((char *,PKG_type *));
#if ZILLAONLY
void old_linkcsubr P_((struct cfordef *));
void Define_OldForeign P_((char *,vfunction *,int *));
#endif

void Init_peekpoke P_((Zvoid));
void Init_vector P_((Zvoid));
void Init_gl P_((Zvoid));
void Init_forfunctest P_((Zvoid));

/**** foreign arrays ****/

extern int T_Farray;

#define FARRAY(o) ((Farray *)POINTER(o))

#define FARRAY_MAXDIM 3

typedef struct farray {
  Object tag;  /* needed by elk gc system */
  int type;
  int len;
  int shape[FARRAY_MAXDIM];          /* shape, used by vector code.
                                        inner dimension is [0].
                                      */
  int ndim;                          /* used by vector code */
    /* magic must be immediately before start of data! */
  int4 magic;           /* this is for non-scheme code which wants
                           to know if an array is an farray */
  Zbyte data[1];        /* first word of actual data */
} Farray;


#define TYPEORFARRAYTYPE(A) \
  ((TYPE(A)==T_Farray) ? FARRAY(A)->type : TYPE(A))

#define FARRAYDATA(D,dtype) ((dtype *)FARRAY(D)->data)
#define FARRAYDATAPTR(var,D,dtype) dtype *var = ((dtype *)FARRAY(D)->data)

void Init_farray P_((Zvoid));
Object farray_make P_((int4 type,int4 len));
Object farray_make_like P_((Object A));
Object P_farray_copy P_((Object));
Object P_farray_ref P_((Object,Object));
void farray_copyshape P_((Object from,Object to));
void farray_check P_((Object));
void farray_print P_((Object,Object,bool,int,int));

/* see comment at beginning of this file */
#ifdef undo_proc
# undef proc
# undef undo_proc
#endif

#endif /*ZELK_H*/
#endif /*ZELK%%%%%%%%%%%%%%%%*/
