
Hi Roberto,
Hi Vitor,
I have tried right now and still get a failure, but with a very different stack trace. Thanks a lot for your prompt responses
Sorry for the delay.
There were indeed problems when using YapRunGoal, as it was only tested from the top-level. YapThrow and YapCallProlog seemed to be working fine.
This is a program I used for testing (I updated some changes to the CVS version). Do you mind checking if it works for you? If it doesn't, please tell me. If it does, then I think I'll need some more info to track your bug.
Cheers,
Vitor
PS: Yes, I know, the documentation is very bad :-(.
/************************************************************************* * * * YAP Prolog * * * * Yap Prolog was developed at NCCUP - Universidade do Porto * * * * Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 * * * ************************************************************************** * * * File: x.c * * Last rev: * * mods: * * comments: example of exception handling in C-interface * * * *************************************************************************/
#include "config.h" #include "c_interface.h" #include <math.h> #if defined(__MINGW32__) || _MSC_VER #include <windows.h> #endif
void PROTO(init_x, (void));
/* Throw a simple exception
?- x(a).
*/ static int p_x(void) { Term tf = YapMkAtomTerm(YapLookupAtom("hello")); YapThrow(tf); return(TRUE); }
/* Throw a complex exception
?- x2(a).
*/ static int p_x2(void) { Term tf, t[3]; Functor f = YapMkFunctor(YapLookupAtom("f"),3);
t[0] = YapMkAtomTerm(YapLookupAtom("hello")); t[1] = YapMkVarTerm(); t[2] = ARG1; tf = YapMkApplTerm(f,3,t); YapThrow(tf); return(TRUE); }
/* Run a throw goal: exception is not thrown outside caller
?- ux(a).
*/ static int p_ux(void) { Term tf, t[3]; Functor f1 = YapMkFunctor(YapLookupAtom("throw"),1); Functor f2 = YapMkFunctor(YapLookupAtom("f"),3);
t[0] = YapMkAtomTerm(YapLookupAtom("hello")); t[1] = YapMkVarTerm(); t[2] = ARG1; tf = YapMkApplTerm(f2,3,t); t[0] = tf; tf = YapMkApplTerm(f1,1,t); return(YapCallProlog(tf)); }
/* Run goal as argument
?- g(X=2). ; ?- g(fail). ?- g(throw(a)).
*/ static int p_g(void) { return(YapCallProlog(ARG1)); }
/* Run goal as argument and check for exceptions. Do a throw if so. ?- g2(X=2). ; ?- g2(fail). ?- g2(throw(a)).
*/ static int p_g2(void) { Term ex; int out = YapCallProlog(ARG1); if (YapGoalHasException(&ex)) { YapThrow(ex); return(FALSE); } return(out); }
/* Use YapRunGoal, as it keeps the choice-point stack. Notice that we need to do prunegoal before we exit */ static int p_h(void) { int out = YapRunGoal(ARG1); if (out) { YapPruneGoal(); } return(out); }
/* same and also check for exceptions.
?- h2(X=2). ; ?- h2(fail). ?- h2(throw(a)).
*/ static int p_h2(void) { Term ex; int out = YapRunGoal(ARG1); if (out) { YapPruneGoal(); } if (YapGoalHasException(&ex)) { YapThrow(ex); return(FALSE); } return(out); }
void init_x(void) { UserCPredicate("x", p_x, 0); UserCPredicate("x", p_x2, 1); UserCPredicate("ux", p_ux, 1); UserCPredicate("g", p_g, 1); UserCPredicate("g2", p_g2, 1); UserCPredicate("h", p_h, 1); UserCPredicate("h2", p_h2, 1); }
#ifdef _WIN32
int WINAPI PROTO(win_x, (HANDLE, DWORD, LPVOID));
int WINAPI win_x(HANDLE hinst, DWORD reason, LPVOID reserved) { switch (reason) { case DLL_PROCESS_ATTACH: break; case DLL_PROCESS_DETACH: break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; } return 1; } #endif