/*
 * rml-select.h
 */
#define RML_SWITCH
/* config.h for Intel x86 / Mingw32 / gcc */

/* the following section was generated by repchk */
typedef int rml_sint_t;
typedef unsigned int rml_uint_t;
#define RML_LOG2_SIZE_INT 2
#define RML_SIZE_INT 4
#define RML_SIZE_DBL 8
#define RML_DBL_PAD
/* end of repchk-generated section */

#define	RML_CLOCK_ANSIC

#define	RML_ALLOCA_BUILTIN

#define rml_setjmp	setjmp
#define rml_longjmp	longjmp

#ifdef	RML_PLAIN
#define RML_YOUNG_SIZE	(1024*1024)
#endif
#ifdef	RML_SWITCH
#define RML_YOUNG_SIZE	(72*1024)
#endif

#ifdef	RML_PLAIN
#define RML_STATE_JOIN
#define RML_STATE_APTR
#endif
#ifdef	RML_SWITCH
#define RML_STATE_JOIN
#define RML_STATE_APTR
#endif

#define RML_GCCGOTO
#define RML_GCCGOTO_NOSHIFT
/* starting rml.h */
#ifndef _RML_H_
#define _RML_H_
/*

    This file is part of Relational Meta-Language (RML).
	http://www.ida.liu.se/~pelab/rml

RML COPYRIGHT NOTICE, LICENSE AND DISCLAIMER.

------------------------------------------------------------------------
Portions Copyright (c) 2002-2007 by Adrian Pop
(Versions above rml-2.1.8)

Permission to use, copy, modify, and distribute this software and
its documentation for NON-COMMERCIAL purposes and without fee is hereby 
granted, provided that this copyright notice appear in all copies and 
that both the copyright notice and this permission notice and warranty
disclaimer appear in supporting documentation, and that the name of
The Author not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior permission.
For COMMERCIAL uses of versions above rml-2.1.8 please contact 
Adrian Pop, adrpo@ida.liu.se. 

THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
USE OR PERFORMANCE OF THIS SOFTWARE.

------------------------------------------------------------------------
Portions Copyright (c) 1994-2000 by Mikael Pettersson.
(Versions up to rml-2.1.8)

Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both the copyright notice and this permission notice and warranty
disclaimer appear in supporting documentation, and that the name of
The Author not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior permission.

THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
USE OR PERFORMANCE OF THIS SOFTWARE.

 * rml-core.h
 */
/*
 * A value is represented as a 32-bit quantity with a tag in the lowest bit.
 * An even value i<<1 represents the integer i.
 * An odd value p+3 represents (a pointer to) the node at even address p-3.
 * A value is typed as `void*'. When manipulated as an integer (possibly unsigned),
 * the typedef rml_sint_t (or rml_uint_t) is used. This type is either int or long.
 * False and true are represented as the fixnums 0 and 1, respectively.
 *
 * On a 64-bit machine, a value is a 64-bit quantity.
 */
#define RML_IMMEDIATE(i)	((void*)(i))
#define RML_TAGFIXNUM(i)	((i) << 1)
#define RML_UNTAGFIXNUM(x)	((rml_sint_t)(x) >> 1)	/* SIGNED right-shift */
#define RML_FALSE		RML_IMMEDIATE(RML_TAGFIXNUM(0))
#define RML_TRUE		RML_IMMEDIATE(RML_TAGFIXNUM(1))
#define RML_ISIMM(x)		(!((rml_uint_t)(x) & 1))
#define RML_FIXNUM_AND(x,y)	RML_IMMEDIATE((rml_sint_t)(x) & (rml_sint_t)(y))
#define RML_FIXNUM_OR(x,y)	RML_IMMEDIATE((rml_sint_t)(x) | (rml_sint_t)(y))
#define RML_FIXNUM_LT(x,y)	((rml_sint_t)(x) <  (rml_sint_t)(y))
#define RML_FIXNUM_LE(x,y)	((rml_sint_t)(x) <= (rml_sint_t)(y))
#define RML_FIXNUM_EQ(x,y)	((x) == (y))
#define RML_FIXNUM_NE(x,y)	((x) != (y))
#define RML_FIXNUM_GE(x,y)	((rml_sint_t)(x) >= (rml_sint_t)(y))
#define RML_FIXNUM_GT(x,y)	((rml_sint_t)(x) >  (rml_sint_t)(y))
#define RML_FIXNUM_ADD(x,y)	RML_IMMEDIATE((rml_sint_t)(x) + (rml_sint_t)(y))
#define RML_FIXNUM_DIV(x,y)	RML_IMMEDIATE(RML_TAGFIXNUM((rml_sint_t)(x) / (rml_sint_t)(y)))
#define RML_FIXNUM_MOD(x,y)	RML_IMMEDIATE((rml_sint_t)(x) % (rml_sint_t)(y))
#define RML_FIXNUM_MUL(x,y)	RML_IMMEDIATE((rml_sint_t)(x) * RML_UNTAGFIXNUM(y))
#define RML_FIXNUM_NEG(x)	RML_IMMEDIATE(-(rml_sint_t)(x))
#define RML_FIXNUM_SUB(x,y)	RML_IMMEDIATE((rml_sint_t)(x) - (rml_sint_t)(y))
#define RML_TAGPTR(p)		((void*)((char*)(p) + 3))
#define RML_UNTAGPTR(x)		((void*)((char*)(x) - 3))
#define RML_GETHDR(x)		(*(rml_uint_t*)RML_UNTAGPTR(x))

/*
 * A word is a 32-bit quantity.
 * A node is a word-aligned structure, starting with a 32-bit unsigned header.
 * The high 22 bits of the header, `slots', contain the number of words
 * of the node, not counting the header itself.
 * The low 10 bits of the header contain a tag.
 * [ABCDEFGH00]	a structure with constructor A*128+B*64+C*32+D*16+E*8+F*4+G*2+H
 * [0000000001]	an unbound reference node; `slots' is 1
 * [0000000010]	an instantiated reference node; `slots' is 1
 * [XY00000101]	a byte string with `slots*4+X*2+Y-4' bytes
 *		slots is always >= 1, and a '\0' follows the last byte
 * [0000001001]	a 64-bit floating-point value; `slots' is 2
 * [xxxxxxxx11]	(used during garbage collection) a forwarded node;
 *		the header itself is the forwarding address, i.e.
 *		the header is RML_TAGPTR(forward_address)
 *
 * (IDEA: let RML_BOUNDHDR be a special case of constructor node, using tag 0)
 *
 * Bit 0 is zero if the node contains pointers, 1 otherwise.
 * Since structure headers have zeroes in their lowest two bits, they
 * could be used to directly index jump tables.
 *
 * On a 64-bit machine, words are 64 bits, the header is 64 bits, `slots'
 * is 54 bits, and strings and reals have the following tags:
 * [XYZ0000101]	a byte string with `slots*8+X*4*Y*2+Z-8' bytes
 * [0000001001]	a 64-bit floating-point value; `slots' is 1
 *
 * The definition of RML_STRINGHDR(nbytes) is
 *	((nbytes + RML_SIZE_INT) << (10-RML_LOG2_SIZE_INT)) + 5
 * but this requires 3 arithmetic operations (add; shift; add).
 * Noting that (x + y) << z == (x << z) + (y << z), we have
 *	(nbytes<<(10-RML_LOG2_SIZE_INT))+(RML_SIZE_INT<<(10-RML_LOG2_SIZE_INT))+5
 * The middle expression simplifies to (1 << 10), so the final form is:
 *	(nbytes << (10-RML_LOG2_SIZE_INT)) + ((1 << 10) + 5)
 * which only requires 2 arithmetic operations (shift; add).
 */
#define RML_UNBOUNDHDR		(0x401)
#define RML_BOUNDHDR		(0x402)
#define RML_STRINGHDR(nbytes)	(((nbytes)<<(10-RML_LOG2_SIZE_INT))+((1<<10)+5))
#define RML_HDRISSTRING(hdr)	(((hdr) & ((1<<(10-RML_LOG2_SIZE_INT))-1)) == 5)
#define RML_HDRSTRLEN(hdr)	(((hdr) >> (10-RML_LOG2_SIZE_INT)) - RML_SIZE_INT)
#define RML_REALHDR		(((RML_SIZE_DBL/RML_SIZE_INT) << 10) + 9)
#define RML_STRUCTHDR(slots,ctor) (((slots) << 10) + (((ctor) & 255) << 2))
#define RML_HDRISSTRUCT(hdr)	(!((hdr) & 3))
#define RML_HDRCTOR(hdr)	(((hdr) >> 2) & 255)
#define RML_NILHDR		RML_STRUCTHDR(0,0)
#define RML_CONSHDR		RML_STRUCTHDR(2,1)
#define RML_HDRSLOTS(hdr)	((hdr) >> 10)
#define RML_HDRHASPTRS(hdr)	(!((hdr) & 1))
#define RML_HDRISFORWARD(hdr)	(((hdr) & 3) == 3)

