#include "config.h"
#include <exceptions.h>
EXTERN void UnlinkIfHandler(Continuation*);
EXTERN int SaveOrHandler(void *label, Continuation *cont);
EXTERN int SaveIfHandler(void *label, Continuation *cont);
extern void ReRaiseUnlessMissing();

#define OR_(k, T) ({ Continuation cont;		\
	extern char Llabel##k[1];			\
	SaveOrHandler(Llabel##k, &cont) ? (
#define ELSE_OR_(k) ) : ({	\
	JUMP(UNDERSCORE "Llabel" #k); PRIM_HANDLER(Fail,"Llabel" #k); (
#define END_OR_ ); }); })

#define IF_THEN_ELSE(k,a,b,c) ({ Continuation cont;	\
	extern char Llabel##k[1]; struct Any TMP;		\
	if (SaveIfHandler(Llabel##k, &cont))		\
	  {a; UnlinkIfHandler(&cont); TMP =(b); 	\
	} else { JUMP("Llabel" #k);			\
	  PRIM_HANDLER(Fail,"Llabel" #k); TMP=(c); }; TMP;})

#define IF_(k,T) ({ Continuation cont;	\
	extern char Llabel##k[1]; T TMP;		\
	if (SaveIfHandler(Llabel##k, &cont)) {
#define THEN_(k) ; UnlinkIfHandler(&cont); TMP =(
#define ELSE_(k) ); 	\
	} else { JUMP("Llabel" #k); PRIM_HANDLER(Fail,"Llabel" #k); TMP=(
#define END_IF_ ); }; TMP;})

#define IF1_(k,T) ({ Continuation cont;		\
	extern char Llabel##k[1]; T TMP;		\
	if (SaveIfHandler(Llabel##k, &cont)) TMP=(
#define ELSE_IF1_(k) ), UnlinkIfHandler(&cont);		\
	else { JUMP("Llabel" #k); PRIM_HANDLER(Fail,"Llabel" #k); TMP=(
#define END_IF1_  ); }; TMP;})

#ifdef USE_EXCEPTIONS
#define IFV(k) { int _failed=0; try {
#define THENV  }  catch (Condition* c) { _failed = 1; } if (!_failed) {
#define ELSEV(k, exception) } else {
#define ENDV  }}
#elif defined(USE_LONGJMP)
#define IFV(k) { Continuation cont;  \
	if (SaveIfHandler(0, &cont), setjmp(cont.jump_buf)==0) {{
#define THENV }; UnlinkIfHandler(&cont);
#define ELSEV(k, exception) } else {
#define ENDV  }}
#else
#define IFV(k) { Continuation cont;	extern char Llabel##k[1];\
	if (SaveIfHandler(Llabel##k, &cont)) {{
#define THENV }; UnlinkIfHandler(&cont);
#define ELSEV(k, exception) \
 	} else { JUMP("Llabel" #k); PRIM_HANDLER(exception, "Llabel" #k); {
#define ENDV  }}}
#endif

#define CATCH_MISSING(k) IFV(k)
#define HANDLE_MISSING(k) THENV ELSEV(k,Fail) ReRaiseUnlessMissing();
#define END_MISSING ENDV

#define IF_ELSE(k,a,b) ({ Continuation cont;		\
	extern char Llabel##k[1]; Object TMP;		\
	if (SaveIfHandler(Llabel##k, &cont))		\
	  TMP=(a), UnlinkIfHandler(&cont);		\
	else {	JUMP("Llabel" #k);			\
		PRIM_HANDLER)Fail, "Llabel" #k);	\
	        TMP=(b); }; TMP;})
