/* header file for S-Lang internal structures that users do not (should not)
   need.  Use slang.h for that purpose. */
/* 
 * Copyright (c) 1992, 1994 John E. Davis 
 * All rights reserved.
 *
 * Permission is hereby granted, without written agreement and without
 * license or royalty fees, to use, copy, and distribute this
 * software and its documentation for any purpose, provided that the
 * above copyright notice and the following two paragraphs appear in
 * all copies of this software.
 *
 * IN NO EVENT SHALL JOHN E. DAVIS BE LIABLE TO ANY PARTY FOR DIRECT,
 * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
 * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF JOHN E. DAVIS
 * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * JOHN E. DAVIS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
 * BASIS, AND JOHN E. DAVIS HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
 * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 */


#include <stdlib.h>
#include <string.h>
#include "config.h"
#include "jmalloc.h"

#ifdef __GO32__
#  define SLANG_SYSTEM_NAME "_IBMPC"
#else
# if defined (msdos) || defined (__os2__)
#  define SLANG_SYSTEM_NAME "_IBMPC"
# else
#  ifdef VMS
#    define SLANG_SYSTEM_NAME "_VMS"
#  else
#    define SLANG_SYSTEM_NAME "_UNIX"
#  endif
# endif
#endif


typedef struct SLang_Object_Type
  {
     unsigned short type;
     long value;
#ifdef USE_DOUBLE
     long extra;
#endif
  }
SLang_Object_Type;


#define LANG_MAX_SYMBOLS 500
/* maximum number of global symbols--- slang builtin, functions, global vars */

/* Subtypes */
#define ERROR_BLOCK	0x01
#define EXIT_BLOCK	0x02
/* gets executed if block encounters error other than stack related */


/* directive subtypes */
#define LANG_LOOP_MASK	0x80
#define LANG_LOOP	0x81
#define LANG_WHILE	0x82
#define LANG_FOR	0x83
#define LANG_FOREVER	0x84
#define LANG_CFOR	0x85
#define LANG_DOWHILE	0x86

#define LANG_IF_MASK	0x40
#define LANG_IF		0x41
#define LANG_IFNOT	0x42
#define LANG_ELSE	0x43


/* local, global variable assignments
   The order here is important.  See interp_variable_eqs to see how this
   is exploited. */
#define LANG_EQS_MASK	0x20
/* local variables */
#define LANG_LEQS	0x21
#define LANG_LPEQS	0x22
#define LANG_LMEQS	0x23
#define LANG_LPP	0x24
#define LANG_LMM	0x25
/* globals */
#define LANG_GEQS	0x26
#define LANG_GPEQS	0x27
#define LANG_GMEQS	0x28
#define LANG_GPP	0x29
#define LANG_GMM	0x2A
/* intrinsic variables */
#define LANG_IEQS	0x2B
#define LANG_IPEQS	0x2C
#define LANG_IMEQS	0x2D
#define LANG_IPP	0x2E
#define LANG_IMM	0x2F

/* intrinsic variables, integer only, from lang_add_variable */

#define LANG_ELSE_MASK	0x10
#define LANG_ANDELSE	0x11
#define LANG_ORELSE	0x12
#define LANG_SWITCH	0x13

/* binary stypes and cmp stypes */
#define LANG_EQ		1
#define LANG_NE		2
#define LANG_GT		3
#define LANG_GE		4
#define LANG_LT		5
#define LANG_LE		6
#define LANG_OR		7
#define LANG_PLUS	8
#define LANG_MINUS	9
#define LANG_TIMES	10
#define LANG_DIVIDE	11
#define LANG_AND	12
#define LANG_BAND	13
#define LANG_BOR	14
#define LANG_BXOR	15
#define LANG_SHL	16
#define LANG_SHR	17
#define LANG_MOD	18


/* UNARY subtypes */
#define LANG_NOT	1
#define LANG_CHS	2
#define LANG_BNOT	3
#define LANG_ABS	4
#define LANG_SIGN	5
#define LANG_SQR	6
#define LANG_MUL2	7


extern void SLcompile(char *);
extern void (*SLcompile_ptr)(char *);

typedef struct Lang_Name2_Type
{
   char *name;  int type;
} Lang_Name2_Type;

extern void SLstupid_hash(void);

typedef struct SLName_Table
{
   struct SLName_Table *next;	       /* next table */
   SLang_Name_Type *table;	       /* pointer to table */
   int n;			       /* entries in this table */
   char name[32];		       /* name of table */
   int ofs[256];		       /* offsets into table */
} SLName_Table;

extern SLName_Table *SLName_Table_Root;
extern SLang_Name_Type SLang_Name_Table[LANG_MAX_SYMBOLS];

extern int SL_eqs_name(char *, Lang_Name2_Type *);
extern Lang_Name2_Type Lang_Binaries[];
extern SLang_Object_Type *SLStack_Pointer;
extern int extract_token(char **, char *);
extern char *SLbyte_compile_name(char *);
extern int SLang_pop(SLang_Object_Type *);
extern char *SLsprintf(void);
extern char *SLexpand_escaped_char(char *, char *);
extern SLang_Object_Type *SLreverse_stack(int *);
extern SLang_Name_Type *SLang_locate_name(char *);


/* array types */
typedef struct Array_Type
{
   int dim;			       /* # of dims (max 3) */
   int x,y,z;			       /* actual dims */
   long ptr;			       /* address of buffer */
   unsigned char type;		       /* int, float, etc... */
   unsigned char flags;		       /* This is 0 if it is a S-Lang array,
					* LANG_IVARIABLE if it is read/write
					* C array, LANG_RVARIABLE if it is 
					* read only C array.
					*/
} Array_Type;

/* maximum size of run time stack */
#ifdef msdos
#define LANG_MAX_STACK_LEN 500
#else
#define LANG_MAX_STACK_LEN 1000
#endif

extern SLang_Object_Type SLRun_Stack[LANG_MAX_STACK_LEN];
extern SLang_Object_Type *SLStack_Pointer;

extern int SLang_Trace;
extern int SLstack_depth(void);

extern void SLang_trace_fun(char *);
extern void SLexecute_function(SLang_Name_Type *);
extern long SLmake_string (char *);

/* useful macro to tell if string should be freed after its use. */
#define IS_DATA_STRING(obj)\
   ((((obj).type >> 8) == STRING_TYPE) && (((obj).type & 0xFF) == LANG_DATA))

extern int slang_eqs_name(char *, Lang_Name2_Type *);
extern void SLang_push(SLang_Object_Type *);
extern void SLang_push_float(FLOAT);
extern void SLadd_variable(char *);
extern int SLatoi(unsigned char *);
extern void SLadd_name(char *, long, unsigned short);
extern void SLang_clear_error(void);
extern int SLPreprocess_Only;		        /* preprocess instead of 
						 * bytecompiling
						 */
