lpc4/lib/
lpc4/lib/doc/efun/
lpc4/lib/doc/lfun/
lpc4/lib/doc/operators/
lpc4/lib/doc/simul_efuns/
lpc4/lib/doc/types/
lpc4/lib/etc/
lpc4/lib/include/
lpc4/lib/include/arpa/
lpc4/lib/obj/d/
lpc4/lib/save/
lpc4/lib/secure/
lpc4/lib/std/
lpc4/lib/std/living/
#ifndef INTERPRET_H
#define INTERPRET_H

struct shared;
struct regexp;

union storage_union
{
  float fnum;
  int number;
  struct shared *string;
  struct object *ob;
  struct vector *vec;
  struct lvalue *lvalue;
  struct regexp *regexp;
  int *ref;
};

/*
 * The value stack element.
 * If it is a string, then the way that the string has been allocated differ,
 * wich will affect how it should be freed.
 */
struct svalue
{
  unsigned short type;
  unsigned short subtype;
  union storage_union u;
};

/* 0 must be without need to be freed */
#define T_POINTER	0
#define T_OBJECT	1
#define T_MAPPING	2
#define T_LIST		3
#define T_ALIST_PART    4
#define T_FUNCTION      5
#define T_REGEXP        6
#define T_STRING	7
#define T_FLOAT         8
#define T_LVALUE	9
#define T_NUMBER	10
#define T_NOTHING       254
#define T_ANY           255

#ifdef STRALLOC_GC
#define MAX_REF_TYPE T_REGEXP
#else
#define MAX_REF_TYPE T_STRING
#endif

#define T_INT           T_NUMBER

#define BT_LVALUE       (1<<T_LVALUE)
#define BT_NUMBER       (1<<T_NUMBER)
#define BT_STRING	(1<<T_STRING)
#define BT_POINTER	(1<<T_POINTER)
#define BT_OBJECT	(1<<T_OBJECT)
#define BT_MAPPING	(1<<T_MAPPING)
#define BT_LIST		(1<<T_LIST)
#define BT_ALIST_PART   (1<<T_ALIST_PART)
#define BT_FUNCTION     (1<<T_FUNCTION)
#define BT_FLOAT        (1<<T_FLOAT)
#define BT_REGEXP       (1<<T_REGEXP)
#define BT_INT          (1<<T_INT)
#define BT_ANY          0xffff
/* these types uses the .u.vec */
#define BT_VECTOR (BT_ALIST_PART | BT_POINTER | BT_MAPPING | BT_LIST)

#define IS_TYPE(X,Y) ((1<<(X).type) & (Y))

/* different types of zeros */
#define NUMBER_NUMBER 0 /* normal number */
#define NUMBER_UNDEFINED 1 /* value not present */
#define NUMBER_DESTRUCTED_OBJECT 2 /* a destructed object */
#define NUMBER_DESTRUCTED_FUNCTION 3 /* a function in a destructed object */

#define LVALUE_INDEX 0
#define LVALUE_RANGE 1
#define LVALUE_LOCAL 2
#define LVALUE_GLOBAL 3
#define LVALUE_SHORT_GLOBAL 4

#define LVALUES 800

struct lvalue
{
  short type;
  short rttype;
  union ptr
  {
    struct svalue *sval;
    union storage_union *uval;
  } ptr;
  struct svalue ind;
};

struct lnode_def;
void free_vector PROT((struct vector *));
void free_all_values();

/*
 * Control stack element.
 * 'prog' is usually same as 'ob->prog' (current_object), except when
 * when the current function is defined by inheritance.
 * The pointer, csp, will point to the values that will be used at return.
 */
struct control_stack
{
  struct object *comgiver;	/* Always save the command giver... */
  struct object *ob;		/* Current object */
  struct program *prog;		/* Current program */
  int num_local_variables;	/* Local + arguments */
  int num_of_arguments;		/* Local + arguments */
  char *pc;
  struct svalue *fp;
  struct function *funp;	/* Only used for tracebacks */
  int func;			/* funp==prog->funcions[func] */
  int function_index_offset;	/* Used when executing functions in inherited
				   programs */
  int variable_index_offset;	/* Same */
  struct vector *va_args;	/* remaining arguments */
};

