[PPL-devel] Re: [Yap-users] Throwing Prolog exceptions from C code

Vitor Santos Costa vitor at biostat.wisc.edu
Tue Jun 18 04:38:03 CEST 2002


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



More information about the PPL-devel mailing list