/*
 * Node layout and access macros
 */

struct rml_header {
    rml_uint_t header;
};

/* REFERENCES */

struct rml_ref {
    rml_uint_t header;	/* RML_{UN,}BOUNDHDR */
    void *data;
};
#define RML_REFDATA(x) (((struct rml_ref*)RML_UNTAGPTR(x))->data)

/* STRINGS */

struct rml_string {
    rml_uint_t header;	/* RML_STRINGHDR(bytes) */
    char data[1];	/* `bytes' elements + terminating '\0' */
};
#define RML_STRINGDATA(x) (((struct rml_string*)RML_UNTAGPTR(x))->data)

#define RML_DEFSTRINGLIT(NAME,LEN,VAL)	\
    struct {				\
	rml_uint_t header;		\
	char data[LEN+1];		\
    } NAME = { RML_STRINGHDR(LEN), VAL }
#define RML_REFSTRINGLIT(NAME) RML_TAGPTR(&(NAME).header)

/* REALS */

struct rml_real {
    rml_uint_t header;	/* RML_REALHDR */
    rml_uint_t data[RML_SIZE_DBL/RML_SIZE_INT];
};
#define RML_REALDATA(x) (((struct rml_real*)RML_UNTAGPTR(x))->data)

#ifdef	RML_DBL_PAD
struct rml_real_lit {	/* there must be no padding between `header' and `data' */
    rml_uint_t filler;
    rml_uint_t header;
    double data;
};
#define RML_DEFREALLIT(NAME,VAL) struct rml_real_lit NAME = {0,RML_REALHDR,VAL}
#else	/* !RML_DBL_PAD */
struct rml_real_lit {	/* there must be no padding between `header' and `data' */
    rml_uint_t header;
    double data;
};
#define RML_DEFREALLIT(NAME,VAL) struct rml_real_lit NAME = {RML_REALHDR,VAL}
#endif	/* RML_DBL_PAD */
#define RML_REFREALLIT(NAME) RML_TAGPTR(&(NAME).header)

#ifdef	RML_DBL_STRICT
union rml_double_as_words {
    double d;
    rml_uint_t data[2];
};
extern double rml_prim_get_real(void*);
extern void rml_prim_set_real(struct rml_real*, double);
#else	/* !RML_DBL_STRICT */
#define rml_prim_get_real(x)	(*(double*)RML_REALDATA(x))
#define rml_prim_set_real(p,d)	(*(double*)((p)->data) = (d))
#endif	/* RML_DBL_STRICT */

/* STRUCTS */

struct rml_struct {
    rml_uint_t header;	/* RML_STRUCTHDR(slots,ctor) */
    void *data[1];	/* `slots' elements */
};
#define RML_STRUCTDATA(x) (((struct rml_struct*)RML_UNTAGPTR(x))->data)
#define RML_CAR(X)	RML_FETCH(RML_OFFSET(RML_UNTAGPTR(X),1))
#define RML_CDR(X)	RML_FETCH(RML_OFFSET(RML_UNTAGPTR(X),2))