#define IS_ZERO(x) (!(x) || (((x)->type == T_NUMBER) && ((x)->u.number == 0)))
#define SET_TO_ZERO(x) ((x).type=T_NUMBER,(x).subtype=NUMBER_NUMBER,(x).u.number=0)
#define SET_TO_ONE(x) ((x).type=T_NUMBER,(x).subtype=NUMBER_NUMBER,(x).u.number=1)
#define SET_TO_UNDEFINED(x) ((x).type=T_NUMBER,(x).subtype=NUMBER_UNDEFINED,(x).u.number=0)
#define SET_STR(X,Y) ((X)->type=T_STRING,(X)->u.string=BASE(Y))

struct svalue *apply_lfun(int fun,struct object *ob,int num_arg,int ignorestatic);
struct svalue *apply PROT((char *, struct object *, int,int));
struct svalue *apply_shared PROT((char *, struct object *, int,int));
int apply_lambda_low(struct object *,int,int,int);
struct svalue *apply_lambda(struct svalue *,int,int);
struct svalue *apply_master_ob PROT((char *fun, int num_arg));
struct svalue *safe_apply (char *fun,struct object * ob,int num_arg);
struct svalue *safe_apply_lambda(struct svalue *lambda,int num_arg);
struct svalue *apply_numbered_fun(struct object *o,int fun,int num_arg,int ignorestatic);

void push_string PROT((char *));
void push_number PROT((int));
void push_object PROT((struct object *));
int inter_sscanf PROT((int));
void assert_master_ob_loaded();
void check_eval_cost();
char *function_exists PROT((char *, struct object *));
char *function_exists_in_prog(char *fun,struct program *prog);
int get_line_number_if_any PROT((void));
void check_a_lot_ref_counts PROT((struct program *));
void clear_state PROT((void));
void reset_machine PROT((int));
void push_svalue PROT((struct svalue *));
void push_new_shared_string(char *p);
void call_function PROT((struct program *, struct function *));
int find_function(char *fun,struct program *prog);
int find_shared_string_function(char *fun,struct program *prog);
void pop_stack();
void push_zero();
void push_shared_string(char *);
void push_malloced_string(char *);
void pop_n_elems(int);
void bad_arg(int arg,int instruction)  ATTRIBUTE((noreturn));
void push_vector(struct vector *v);
void push_one();
struct svalue *find_value(int num);
void eval_instruction(char *p);
INLINE void push_mapping(struct vector *v);

void assign_svalue PROT((struct svalue *, struct svalue *));
void move_svalue PROT((struct svalue *, struct svalue *));
INLINE void assign_svalue_no_free PROT((struct svalue *to, struct svalue *from));
#ifdef DEBUG
void assign_svalue_raw PROT((struct svalue *to, struct svalue *from));
#else

#define assign_svalue_raw(TO,FROM) \
  { struct svalue t; *(TO)=t=*(FROM); if(t.type<=MAX_REF_TYPE) t.u.ref[0]++; }
     
#endif
INLINE void free_svalue PROT((struct svalue *));
INLINE void free_svalues PROT((struct svalue *,int));
INLINE void free_lvalue PROT((struct lvalue *));
INLINE void push_control_stack(struct function *funp);
void pop_control_stack();
void push_pop_error_context (int push);
INLINE void push_conditional(int f);
INLINE void copy_svalue(struct svalue *dest,struct svalue *src);
void copy_svalues_no_free(struct svalue *to,struct svalue *from,int num);
void copy_svalues(struct svalue *,struct svalue *,int);
void copy_svalues_raw(struct svalue *,struct svalue *,int);
INLINE void push_list(struct vector *v);

INLINE void assign_short_svalue_no_free(union storage_union *to,
					struct svalue *from,
					unsigned short type);
INLINE void assign_short_svalue(union storage_union *to,
				struct svalue *from,
				unsigned short type);
INLINE void free_short_svalue(union storage_union *u,
			      unsigned short type);
INLINE void assign_svalue_from_short_no_free(struct svalue *to,
				     union storage_union *from,
				     unsigned short type);

#define APPLY_MASTER_OB(RET,FUN,ARGS) \
{ \
  static int fun_,master_cnt=0; \
  extern struct object *master_ob; \
  assert_master_ob_loaded(); \
  if(master_cnt!=master_ob->prog->id) \
  { \
    fun_=find_function(FUN,master_ob->prog); \
    master_cnt=master_ob->prog->id; \
  } \
  RET apply_numbered_fun(master_ob,fun_,ARGS,1); \
}
extern struct svalue const_empty_string;
#endif