/* header file for S-Lang internal structures that users do not (should not)
   need.  Use slang.h for that purpose. */
/* 

   Copyright (C) 1993 John E. Davis (davis@amy.tch.harvard.edu)
   All rights reserved.

   This file is part of S-Lang.

   S-Lang is distributed in the hope that it will be useful, but WITHOUT
   ANY WARRANTY.  No author or distributor accepts responsibility to
   anyone for the consequences of using it or for whether it serves any
   particular purpose or works at all, unless he says so in writing.
   Refer to the S-Lang General Public License for full details.

   Everyone is granted permission to copy, modify and redistribute
   S-Lang, but only under the conditions described in the S-Lang General
   Public License.  A copy of this license is supposed to have been given
   to you along with S-Lang so you can know your rights and
   responsibilities.  It should be in a file named COPYING.  Among other
   things, the copyright notice and this notice must be preserved on all
   copies.

*/

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

#ifdef __GO32__
#  define SLANG_SYSTEM_NAME "_IBMPC"
#else
# ifdef msdos
#  define SLANG_SYSTEM_NAME "_IBMPC"
# else
#  ifdef VMS
#    define SLANG_SYSTEM_NAME "_VMS"
#  else
#    define SLANG_SYSTEM_NAME "_UNIX"
#  endif
# endif
#endif
   
#define LANG_MAX_SYMBOLS 500
/* maximum number of global symbols--- slang builtin, functions, global vars */

/* Subtypes */
#define ERROR_BLOCK	0x01
/* 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... */
} Array_Type;

/* maximum size of run time stack */
#define LANG_MAX_STACK_LEN 1000
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 *);

/* 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 long SLmake_string(char *);
extern void SLadd_name(char *, long, unsigned short);
extern void SLang_clear_error(void);
		     