#define RML_DEFSTRUCTLIT(NAME,LEN,CON)	\
    struct {				\
	rml_uint_t header;		\
	void *data[LEN];		\
    } NAME = { RML_STRUCTHDR(LEN,CON),
#define RML_DEFSTRUCT0LIT(NAME,CON) struct rml_header NAME = { RML_STRUCTHDR(0,CON) }
#define RML_REFSTRUCTLIT(NAME) RML_TAGPTR(&(NAME).header)
#define __CRAP }	/* restore Emacs C-mode indentation state */

/*
 * Additional operators used by the C code
 */
#define RML_OFFSET(p,i)		((void*)((void**)(p) + (i)))
#define RML_FETCH(p)		(*(void**)(p))
#define RML_STORE(dst,val)	(*(void**)(dst) = (val))

/*
 * Strictly internal declarations
 */
extern rml_sint_t rml_prim_atoi(const struct rml_string*);
#define RML_CLOCKS_PER_SEC	1000	/* milliseconds */
extern unsigned long rml_prim_clock(void);
extern char rml_flag_bench;
extern unsigned long rml_clock_start;
extern char rml_flag_gclog;
extern unsigned long rml_gc_start_clock;
extern unsigned long rml_gc_end_clock;
extern double        rml_gc_total_time;
extern char rml_flag_log;
extern unsigned long rml_call_count;
extern char rml_flag_no_stack_check;
extern char rml_debug_enabled;
extern char rml_trace_enabled;

/* adrpo added look into p-gccore.c for more */
/* the young region */
extern void **rml_young_region;
extern unsigned long rml_young_size;

/* the older region */
extern unsigned long rml_older_size;
extern void **rml_current_region;
extern void **rml_current_next;
extern void **rml_reserve_region;

/* the roots */
extern void **rmlSPMIN;
extern void **rml_stack;
extern unsigned long rml_stack_size;

extern void *rml_trail[];
extern unsigned long rml_trail_size;

extern void *rml_array_trail[];
extern unsigned long rml_array_trail_size;

extern unsigned long rml_allocated_from_c;


#ifdef	RML_MORE_LOGGING
extern const char *rml_latest_module;
extern unsigned char rml_latest_known;
extern unsigned long rml_intra_calls;
extern unsigned long rml_intra_known_calls;
extern unsigned long rml_inter_calls;
extern unsigned long rml_inter_known_calls;
#endif	/*RML_MORE_LOGGING*/
extern void rml_exit(int);
extern struct rml_string *rml_prim_mkstring(rml_uint_t, rml_uint_t);
extern void *rml_prim_mkreal(double);

/* adrpo added 2004-11-03 */
extern void rml_show_status(void);


/*
 * Module init stuff
 */
struct rml_gval {
    union {
	void *value;
	struct rml_gval *prev;
    } u;
    struct rml_gval *next;
    const char *name;
};     
#define RML_GVAL_VALUE(GVAL) ((GVAL).u.value)
extern void rml_gval_init(struct rml_gval*);
extern void RML_5finit(void);
extern void Main_5finit(void);	/* user's Main_init */

/*
 * Memory allocation operations
 */
extern void *rml_prim_alloc(rml_uint_t, rml_uint_t);

/*
 * Primitive operations
 * Some of these have both macro and non-macro versions.
 * These could have the same names in ANSI-C, but alas not
 * in some not-quite ANSI-C compilers.
 */
extern const struct rml_header rml_prim_nil;
#define rml_prim_marker()	((void*)(rmlTP))
extern rml_sint_t rml_prim_stringeq(void*, rml_uint_t, const char*);
extern void *rml_prim_equal(void*, void*);
extern void  rml_prim_unwind_(void**);
#define rml_prim_unwind(XTP) do{if(rmlTP<(void**)(XTP))rml_prim_unwind_((void**)(XTP));}while(0)

/*
 * Primitive operations for inlinable primitive procedures.
 * Preconditions like division by zero are supposed to have been checked.
 */
#define RML_PRIM_MKBOOL(FLAG)	((FLAG) ? RML_TRUE : RML_FALSE)
#define RML_PRIM_BOOL_NOT(X)	RML_PRIM_MKBOOL(((X) == RML_FALSE))
#define RML_PRIM_INT_NEG(X)	RML_FIXNUM_NEG((X))
#define RML_PRIM_INT_ABS(X)	(RML_FIXNUM_LT((X),RML_IMMEDIATE(RML_TAGFIXNUM(0))) ? RML_FIXNUM_NEG((X)) : (X))
#define RML_PRIM_BOOL_AND(X,Y)	RML_FIXNUM_AND((X),(Y))
#define RML_PRIM_BOOL_OR(X,Y)	RML_FIXNUM_OR((X),(Y))
#define RML_PRIM_INT_ADD(X,Y)	RML_FIXNUM_ADD((X),(Y))
#define RML_PRIM_INT_SUB(X,Y)	RML_FIXNUM_SUB((X),(Y))
#define RML_PRIM_INT_MUL(X,Y)	RML_FIXNUM_MUL((X),(Y))
#define RML_PRIM_INT_DIV(X,Y)	RML_FIXNUM_DIV((X),(Y))
#define RML_PRIM_INT_MOD(X,Y)	RML_FIXNUM_MOD((X),(Y))
#define RML_PRIM_INT_MAX(X,Y)	(RML_FIXNUM_GE((X),(Y)) ? (X) : (Y))
#define RML_PRIM_INT_MIN(X,Y)	(RML_FIXNUM_LE((X),(Y)) ? (X) : (Y))
#define RML_PRIM_INT_LT(X,Y)	RML_PRIM_MKBOOL(RML_FIXNUM_LT((X),(Y)))
#define RML_PRIM_INT_LE(X,Y)	RML_PRIM_MKBOOL(RML_FIXNUM_LE((X),(Y)))
#define RML_PRIM_INT_EQ(X,Y)	RML_PRIM_MKBOOL(RML_FIXNUM_EQ((X),(Y)))
#define RML_PRIM_INT_NE(X,Y)	RML_PRIM_MKBOOL(RML_FIXNUM_NE((X),(Y)))
#define RML_PRIM_INT_GE(X,Y)	RML_PRIM_MKBOOL(RML_FIXNUM_GE((X),(Y)))
#define RML_PRIM_INT_GT(X,Y)	RML_PRIM_MKBOOL(RML_FIXNUM_GT((X),(Y)))

/*
 * Handling of external (user) roots.
 *
 * - User defines a function "rml_user_gc()".
 * - rml_user_gc() is called from the RML gc at gc time.
 *   The user's function is required to find ALL external references
 *   into the RML heap and to call rml_user_gc_callback() on the
 *   address of each such reference. It is safe to call the callback
 *   on any cell containing an RML value.
 *   For performance, the callback is passed a pointer to a vector
 *   of references and its length.
 *   The rml_user_gc() function should be prepared to find and ignore
 *   already-forwarded objects; use the RML_HDRISFORWARD() test for this.
 * - The RML library provides a dummy implementation of rml_user_gc(),
 *   for applications not needing gc of external roots.
 */
struct rml_xgcstate;	/* opaque for users */
extern void rml_user_gc_callback(struct rml_xgcstate *state, void **vec, rml_uint_t nelts);
extern void rml_user_gc(struct rml_xgcstate *state);

/*
 * rml-state.h
 */
#ifdef	RML_STATE_JOIN

/* 2004-09-28 adrpo added 32 parameters instead of 16 */
#define RML_NUM_ARGS	32

struct rml_state {
  void *SP, *FC, *SC, **TP, *ARGS[RML_NUM_ARGS];
  void **young_next, **young_limit; 
  void **ATP;
  rml_uint_t nrArgs;
};
extern struct rml_state rml_state;

#define rml_state_SP		(rml_state.SP)
#define rml_state_FC		(rml_state.FC)
#define rml_state_SC		(rml_state.SC)
#define rml_state_TP		(rml_state.TP)
#define rml_state_ATP		(rml_state.ATP)
#define rml_state_ARGS		(rml_state.ARGS)
#define rml_state_young_next	(rml_state.young_next)
#define rml_state_young_limit	(rml_state.young_limit)
#define rml_state_nrArgs        (rml_state.nrArgs)

#if	defined(RML_STATE_APTR) || defined(RML_STATE_LPTR)

#define rmlSP			(rmlState->SP)
#define rmlFC			(rmlState->FC)
#define rmlSC			(rmlState->SC)
#define rmlTP			(rmlState->TP)
#define rmlA0			(rmlState->ARGS[0])
#define rmlA1			(rmlState->ARGS[1])
#define rmlA2			(rmlState->ARGS[2])
#define rmlA3			(rmlState->ARGS[3])
#define rmlA4			(rmlState->ARGS[4])
#define rmlA5			(rmlState->ARGS[5])
#define rmlA6			(rmlState->ARGS[6])
#define rmlA7			(rmlState->ARGS[7])
#define rmlA8			(rmlState->ARGS[8])
#define rmlA9			(rmlState->ARGS[9])
#define rmlA10			(rmlState->ARGS[10])
#define rmlA11			(rmlState->ARGS[11])
#define rmlA12			(rmlState->ARGS[12])
#define rmlA13			(rmlState->ARGS[13])
#define rmlA14			(rmlState->ARGS[14])
#define rmlA15			(rmlState->ARGS[15])
/* 2004-09-28 adrpo added 16 more parameters */
#define rmlA16			(rmlState->ARGS[16])
#define rmlA17			(rmlState->ARGS[17])
#define rmlA18			(rmlState->ARGS[18])
#define rmlA19			(rmlState->ARGS[19])
#define rmlA20			(rmlState->ARGS[20])
#define rmlA21			(rmlState->ARGS[21])
#define rmlA22			(rmlState->ARGS[22])
#define rmlA23			(rmlState->ARGS[23])
#define rmlA24			(rmlState->ARGS[24])
#define rmlA25			(rmlState->ARGS[25])
#define rmlA26			(rmlState->ARGS[26])
#define rmlA27			(rmlState->ARGS[27])
#define rmlA28			(rmlState->ARGS[28])
#define rmlA29			(rmlState->ARGS[29])
#define rmlA30			(rmlState->ARGS[30])
#define rmlA31			(rmlState->ARGS[31])
#define rml_young_next		(rmlState->young_next)
#define rml_young_limit		(rmlState->young_limit)
#define rmlATP			(rmlState->ATP)
#define rml_nrArgs          (rmlState->nrArgs)

#else	/*!(RML_STATE_APTR || RML_STATE_LPTR)*/

#define rmlSP			(rml_state.SP)
#define rmlFC			(rml_state.FC)
#define rmlSC			(rml_state.SC)
#define rmlTP			(rml_state.TP)
#define rmlA0			(rml_state.ARGS[0])
#define rmlA1			(rml_state.ARGS[1])
#define rmlA2			(rml_state.ARGS[2])
#define rmlA3			(rml_state.ARGS[3])
#define rmlA4			(rml_state.ARGS[4])
#define rmlA5			(rml_state.ARGS[5])
#define rmlA6			(rml_state.ARGS[6])
#define rmlA7			(rml_state.ARGS[7])
#define rmlA8			(rml_state.ARGS[8])
#define rmlA9			(rml_state.ARGS[9])
#define rmlA10			(rml_state.ARGS[10])
#define rmlA11			(rml_state.ARGS[11])
#define rmlA12			(rml_state.ARGS[12])
#define rmlA13			(rml_state.ARGS[13])
#define rmlA14			(rml_state.ARGS[14])
#define rmlA15			(rml_state.ARGS[15])
/* 2004-09-28 adrpo added 16 more parameters */
#define rmlA16			(rml_state.ARGS[16])
#define rmlA17			(rml_state.ARGS[17])
#define rmlA18			(rml_state.ARGS[18])
#define rmlA19			(rml_state.ARGS[19])
#define rmlA20			(rml_state.ARGS[20])
#define rmlA21			(rml_state.ARGS[21])
#define rmlA22			(rml_state.ARGS[22])
#define rmlA23			(rml_state.ARGS[23])
#define rmlA24			(rml_state.ARGS[24])
#define rmlA25			(rml_state.ARGS[25])
#define rmlA26			(rml_state.ARGS[26])
#define rmlA27			(rml_state.ARGS[27])
#define rmlA28			(rml_state.ARGS[28])
#define rmlA29			(rml_state.ARGS[29])
#define rmlA30			(rml_state.ARGS[30])
#define rmlA31			(rml_state.ARGS[31])
#define rml_young_next		(rml_state.young_next)
#define rml_young_limit		(rml_state.young_limit)
#define rml_nrArgs              (rml_state.nrArgs)
#define rmlATP			(rml_state.ATP)


#endif	/*RML_STATE_APTR || RML_STATE_LPTR*/

#else	/*!RML_STATE_JOIN*/

extern void *rmlSP, *rmlFC, *rmlSC, **rmlTP, **rmlATP, *rmlARGS[];
extern void **rml_young_next, **rml_young_limit;
extern rml_uint_t rml_nrArgs;

#define rml_state_SP		rmlSP
#define rml_state_FC		rmlFC
#define rml_state_SC		rmlSC
#define rml_state_TP		rmlTP
#define rml_state_ATP		rmlATP
#define rml_state_ARGS		rmlARGS
#define rml_state_young_next	rml_young_next
#define rml_state_young_limit	rml_young_limit
#define rml_state_nrArgs        rml_nrArgs
#define rmlA0			(rmlARGS[0])
#define rmlA1			(rmlARGS[1])
#define rmlA2			(rmlARGS[2])
#define rmlA3			(rmlARGS[3])
#define rmlA4			(rmlARGS[4])
#define rmlA5			(rmlARGS[5])
#define rmlA6			(rmlARGS[6])
#define rmlA7			(rmlARGS[7])
#define rmlA8			(rmlARGS[8])
#define rmlA9			(rmlARGS[9])
#define rmlA10			(rmlARGS[10])
#define rmlA11			(rmlARGS[11])
#define rmlA12			(rmlARGS[12])
#define rmlA13			(rmlARGS[13])
#define rmlA14			(rmlARGS[14])
#define rmlA15			(rmlARGS[15])
/* 2004-09-27 adrpo added 16 more parameters */
#define rmlA16			(rmlARGS[16])
#define rmlA17			(rmlARGS[17])
#define rmlA18			(rmlARGS[18])
#define rmlA19			(rmlARGS[19])
#define rmlA20			(rmlARGS[20])
#define rmlA21			(rmlARGS[21])
#define rmlA22			(rmlARGS[22])
#define rmlA23			(rmlARGS[23])
#define rmlA24			(rmlARGS[24])
#define rmlA25			(rmlARGS[25])
#define rmlA26			(rmlARGS[26])
#define rmlA27			(rmlARGS[27])
#define rmlA28			(rmlARGS[28])
#define rmlA29			(rmlARGS[29])
#define rmlA30			(rmlARGS[30])
#define rmlA31			(rmlARGS[31])


#endif	/*RML_STATE_JOIN*/
/*
 * rml-labels.h
 * for `dispatching switches'
 */

#ifdef __STDC__
#define RML_GLUE(A,B) A##B
#else /* this may or may not work.. */
#define RML_GLUE(A,B) A/**/B
#endif

typedef struct rml_label {
#ifdef	RML_STATE_APTR
    const struct rml_label	*(*fun)(unsigned, struct rml_state* const);
#else	/*!RML_STATE_APTR*/
    const struct rml_label	*(*fun)(unsigned);
#endif	/*AGPTR*/
    unsigned			tag;
    unsigned			*mask;
} rml_label_t;

typedef const struct rml_label *rml_labptr_t;
#define RML_LABPTR(LABEL)	(&LABEL)
#define RML_LABVAL(LABEL)	RML_IMMEDIATE(&LABEL)

#ifdef	RML_STATE_APTR

#define RML_FORWARD_MODULE(MODULE)	static const rml_label_t *MODULE(unsigned, struct rml_state* const)
#define RML_BEGIN_MODULE(MODULE)	static const rml_label_t *MODULE(unsigned switch_tag, struct rml_state * const rmlState)
#define RML_END_MODULE		/*empty*/
#define RML_APPLY(LABPTR)	((*((LABPTR)->fun))((LABPTR)->tag, rmlState))

#else	/*!RML_STATE_APTR*/

#ifdef	RML_STATE_LPTR

#define RML_FORWARD_MODULE(MODULE)	static const rml_label_t *MODULE(unsigned)
#define RML_BEGIN_MODULE(MODULE)	static const rml_label_t *MODULE(unsigned switch_tag) { struct rml_state * const rmlState = &rml_state;
#define RML_END_MODULE		}
#define RML_APPLY(LABPTR)	((*((LABPTR)->fun))((LABPTR)->tag))

#else	/*!RML_STATE_LPTR*/

#define RML_FORWARD_MODULE(MODULE)	static const rml_label_t *MODULE(unsigned)
#define RML_BEGIN_MODULE(MODULE)	static const rml_label_t *MODULE(unsigned switch_tag)
#define RML_END_MODULE		/*empty*/
#define RML_APPLY(LABPTR)	((*((LABPTR)->fun))((LABPTR)->tag))

#endif	/*RML_STATE_LPTR*/
#endif	/*RML_STATE_APTR*/

/* used internally in librml.a only */
extern const unsigned rml_internal_mask;
#define RML_FORWARD_LABEL(LABEL)	const rml_label_t LABEL
#define RML_BEGIN_LABEL(LABEL)\
RML_FORWARD_MODULE(RML_GLUE(module__,LABEL));\
const rml_label_t LABEL = {RML_GLUE(module__,LABEL),0,(unsigned*)&rml_internal_mask};\
RML_BEGIN_MODULE(RML_GLUE(module__,LABEL))
#define RML_END_LABEL		RML_END_MODULE
#define RML_TAILCALLK(KONT)	return (rml_labptr_t)RML_FETCH((KONT))

/* memory allocation */
extern void rml_prim_gc(rml_uint_t, rml_uint_t);
#define RML_ALLOC(VAR,NWORDS,NARGS,TAGLABEL) do{(VAR)=(void*)rml_young_next;if((rml_young_next=(void**)(VAR)+(NWORDS))>=rml_young_limit){gc_nwords=(NWORDS);gc_nargs=(NARGS);switch_tag=TAGLABEL;goto collect;}}while(0)

/*
 * rml-predef.h
 */

extern void rml_prim_motor(rml_labptr_t);
extern int rml_prim_once(rml_labptr_t);	/* C calls RML */
extern RML_FORWARD_LABEL(Main__main);	/* user code's entry point */
/* let the print relation be available for non-debug-version-rml-library also */
extern void rmldb_var_print(void *p);

/*
 * Standard procedures
 * adrpo added Java named RML buildin relations 2005-11-10
 */
extern RML_FORWARD_LABEL(RML__bool_5fand);
extern RML_FORWARD_LABEL(RML__bool_5fnot);
extern RML_FORWARD_LABEL(RML__bool_5for);
   /* java named */
#define RML__boolAnd RML__bool_5fand
#define RML__boolNot RML__bool_5fnot
#define RML__boolOr RML__bool_5for


/* chars */
extern RML_FORWARD_LABEL(RML__int_5fint);
extern RML_FORWARD_LABEL(RML__list_5fstring);
extern RML_FORWARD_LABEL(RML__string_5flist);
extern RML_FORWARD_LABEL(RML__string_5fnth);
extern RML_FORWARD_LABEL(RML__string_5fget);
extern RML_FORWARD_LABEL(RML__string_5fsetnth);
extern RML_FORWARD_LABEL(RML__string_5fupdate);
extern RML_FORWARD_LABEL(RML__string_5fequal);
extern RML_FORWARD_LABEL(RML__string_5fcompare);
#define RML__char_5fint	RML__int_5fint
#define RML__int_5fchar	RML__int_5fint
   /* java named */
#define RML__intChar        RML__int_5fint
#define RML__charInt        RML__int_5fint
#define RML__listString     RML__list_5fstring
#define RML__stringList     RML__string_5flist
#define RML__stringNth      RML__string_5fnth
#define RML__stringGet      RML__string_5fget
#define RML__stringSetNth   RML__string_5fset_5fnth
#define RML__stringUpdate   RML__string_5fupdate
#define RML__stringEqual    RML__string_5fequal
#define RML__stringCompare  RML__string_5fcompare

/* string chars */
extern RML_FORWARD_LABEL(RML__string_5fchar_5fint);
extern RML_FORWARD_LABEL(RML__int_5fstring_5fchar);
extern RML_FORWARD_LABEL(RML__list_5fstring_5fchar);
extern RML_FORWARD_LABEL(RML__string_5flist_5fstring_5fchar);
extern RML_FORWARD_LABEL(RML__string_5fnth_5fstring_5fchar);
extern RML_FORWARD_LABEL(RML__string_5fget_5fstring_5fchar);
extern RML_FORWARD_LABEL(RML__string_5fsetnth_5fstring_5fchar);
extern RML_FORWARD_LABEL(RML__string_5fupdate_5fstring_5fchar);
   /* java named */
#define RML__stringCharInt           RML__string_5fchar_5fint
#define RML__intStringChar           RML__int_5fstring_5fchar
#define RML__listStringChar          RML__list_5fstring_5fchar
#define RML__stringListStringChar    RML__string_5flist_5fstring_5fchar
#define RML__stringNthStringChar     RML__string_5fnth_5fstring_5fchar
#define RML__stringGetStringChar     RML__string_5fget_5fstring_5fchar
#define RML__stringSetNthStringChar  RML__string_5fsetnth_5fstring_5fchar
#define RML__stringUpdateStringChar  RML__string_5fupdate_5fstring_5fchar

extern RML_FORWARD_LABEL(RML__int_5fabs);
extern RML_FORWARD_LABEL(RML__int_5fadd);
extern RML_FORWARD_LABEL(RML__int_5fdiv);
extern RML_FORWARD_LABEL(RML__int_5feq);
extern RML_FORWARD_LABEL(RML__int_5fge);
extern RML_FORWARD_LABEL(RML__int_5fgt);
extern RML_FORWARD_LABEL(RML__int_5fle);
extern RML_FORWARD_LABEL(RML__int_5flt);
extern RML_FORWARD_LABEL(RML__int_5fmax);
extern RML_FORWARD_LABEL(RML__int_5fmin);
extern RML_FORWARD_LABEL(RML__int_5fmod);
extern RML_FORWARD_LABEL(RML__int_5fmul);
extern RML_FORWARD_LABEL(RML__int_5fne);
extern RML_FORWARD_LABEL(RML__int_5fneg);
extern RML_FORWARD_LABEL(RML__int_5freal);
extern RML_FORWARD_LABEL(RML__int_5fstring);
extern RML_FORWARD_LABEL(RML__int_5fsub);
   /* java named */
#define RML__intAbs    RML__int_5fabs
#define RML__intAdd    RML__int_5fadd
#define RML__intDiv    RML__int_5fdiv
#define RML__intEq     RML__int_5feq
#define RML__intGe     RML__int_5fge
#define RML__intGt     RML__int_5fgt
#define RML__intLe     RML__int_5fle
#define RML__intLt     RML__int_5flt
#define RML__intMax    RML__int_5fmax
#define RML__intMin    RML__int_5fmin
#define RML__intMod    RML__int_5fmod
#define RML__intMul    RML__int_5fmul
#define RML__intNe     RML__int_5fne
#define RML__intNeg    RML__int_5fneg
#define RML__intReal   RML__int_5freal
#define RML__intString RML__int_5fstring
#define RML__intSub    RML__int_5fsub

/* lists */
extern RML_FORWARD_LABEL(RML__list_5fappend);
extern RML_FORWARD_LABEL(RML__list_5fdelete);
extern RML_FORWARD_LABEL(RML__list_5flength);
extern RML_FORWARD_LABEL(RML__list_5fmember);
extern RML_FORWARD_LABEL(RML__list_5fnth);
extern RML_FORWARD_LABEL(RML__list_5fget);
extern RML_FORWARD_LABEL(RML__list_5freverse);
extern RML_FORWARD_LABEL(RML__list_5fvector);
extern RML_FORWARD_LABEL(RML__list_5farray);
   /* java named */
#define RML__listAppend  RML__list_5fappend
#define RML__listDelete  RML__list_5fdelete
#define RML__listLength  RML__list_5flength
#define RML__listMember  RML__list_5fmember
#define RML__listNth     RML__list_5fnth
#define RML__listGet     RML__list_5fget
#define RML__listReverse RML__list_5freverse
#define RML__listVector  RML__list_5fvector
#define RML__listArray   RML__list_5farray

/* logical variables */
extern RML_FORWARD_LABEL(RML__lvar_5fget);
extern RML_FORWARD_LABEL(RML__lvar_5fnew);
extern RML_FORWARD_LABEL(RML__lvar_5fset);
   /* java named */
#define RML__lvarGet RML__lvar_5fget
#define RML__lvarNew RML__lvar_5fnew
#define RML__lvarSet RML__lvar_5fset

/* reals */
extern RML_FORWARD_LABEL(RML__real_5fabs);
extern RML_FORWARD_LABEL(RML__real_5fadd);
extern RML_FORWARD_LABEL(RML__real_5fatan);
extern RML_FORWARD_LABEL(RML__real_5fcos);
extern RML_FORWARD_LABEL(RML__real_5fdiv);
extern RML_FORWARD_LABEL(RML__real_5feq);
extern RML_FORWARD_LABEL(RML__real_5fexp);
extern RML_FORWARD_LABEL(RML__real_5ffloor);
extern RML_FORWARD_LABEL(RML__real_5fge);
extern RML_FORWARD_LABEL(RML__real_5fgt);
extern RML_FORWARD_LABEL(RML__real_5fint);
extern RML_FORWARD_LABEL(RML__real_5fle);
extern RML_FORWARD_LABEL(RML__real_5fln);
extern RML_FORWARD_LABEL(RML__real_5flt);
extern RML_FORWARD_LABEL(RML__real_5fmax);
extern RML_FORWARD_LABEL(RML__real_5fmin);
extern RML_FORWARD_LABEL(RML__real_5fmod);
extern RML_FORWARD_LABEL(RML__real_5fmul);
extern RML_FORWARD_LABEL(RML__real_5fne);
extern RML_FORWARD_LABEL(RML__real_5fneg);
extern RML_FORWARD_LABEL(RML__real_5fpow);
extern RML_FORWARD_LABEL(RML__real_5fsin);
extern RML_FORWARD_LABEL(RML__real_5fsqrt);
extern RML_FORWARD_LABEL(RML__real_5fstring);
extern RML_FORWARD_LABEL(RML__real_5fsub);
extern RML_FORWARD_LABEL(RML__real_5fasin);
extern RML_FORWARD_LABEL(RML__real_5facos);
extern RML_FORWARD_LABEL(RML__real_5fatan);
extern RML_FORWARD_LABEL(RML__real_5fatan2);
extern RML_FORWARD_LABEL(RML__real_5fcosh);
extern RML_FORWARD_LABEL(RML__real_5flog);
extern RML_FORWARD_LABEL(RML__real_5flog10);
extern RML_FORWARD_LABEL(RML__real_5fsinh);
extern RML_FORWARD_LABEL(RML__real_5ftanh);
   /* java named */
#define RML__realAbs    RML__real_5fabs
#define RML__realAdd    RML__real_5fadd
#define RML__realAtan   RML__real_5fatan
#define RML__realCos    RML__real_5fcos
#define RML__realDiv    RML__real_5fdiv
#define RML__realEq     RML__real_5feq
#define RML__realExp    RML__real_5fexp
#define RML__realFloor  RML__real_5ffloor
#define RML__realGe     RML__real_5fge
#define RML__realGt     RML__real_5fgt
#define RML__realInt    RML__real_5fint
#define RML__realLe     RML__real_5fle
#define RML__realLn     RML__real_5fln
#define RML__realLt     RML__real_5flt
#define RML__realMax    RML__real_5fmax
#define RML__realMin    RML__real_5fmin
#define RML__realMod    RML__real_5fmod
#define RML__realMul    RML__real_5fmul
#define RML__realNe     RML__real_5fne
#define RML__realNeg    RML__real_5fneg
#define RML__realPow    RML__real_5fpow
#define RML__realSin    RML__real_5fsin
#define RML__realSqrt   RML__real_5fsqrt
#define RML__realString RML__real_5fstring
#define RML__realSub    RML__real_5fsub
#define RML__realAsin   RML__real_5fasin
#define RML__realAcos   RML__real_5facos
#define RML__realAtan2  RML__real_5fatan2
#define RML__realCosh   RML__real_5fcosh
#define RML__realLog    RML__real_5flog
#define RML__realLog10  RML__real_5flog10
#define RML__realSinh   RML__real_5fsinh
#define RML__realTanh   RML__real_5ftanh

/* strings */
extern RML_FORWARD_LABEL(RML__string_5fappend);
extern RML_FORWARD_LABEL(RML__string_5fint);
extern RML_FORWARD_LABEL(RML__string_5flength);
   /* java named */
#define RML__stringAppend RML__string_5fappend
#define RML__stringInt    RML__string_5fint
#define RML__stringLength RML__string_5flength

/* declarative vectors */
extern RML_FORWARD_LABEL(RML__vector_5flength);
extern RML_FORWARD_LABEL(RML__vector_5flist);
extern RML_FORWARD_LABEL(RML__vector_5fnth);
extern RML_FORWARD_LABEL(RML__vector_5fget);
extern RML_FORWARD_LABEL(RML__vector_5fsetnth);
extern RML_FORWARD_LABEL(RML__vector_5fupdate);
extern RML_FORWARD_LABEL(RML__vector_5fcreate);
extern RML_FORWARD_LABEL(RML__vector_5fadd);
extern RML_FORWARD_LABEL(RML__vector_5farray);
extern RML_FORWARD_LABEL(RML__vector_5fcopy);
   /* java named */
#define RML__vectorLength RML__vector_5flength
#define RML__vectorList   RML__vector_5flist
#define RML__vectorNth    RML__vector_5fnth
#define RML__vectorGet    RML__vector_5fget
#define RML__vectorSetNth RML__vector_5fsetnth
#define RML__vectorUpdate RML__vector_5fupdate
#define RML__vectorCreate RML__vector_5fcreate
#define RML__vectorAdd    RML__vector_5fadd
#define RML__vectorArray  RML__vector_5farray
#define RML__vectorCopy   RML__vector_5fcopy

/* mutable arrays */
extern RML_FORWARD_LABEL(RML__array_5flength);
extern RML_FORWARD_LABEL(RML__array_5flist);
extern RML_FORWARD_LABEL(RML__array_5fnth);
extern RML_FORWARD_LABEL(RML__array_5fget);
extern RML_FORWARD_LABEL(RML__array_5fsetnth);
extern RML_FORWARD_LABEL(RML__array_5fupdate);
extern RML_FORWARD_LABEL(RML__array_5fcreate);
extern RML_FORWARD_LABEL(RML__array_5fadd);
extern RML_FORWARD_LABEL(RML__array_5fvector);
extern RML_FORWARD_LABEL(RML__array_5fcopy);
   /* java named */
#define RML__arrayLength RML__array_5flength
#define RML__arrayList   RML__array_5flist
#define RML__arrayNth    RML__array_5fnth
#define RML__arrayGet    RML__array_5fget
#define RML__arraySetNth RML__array_5fsetnth
#define RML__arrayUpdate RML__array_5fupdate
#define RML__arrayCreate RML__array_5fcreate
#define RML__arrayAdd    RML__array_5fadd
#define RML__arrayVector RML__array_5fvector
#define RML__arrayCopy   RML__array_5fcopy

/* if expressions */
extern RML_FORWARD_LABEL(RML__if_5fexp);
#define RML__ifExp   RML__if_5fexp

/* misc */
extern RML_FORWARD_LABEL(RML__clock);
extern RML_FORWARD_LABEL(RML__print);
extern RML_FORWARD_LABEL(RML__tick);

/* debugging */
/* let these relation be available in all rml libraries */
/* however their code depends on _RMLDB_DEFINED_ */
extern RML_FORWARD_LABEL(RML__debug_5fprint);
extern RML_FORWARD_LABEL(RML__debug);
extern RML_FORWARD_LABEL(RML__debug_5fpush_5fin01);
extern RML_FORWARD_LABEL(RML__debug_5fpush_5fin02);
extern RML_FORWARD_LABEL(RML__debug_5fpush_5fin03);
extern RML_FORWARD_LABEL(RML__debug_5fpush_5fin04);
extern RML_FORWARD_LABEL(RML__debug_5fpush_5fin05);
extern RML_FORWARD_LABEL(RML__debug_5fpush_5fin06);
extern RML_FORWARD_LABEL(RML__debug_5fpush_5fin07);
extern RML_FORWARD_LABEL(RML__debug_5fpush_5fin08);
extern RML_FORWARD_LABEL(RML__debug_5fpush_5fin09);
extern RML_FORWARD_LABEL(RML__debug_5fpush_5fin10);
extern RML_FORWARD_LABEL(RML__debug_5fpush_5fin11);
extern RML_FORWARD_LABEL(RML__debug_5fpush_5fin12);
extern RML_FORWARD_LABEL(RML__debug_5fpush_5fin13);
extern RML_FORWARD_LABEL(RML__debug_5fpush_5fin14);
extern RML_FORWARD_LABEL(RML__debug_5fpush_5fin15);
extern RML_FORWARD_LABEL(RML__debug_5fpush_5fin16);
extern RML_FORWARD_LABEL(RML__debug_5fpush_5fout01);
extern RML_FORWARD_LABEL(RML__debug_5fpush_5fout02);
extern RML_FORWARD_LABEL(RML__debug_5fpush_5fout03);
extern RML_FORWARD_LABEL(RML__debug_5fpush_5fout04);
extern RML_FORWARD_LABEL(RML__debug_5fpush_5fout05);
extern RML_FORWARD_LABEL(RML__debug_5fpush_5fout06);
extern RML_FORWARD_LABEL(RML__debug_5fpush_5fout07);
extern RML_FORWARD_LABEL(RML__debug_5fpush_5fout08);
extern RML_FORWARD_LABEL(RML__debug_5fpush_5fout09);
extern RML_FORWARD_LABEL(RML__debug_5fpush_5fout10);
extern RML_FORWARD_LABEL(RML__debug_5fpush_5fout11);
extern RML_FORWARD_LABEL(RML__debug_5fpush_5fout12);
extern RML_FORWARD_LABEL(RML__debug_5fpush_5fout13);
extern RML_FORWARD_LABEL(RML__debug_5fpush_5fout14);
extern RML_FORWARD_LABEL(RML__debug_5fpush_5fout15);
extern RML_FORWARD_LABEL(RML__debug_5fpush_5fout16);
extern RML_FORWARD_LABEL(RML__debug_5fshow_5fdepth);

extern void RML__call_debug(char* fileName, int sp, int ep, int sl, int sc, int el, int ec, char* relation, char* call);
#ifndef _RMLDB_COMMAND_H_
#define _RMLDB_COMMAND_H_

/* the commands accepted by the debugger */
#define RMLDB_CMD_NONE 							0000
#define RMLDB_CMD_BREAKPOINT 					1000
#define RMLDB_CMD_DELETE_BREAKPOINT 			1001
#define RMLDB_CMD_CLEAR_BREAKPOINTS 			1002
#define RMLDB_CMD_FUNCTION_BREAKPOINT			1003
#define RMLDB_CMD_DELETE_FUNCTION_BREAKPOINT	1004
#define RMLDB_CMD_STRING_BREAKPOINT 			1005
#define RMLDB_CMD_DELETE_STRING_BREAKPOINT		1006
#define RMLDB_CMD_FAILURE_BREAKPOINT            1007
#define RMLDB_CMD_DELETE_FAILURE_BREAKPOINT     1008
#define RMLDB_CMD_STACK							1009
#define RMLDB_CMD_VARIABLE_VALUE				1010
#define RMLDB_CMD_LAZY_VARIABLE_VALUE			1011
#define RMLDB_CMD_FRAME_VARIABLE_VALUE			1012
#define RMLDB_CMD_FRAME_LAZY_VARIABLE_VALUE		1013

#define RMLDB_CMD_RESUME						2000
#define RMLDB_CMD_STEP							2001
#define RMLDB_CMD_STEP_OVER						2002
#define RMLDB_CMD_STEP_RETURN					2003
#define RMLDB_CMD_RUN							2004
#define RMLDB_CMD_QUIT							2005

/* the response of the debugger to commands */
#define RMLDB_REPLY_OK							"$ok"
#define RMLDB_REPLY_ERROR						"$err"

/* the signals accepted by the debugger  */
#define RMLDB_SIGNAL_SUSPEND					"$u"
#define RMLDB_SIGNAL_QUIT						"$q"


/* the events send by the debugger to the Eclipse UI */
#define RMLDB_EVENT_START						"$t"
#define RMLDB_EVENT_READY						"$rdy"
#define RMLDB_EVENT_STEP						"$s"
#define RMLDB_EVENT_STEP_OVER					"$o"
#define RMLDB_EVENT_STEP_RETURN					"$n"
#define RMLDB_EVENT_RUN							"$r"
#define RMLDB_EVENT_QUIT						"$q"
#define RMLDB_EVENT_SUSPEND						"$u"
#define RMLDB_EVENT_BREAKPOINT					"$b"
#define RMLDB_EVENT_FAILURE_BREAKPOINT          "$bf"
#define RMLDB_EVENT_ERROR						"$err"

typedef struct rmldb_command_t
{
	int ty;   /* the command type */
	union 
	{
		struct brkFile      	 { char *file; int   line;   		} brkFile;
		struct brkFunction  	 { char *file; char *name;   		} brkFunction;		
		struct brkString		 { char *filter;             		} brkString;
        struct brkFailure        { char *filter;                    } brkFailure;        
		struct varValue			 { char *name;       	    		} varValue;
		struct lazyVarValue		 { char *name; int *path;			} lazyVarValue;
		struct frameVarValue     { int frame; int nr;				} frameVarValue;
		struct frameLazyVarValue { int frame; int nr; int *path;	} frameLazyVarValue;
	} data;
} rmldb_command_type;


extern rmldb_command_type* rmldb_current_command;

extern rmldb_command_type* rmldb_mk_cmd(int ty);
extern rmldb_command_type* rmldb_mk_cmd_brkFile          (int ty, char* file, char* line);
extern rmldb_command_type* rmldb_mk_cmd_brkFunction      (int ty, char* file, char* name);
extern rmldb_command_type* rmldb_mk_cmd_brkString        (int ty, char* filter);
extern rmldb_command_type* rmldb_mk_cmd_brkFailure       (int ty, char* filter);
extern rmldb_command_type* rmldb_mk_cmd_varValue         (int ty, char* name);
extern rmldb_command_type* rmldb_mk_cmd_lazyVarValue     (int ty, char* name, char* path);
extern rmldb_command_type* rmldb_mk_cmd_frameVarValue    (int ty, char* frame, char* nr);
extern rmldb_command_type* rmldb_mk_cmd_frameLazyVarValue(int ty, char* frame, char* nr, char* path);
extern int rmldb_freeCommand(rmldb_command_type* cmd);

#endif /* _RMLDB_COMMAND_H_*/
/******************************************************************************
 * @author Adrian Pop [adrpo@ida.liu.se, http://www.ida.liu.se/~adrpo]
 * Copyright (c) 2002-2007, Adrian Pop [adrpo@ida.liu.se],
 * Programming Environments Laboratory (PELAB),
 * Department of Computer and Information Science (IDA), 
 * Linköpings University (LiU). 
 * All rights reserved.
 *
 * http://www.ida.liu.se/~adrpo/license/
 *
 *
 * [ rml-socket.h ] 
 * - Adrian Pop, adrpo@ida.liu.se, http://www.ida.liu.se/~adrpo
 * - creation 2007-02-24
 *   + interface for Windows and Linux sockets
 *   + all things in this file start with rmldb_socket_*
 * - last modified 2007-02-24
 *****************************************************************************/

#ifdef RML_DEBUG
#define RMLDB_SOCKET_PROMPT "rml+mmc-socket>"

#if defined(__MINGW32__) || defined(_MSC_VER)
/*********** MINGW32 && MSVC stuff **********/
#include <winsock2.h>

#define _rmldb_socket_send(x,y,z) send(x,y,z,0)
#define _rmldb_socket_recv(x,y,z) recv(x,y,z,0)
#define _rmldb_socket_close closesocket
#define _rmldb_socket_errorno WSAGetLastError()

#else /***************** unix stuff ***************/
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/unistd.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <netdb.h>

#define _rmldb_socket_send(x,y,z) write(x,y,z)
#define _rmldb_socket_recv(x,y,z) read(x,y,z)
#define _rmldb_socket_close close
#define _rmldb_socket_errorno errno
#define SOCKET_ERROR (-1)
#define INVALID_SOCKET (-1)

#endif

/* 
 * set to 1 to have debugging or to 0 to 
 * disable debugging of the socket communication
 */
extern int   rmldb_socket_debug;
/* 
 * initialize the socket library
 * returns -1 on error and 1 on success.
 */
extern int   rmldb_socket_initialize_library(void);  
/* 
 * cleanups the socket library
 * returns -1 on error and 1 on success.
 */
extern int   rmldb_socket_cleanup_library(void);  

/* 
 * get a socket 
 * returns -1 or the socket
 */
extern int   rmldb_socket_get(void);

/* 
 * binds the given socket on localhost and given port
 * performs bind and listen
 * returns -1 on error and 0 on success
 */
extern int   rmldb_socket_bind_and_listen(int socket, char* hostname, int port);
/* 
 * performs accept on the given socket 
 * returns the new socket or -1 on error
 */
extern int   rmldb_socket_accept(int socket);

/* 
 * close the socket 
 * returns -1 for error or 0 for no error 
 */
extern int   rmldb_socket_close(int socket); 

/* send to socket with error handling */
extern int rmldb_socket_outln(int sock, char *msg);
extern int rmldb_socket_out(int sock, char *msg);

#endif
/* handler.h */
#ifndef HANDLER_H_
#define HANDLER_H_

extern int   aaerror(char*);
extern int   aaparse(void);
extern int   aadebug;

#ifdef RML_DEBUG

#if defined(__MINGW32__) || defined(_MSC_VER)

#if defined(__MINGW32__) /* ********** MINGW32 stuff ******/
#include <signal.h>
#endif

#else /***************** unix stuff ***************/
#include <signal.h>
#endif /* unix vs windows stuff */

/* adrpo - debugger global variables */
extern int   rmldb_cmd_port;    /* listen for commands from the client on this port */
extern int   rmldb_reply_port;  /* listen on this port and send synchronous command replys to the client */
extern int   rmldb_event_port;  /* listen on this port and send event to the client */
extern int   rmldb_signal_port; /* listen on this post and wait for async suspend signals from the client */

typedef struct rmldb_communication
{
	int   cmd_bind_sock;     /* bind and accept on this socket */
	int   cmd_sock;          /* listen for commands on this socket */
	int   reply_bind_sock;   /* bind and accept on this socket */
	int   reply_sock;        /* send reply of commands to this socket */	
	int   event_bind_sock;   /* bind and accept on this socket */
	int   event_sock;        /* send output to this port */
	int   signal_bind_sock;  /* bind and accept on this socket */
	int   signal_sock;       /* listen to async events from client */
} rmldb_communication_type;

extern rmldb_communication_type rmldb_communicator;

extern int rmldb_last_command;
extern int rmldb_startSignalHandler(void* arg);
extern int rmldb_endSignalHandler(void);
extern int rmldb_interpretCommand(void);
extern int rmldb_executeCommand(rmldb_command_type* cmd);
extern int rmldb_sendEvent(char* event);
extern int rmldb_sendReply(char* reply);

#endif /* RML_DEBUG */

#endif /*HANDLER_H_*/
/***********************************************************
 [ load.h ] 
  - Adrian Pop, adrpo@ida.liu.se, http://www.ida.liu.se/~adrpo
  - creation 2005-12-27
    + interface for rml debugging 
    + this file contains all the functions for loading the program database. 
	+ all things in this file start with rmldb_
  - last modified 2007-06-01
************************************************************/
#ifndef _RMLDB_LOAD_H_
#define _RMLDB_LOAD_H_

#define RMLDB_MAX_STRING  1000

/* debugger typedefs */

typedef struct rmldb_range_db
{
  int sl;
  int sc;
  int el;
  int ec;
} rmldb_range_db_t;

typedef struct rmldb_ex_loc
{
   char* file;
   rmldb_range_db_t range;
   char* relation;
   char* goal;
   unsigned long SP;
} rmldb_current_execution_loc_t;

typedef struct rmldb_var_node
{
   char* var_name;
   void* var;
   int depth;
   int direction; /* RMLDB_VAR_IN or RMLDB_VAR_OUT */
   struct rmldb_var_node *prev;
   struct rmldb_var_node *next;
} rmldb_var_node_t;

/* types */

typedef struct rmldb_str
{
   char *name;
   int depth;
   struct rmldb_str *prev;
   struct rmldb_str *next;
} rmldb_str_t;

typedef struct rmldb_str_list
{
	rmldb_str_t* list_start;
	rmldb_str_t* list_end;
} rmldb_str_list_t;

/*
    excerpt from rml.grm
    datatype ident	= IDENT of string
    type tyvar		= ident
    datatype longid	= LONGID of ident option * ident
    datatype ty	= VARty of tyvar
				| CONSty of ty list * longid
				| TUPLEty of ty list
				| RELty of ty list * ty list
%nonterm ty of Absyn.ty
	   | tuple_ty of Absyn.ty list
	   | ty_sans_star of Absyn.ty
	   | ty_comma_seq2 of Absyn.ty list
	   | seq_ty of Absyn.ty list
*/

/* define type ahead, as is it mutually recursive
 * with type components 
 */
struct rmldb_type;

typedef struct rmldb_LISTty
{
   int length;
   struct rmldb_type* list_start; 
   struct rmldb_type* list_end;
} rmldb_LISTty_t;

typedef struct rmldb_VARty { char* id; } rmldb_VARty_t;

typedef struct rmldb_CONSty 
{ 
	rmldb_LISTty_t* list;
	char* id;
} rmldb_CONSty_t;

typedef struct rmldb_TUPLEty 
{ 
	rmldb_LISTty_t* list;
} rmldb_TUPLEty_t;

typedef struct rmldb_RELty 
{ 
	rmldb_LISTty_t* list1;
	rmldb_LISTty_t* list2;
} rmldb_RELty_t;


typedef enum rmldb_tyKind 
{
	RMLDB_eNORMAL,
	RMLDB_eLISTty,
	RMLDB_eVARty,
	RMLDB_eCONSty,
	RMLDB_eTUPLEty,
	RMLDB_eRELty
} rmldb_tyKind_t;

typedef struct rmldb_type
{
   rmldb_tyKind_t kind; /* selects the stufs in the union or no union at all */
   union component_t
   {
	 rmldb_LISTty_t*  l;
	 rmldb_VARty_t*   v;
	 rmldb_CONSty_t*  c;
	 rmldb_TUPLEty_t* t;
	 rmldb_RELty_t*   r;
   } component;
   
   /* this is used to name the component */
   char* name;
   
   /* these are used in rmldb_LISTty */
   int depth;
   struct rmldb_type *prev;
   struct rmldb_type *next;
} rmldb_type_t;

typedef struct rmldb_type_db
{
   char *file;
   char *name;
   rmldb_range_db_t* range;
   rmldb_type_t *type;
   int depth;
   struct rmldb_type_db *prev;
   struct rmldb_type_db *next;
} rmldb_type_db_t;

typedef struct rmldb_var_db
{
   char *file;
   rmldb_range_db_t *range;
   rmldb_range_db_t *clause_range; /* for val declarations this will be set to range */
   char *relation; /* for val declarations this will be set to "_VAL_DELCLARATION_" */
   char *name;
   rmldb_type_db_t* type_db;

   int depth;
   struct rmldb_var_db *prev;
   struct rmldb_var_db *next;
} rmldb_var_db_t;

typedef struct rmldb_con_db
{
   char *file;
   int constructor;
   int is_transparent;
   rmldb_range_db_t* range;
   char *name;
   rmldb_type_db_t* type_db;

   int depth;
   struct rmldb_con_db *prev;
   struct rmldb_con_db *next;
} rmldb_con_db_t;

typedef struct rmldb_relation_db
{
   char *file;
   rmldb_range_db_t* range;
   char *name;
   rmldb_type_db_t* type_db;

   int depth;
   struct rmldb_relation_db *prev;
   struct rmldb_relation_db *next;
} rmldb_relation_db_t;

/* ---- components ---- */
/* create a list from two tys */
extern rmldb_LISTty_t* rmldb_make_rmldb_LISTty(rmldb_type_t* type1, rmldb_type_t* type2);
/* appends ty in front of the list */
extern rmldb_LISTty_t* rmldb_make_cons_rmldb_LISTty(rmldb_type_t* type, rmldb_LISTty_t* list);
/* make a VARty */
extern rmldb_VARty_t* rmldb_make_rmldb_VARty(char* id);
/* make a CONSty */
extern rmldb_CONSty_t* rmldb_make_rmldb_CONSty(rmldb_LISTty_t* list, char* id);
/* make a TUPLEty */
extern rmldb_TUPLEty_t* rmldb_make_rmldb_TUPLEty(rmldb_LISTty_t* list);
/* make a RELty */
extern rmldb_RELty_t* rmldb_make_rmldb_RELty(rmldb_LISTty_t* list1, rmldb_LISTty_t* list2);

/* makes a type from a component, and casts it according to kind */
extern rmldb_type_t* rmldb_make_rmldb_type(rmldb_tyKind_t kind, void* component);

extern rmldb_var_db_t* rmldb_make_rmldb_var_db(
		char* file,
		rmldb_range_db_t* range,
		rmldb_range_db_t* clause_range,
		char* relation,
		char* name,
		rmldb_type_db_t* type_db);

extern rmldb_con_db_t* rmldb_make_rmldb_con_db(
		char* file,
		rmldb_range_db_t* range,
		char* name,
		rmldb_type_db_t* type_db,
		int constructor);

extern rmldb_type_db_t* rmldb_make_rmldb_type_db(
		char* file,
		rmldb_range_db_t* range,
		char* name);

extern rmldb_type_db_t* rmldb_make_rmldb_type_db_t(
		rmldb_type_t *type);

extern rmldb_relation_db_t* rmldb_make_rmldb_relation_db(
		char* file,
		rmldb_range_db_t* range,
		char* name,
		rmldb_type_db_t* type_db);

/* variabiles to hold the program database */
/* variables in relations and variables in val declarations */
extern rmldb_var_db_t*      rmldb_var_db_start;
extern rmldb_var_db_t*      rmldb_var_db_end;
/* types */
extern rmldb_type_db_t*     rmldb_type_db_start;
extern rmldb_type_db_t*     rmldb_type_db_end;
/* datatype constructors */
extern rmldb_con_db_t*      rmldb_con_db_start;
extern rmldb_con_db_t*      rmldb_con_db_end;
/* relations */
extern rmldb_relation_db_t* rmldb_relation_db_start;
extern rmldb_relation_db_t* rmldb_relation_db_end;

/* function to work with the program database */
extern int  rmldb_load_db(char** programdb);
extern void rmldb_type_list_push_front(
					rmldb_type_t **start_node, 
				    rmldb_type_t **end_node, 
					rmldb_type_t *node);

extern void rmldb_type_list_push_back(
					rmldb_type_t **start_node, 
				    rmldb_type_t **end_node, 
					rmldb_type_t *node);

extern void rmldb_str_list_add(
					rmldb_str_t **start_node, 
				    rmldb_str_t **end_node, 
					rmldb_str_t *node);

extern void rmldb_var_db_add(
					rmldb_var_db_t **start_node, 
				    rmldb_var_db_t **end_node, 
					rmldb_var_db_t *node);

extern void rmldb_con_db_add(
					rmldb_con_db_t **start_node, 
				    rmldb_con_db_t **end_node, 
					rmldb_con_db_t *node);

extern void rmldb_type_db_add(
					rmldb_type_db_t **start_node, 
				    rmldb_type_db_t **end_node, 
					rmldb_type_db_t *node);

extern void rmldb_relation_db_add(
					rmldb_relation_db_t **start_node, 
				    rmldb_relation_db_t **end_node, 
					rmldb_relation_db_t *node);

/* program database stream */
extern int   aarmldberror(char*);
extern int   aarmldbparse(void);
extern int   aarmldbdebug;
extern int   aarmldb_lineno;

#endif /* _RMLDB_LOAD_H_  */
/******************************************************************************
 * @author Adrian Pop [adrpo@ida.liu.se, http://www.ida.liu.se/~adrpo]
 * Copyright (c) 2002-2007, Adrian Pop [adrpo@ida.liu.se],
 * Programming Environments Laboratory (PELAB),
 * Department of Computer and Information Science (IDA), 
 * Linköpings University (LiU). 
 * All rights reserved.
 *
 * http://www.ida.liu.se/~adrpo/license/
 */
/***********************************************************
 [ debug.h ] 
  - Adrian Pop, adrpo@ida.liu.se, http://www.ida.liu.se/~adrpo
  - creation 2002-10
    + interface for rml debugging 
    + this file contains all the functions for debugging 
	+ all things in this file start with rmldb_
  - last modified 2005-12-27
************************************************************/
#ifndef _RML_DEBUG_H_
#define _RML_DEBUG_H_
/* all these functions depends on RML_DEBUG macro */
/************************************************************/

#ifdef RML_DEBUG

#include <stdio.h>
#include <string.h>

/* this file will be included in the generated rml.h */
/* adrpo some useful defines. */
#define RMLDB_SUCCESS  1
#define RMLDB_FAILURE -1

#define RMLDB_PROMPT "rml+mmc db@>"
#define RMLDB_RUN    		0
#define RMLDB_STEP   		1
#define RMLDB_STEP_OVER		2
#define RMLDB_STEP_RETURN	3
#define RMLDB_BREAKPOINT	4
#define RMLDB_TRACE_CALLS	5

#define RMLDB_VAR_IN 0
#define RMLDB_VAR_OUT 1

extern int   rmldb_execution_type;
extern int   rmldb_execution_startup_type;
extern int   rmldb_last_command; /* need to know if we should start running or get more commands from the debugger */
extern int   rmldb_depth_of_variable_print;
extern int   rmldb_max_string_variable_print;
/* location of current execution point */
extern       rmldb_current_execution_loc_t rmldb_current_execution_loc;

/* init/help/exit */
extern int  rmldb_init(void);
extern int  rmldb_end(void);
extern void rmldb_exit(int status);
extern int  rmldb_quit(char *line);

/* breakpoints */
extern int rmldb_handle_breakpoint_request(rmldb_command_type* cmd);

/* variables */
extern int rmdlb_handle_variable_request(rmldb_command_type* cmd);

/* stack */
extern int rmdlb_handle_stack_request(rmldb_command_type* cmd);
extern int rmldb_push_stack_frame(
			char* file, 
			int charStart, int charEnd, 
			int startLine, int startColumn, int endLine, int endColumn,					  
			char* function,
			char* call);
extern int rmldb_pop_stack_frame(char gototype);

#endif /* RML_DEBUG */

#endif /* _RML_DEBUG_H_  */


/* ending rml.h */
#endif /*_RML_H_*/
