improve error handling

This commit is contained in:
Vitor Santos Costa 2016-09-21 14:41:23 -05:00
parent 76b9946358
commit db2aa5b5f2
6 changed files with 344 additions and 235 deletions

View File

@ -1,5 +1,4 @@
#ifndef _YAPDB_H #ifndef _YAPDB_H
#define _YAPDB_H #define _YAPDB_H
@ -35,13 +34,14 @@ class YAPModule;
*/ */
class YAPModule : protected YAPAtomTerm { class YAPModule : protected YAPAtomTerm {
friend class YAPPredicate; friend class YAPPredicate;
YAPModule( Term t ): YAPAtomTerm( t ) {}; YAPModule(Term t) : YAPAtomTerm(t){};
Term t() { return gt(); } Term t() { return gt(); }
Term curModule() {CACHE_REGS return Yap_CurrentModule(); } Term curModule() { CACHE_REGS return Yap_CurrentModule(); }
public: public:
~YAPModule( ) {}; ~YAPModule(){};
YAPModule( ): YAPAtomTerm( curModule() ) {}; YAPModule() : YAPAtomTerm(curModule()){};
YAPModule( YAPAtom t ): YAPAtomTerm( t ) {}; YAPModule(YAPAtom t) : YAPAtomTerm(t){};
}; };
/** /**
@ -49,144 +49,142 @@ public:
* A YAPModuleProp controls access to a module property. * A YAPModuleProp controls access to a module property.
* *
*/ */
class YAPModuleProp: public YAPProp { class YAPModuleProp : public YAPProp {
friend class YAPPredicate; friend class YAPPredicate;
ModEntry *m; ModEntry *m;
YAPModuleProp(ModEntry *mod) {m = mod;}; YAPModuleProp(ModEntry *mod) { m = mod; };
YAPModuleProp(Term tmod) { m = Yap_GetModuleEntry(tmod); }; YAPModuleProp(Term tmod) { m = Yap_GetModuleEntry(tmod); };
public: public:
YAPModuleProp() { CACHE_REGS m = Yap_GetModuleEntry(Yap_CurrentModule()); }; YAPModuleProp() { CACHE_REGS m = Yap_GetModuleEntry(Yap_CurrentModule()); };
YAPModuleProp(YAPModule tmod) ; YAPModuleProp(YAPModule tmod);
virtual YAPModule module() { return YAPModule(m->AtomOfME); }; virtual YAPModule module() { return YAPModule(m->AtomOfME); };
}; };
/** /**
* @brief YAPFunctor represents Prolog functors Name/Arity * @brief YAPFunctor represents Prolog functors Name/Arity
*/ */
class YAPFunctor: public YAPProp { class YAPFunctor : public YAPProp {
friend class YAPApplTerm; friend class YAPApplTerm;
friend class YAPPredicate; friend class YAPTerm;
Functor f; friend class YAPPredicate;
/// Constructor: receives Prolog functor and casts it to YAPFunctor friend class YAPQuery;
/// Functor f;
/// Notice that this is designed for internal use only. /// Constructor: receives Prolog functor and casts it to YAPFunctor
inline YAPFunctor( Functor ff) { f = ff; } ///
public: /// Notice that this is designed for internal use only.
/// Constructor: receives name as an atom, plus arity inline YAPFunctor(Functor ff) { f = ff; }
///
/// This is the default method, and the most popular
YAPFunctor( YAPAtom at, uintptr_t arity) { f = Yap_MkFunctor( at.a, arity ); }
/// Constructor: receives name as a string plus arity public:
/// /// Constructor: receives name as an atom, plus arity
///
/// This is the default method, and the most popular
YAPFunctor(YAPAtom at, uintptr_t arity) { f = Yap_MkFunctor(at.a, arity); }
/// Constructor: receives name as a string plus arity
///
/// Notice that this is designed for ISO-LATIN-1 right now /// Notice that this is designed for ISO-LATIN-1 right now
/// Note: Python confuses the 3 constructors, /// Note: Python confuses the 3 constructors,
/// use YAPFunctorFromString /// use YAPFunctorFromString
inline YAPFunctor( const char * s, uintptr_t arity, bool isutf8=true) inline YAPFunctor(const char *s, uintptr_t arity, bool isutf8 = true) {
{ f = Yap_MkFunctor( f = Yap_MkFunctor(Yap_LookupAtom(s), arity);
Yap_LookupAtom( s ), arity ); } }
/// Constructor: receives name as a wide string plus arity /// Constructor: receives name as a wide string plus arity
/// ///
/// Notice that this is designed for UNICODE right now /// Notice that this is designed for UNICODE right now
/// ///
/// Note: Python confuses the 3 constructors, /// Note: Python confuses the 3 constructors,
/// use YAPFunctorFromWideString /// use YAPFunctorFromWideString
inline YAPFunctor( const wchar_t * s, uintptr_t arity) { inline YAPFunctor(const wchar_t *s, uintptr_t arity) {
f = Yap_MkFunctor( f = Yap_MkFunctor(Yap_LookupWideAtom(s), arity);
Yap_LookupWideAtom( s ), arity ) ; } }
~YAPFunctor( ) { }; ~YAPFunctor(){};
/// Getter: extract name of functor as an atom /// Getter: extract name of functor as an atom
/// ///
/// this is for external usage. /// this is for external usage.
YAPAtom name(void) { YAPAtom name(void) { return YAPAtom(NameOfFunctor(f)); }
return YAPAtom( NameOfFunctor( f ) );
}
/// Getter: extract arity of functor as an unsigned integer /// Getter: extract arity of functor as an unsigned integer
/// ///
/// this is for external usage. /// this is for external usage.
uintptr_t arity(void) { uintptr_t arity(void) { return ArityOfFunctor(f); }
return ArityOfFunctor( f ); };
}
};
/** /**
* @brief Predicates * @brief Predicates
* *
* This class interfaces with PredEntry in Yatom. * This class interfaces with PredEntry in Yatom.
*/ */
class YAPPredicate: public YAPModuleProp { class YAPPredicate : public YAPModuleProp {
friend class YAPQuery; friend class YAPQuery;
friend class YAPEngine;
protected: protected:
PredEntry *ap; PredEntry *ap;
/// auxiliary routine to find a predicate in the current module. /// auxiliary routine to find a predicate in the current module.
PredEntry *getPred( Term &t, Term* &outp ) ; PredEntry *getPred(Term &t, Term *&outp);
PredEntry *asPred() { return ap; };
/// String constructor for predicates /// String constructor for predicates
/// ///
/// It also communicates the array of arguments t[] /// It also communicates the array of arguments t[]
/// and the array of variables /// and the array of variables
/// back to yapquery /// back to yapquery
YAPPredicate(const char *s0, Term &out, Term &names ) { YAPPredicate(const char *s0, Term &out, Term &names) {
CACHE_REGS CACHE_REGS
BACKUP_MACHINE_REGS(); BACKUP_MACHINE_REGS();
Term *outp; Term *outp;
out = Yap_StringToTerm(s0, strlen(s0)+1, &LOCAL_encoding, 1200, &names ) ; out = Yap_StringToTerm(s0, strlen(s0) + 1, &LOCAL_encoding, 1200, &names);
//extern char *s0; // extern char *s0;
//fprintf(stderr,"ap=%p arity=%d text=%s", ap, ap->ArityOfPE, s); // fprintf(stderr,"ap=%p arity=%d text=%s", ap, ap->ArityOfPE, s);
// Yap_DebugPlWrite(out); // Yap_DebugPlWrite(out);
// delete [] ns; // delete [] ns;
if (out == 0L) if (out == 0L)
throw YAPError(SYNTAX_ERROR); throw YAPError();
ap = getPred( out, outp); ap = getPred(out, outp);
RECOVER_MACHINE_REGS(); RECOVER_MACHINE_REGS();
} }
/// Term constructor for predicates /// Term constructor for predicates
/// ///
/// It is just a call to getPred /// It is just a call to getPred
inline YAPPredicate(Term t) { inline YAPPredicate(Term t) {
CELL * v = NULL; CELL *v = NULL;
ap = getPred( t , v ); ap = getPred(t, v);
} }
/// Cast constructor for predicates, /// Cast constructor for predicates,
/// if we have the implementation data. /// if we have the implementation data.
/// ///
inline YAPPredicate(PredEntry *pe) { inline YAPPredicate(PredEntry *pe) { ap = pe; }
ap = pe;
}
public: public:
~YAPPredicate() {}; ~YAPPredicate(){};
/// Functor constructor for predicates /// Functor constructor for predicates
/// ///
/// Asssumes that we use the current module. /// Asssumes that we use the current module.
YAPPredicate(YAPFunctor f) { YAPPredicate(YAPFunctor f) {
CACHE_REGS CACHE_REGS
ap = RepPredProp(PredPropByFunc(f.f,Yap_CurrentModule())); ap = RepPredProp(PredPropByFunc(f.f, Yap_CurrentModule()));
}; };
/// Functor constructor for predicates, is given a specific module. /// Functor constructor for predicates, is given a specific module.
/// ///
inline YAPPredicate(YAPFunctor f, YAPTerm mod) { inline YAPPredicate(YAPFunctor f, YAPTerm mod) {
ap = RepPredProp(PredPropByFunc(f.f,mod.t)); ap = RepPredProp(PredPropByFunc(f.f, mod.t));
} }
/// Name/arity constructor for predicates. /// Name/arity constructor for predicates.
/// ///
inline YAPPredicate(YAPAtom at, YAPTerm mod) { inline YAPPredicate(YAPAtom at, YAPTerm mod) {
ap = RepPredProp(PredPropByAtom(at.a,mod.t)); ap = RepPredProp(PredPropByAtom(at.a, mod.t));
} }
/// Name/0 constructor for predicates. /// Name/0 constructor for predicates.
/// ///
YAPPredicate(YAPAtom at); YAPPredicate(YAPAtom at);
@ -196,9 +194,9 @@ public:
inline YAPPredicate(YAPAtom at, uintptr_t arity, YAPModule mod) { inline YAPPredicate(YAPAtom at, uintptr_t arity, YAPModule mod) {
if (arity) { if (arity) {
Functor f = Yap_MkFunctor(at.a, arity); Functor f = Yap_MkFunctor(at.a, arity);
ap = RepPredProp(PredPropByFunc(f,mod.t())); ap = RepPredProp(PredPropByFunc(f, mod.t()));
} else { } else {
ap = RepPredProp(PredPropByAtom(at.a,mod.t())); ap = RepPredProp(PredPropByAtom(at.a, mod.t()));
} }
} }
@ -206,24 +204,24 @@ public:
/// ///
YAPPredicate(YAPAtom at, uintptr_t arity); YAPPredicate(YAPAtom at, uintptr_t arity);
/// module of a predicate /// module of a predicate
/// ///
/// notice that modules are currently treated as atoms, this should change. /// notice that modules are currently treated as atoms, this should change.
YAPModule module() { YAPModule module() {
if (ap->ModuleOfPred == PROLOG_MODULE) if (ap->ModuleOfPred == PROLOG_MODULE)
return YAPModule(AtomProlog); return YAPModule(AtomProlog);
else else
return YAPModule(AtomOfTerm(ap->ModuleOfPred)); return YAPModule(AtomOfTerm(ap->ModuleOfPred));
} }
/// name of predicate /// name of predicate
/// ///
/// notice that we return the atom, not a string. /// notice that we return the atom, not a string.
YAPAtom name() { if (ap->ArityOfPE) YAPAtom name() {
return YAPAtom((Atom)ap->FunctorOfPred); if (ap->ArityOfPE)
return YAPAtom((Atom)ap->FunctorOfPred);
else else
return YAPAtom(NameOfFunctor(ap->FunctorOfPred)); return YAPAtom(NameOfFunctor(ap->FunctorOfPred));
} }
/// arity of predicate /// arity of predicate
@ -237,28 +235,20 @@ public:
* *
* This class interfaces with Predicates Implemented in Prolog. * This class interfaces with Predicates Implemented in Prolog.
*/ */
class YAPPrologPredicate: public YAPPredicate { class YAPPrologPredicate : public YAPPredicate {
public: public:
YAPPrologPredicate(YAPAtom name, YAPPrologPredicate(YAPAtom name, uintptr_t arity,
uintptr_t arity, YAPModule module = YAPModule(), bool tabled = false,
YAPModule module = YAPModule(), bool logical_updates = false, bool local = false,
bool tabled = false, bool sourced = true, bool discontiguous = false,
bool logical_updates = false, bool multiFile = false, bool hidden = false,
bool local = false, bool untraceable = false, bool unspyable = false,
bool sourced = true, bool meta = false, bool sync = false,
bool discontiguous = false, bool quasi_quotable = false, size_t mega_clause = 0);
bool multiFile = false, void *assertClause(YAPTerm clause, bool last = true,
bool hidden = false, YAPTerm source = YAPTerm(TermNil));
bool untraceable = false, void *retractClause(YAPTerm skeleton, bool all = false);
bool unspyable = false, void *clause(YAPTerm skeleton, YAPTerm &body);
bool meta = false,
bool sync = false,
bool quasi_quotable = false,
size_t mega_clause = 0
);
void *assertClause( YAPTerm clause, bool last=true, YAPTerm source= YAPTerm(TermNil));
void *retractClause( YAPTerm skeleton, bool all=false);
void *clause( YAPTerm skeleton, YAPTerm &body );
}; };
/** /**
@ -266,52 +256,35 @@ public:
* *
* This class interfaces with Predicates Implemented in Prolog. * This class interfaces with Predicates Implemented in Prolog.
*/ */
class YAPFLIP: public YAPPredicate { class YAPFLIP : public YAPPredicate {
public: public:
YAPFLIP(CPredicate call, YAPFLIP(CPredicate call, YAPAtom name, uintptr_t arity,
YAPAtom name, YAPModule module = YAPModule(), CPredicate retry = 0,
uintptr_t arity, CPredicate cut = 0, size_t extra = 0, bool test = false)
YAPModule module = YAPModule(), : YAPPredicate(name, arity, module) {
CPredicate retry = 0,
CPredicate cut = 0,
size_t extra = 0,
bool test = false
) : YAPPredicate( name, arity, module) {
if (retry) { if (retry) {
Yap_InitCPredBackCut(name.getName(), arity, extra, call, retry, cut, UserCPredFlag); Yap_InitCPredBackCut(name.getName(), arity, extra, call, retry, cut,
UserCPredFlag);
} else { } else {
if (test) { if (test) {
YAP_UserCPredicate (name.getName(), YAP_UserCPredicate(name.getName(), call, arity);
call, arity);
} else { } else {
YAP_UserCPredicate (name.getName(), YAP_UserCPredicate(name.getName(), call, arity);
call, arity);
} }
} }
}; };
YAPFLIP(const char *name, YAPFLIP(const char *name, uintptr_t arity, YAPModule module = YAPModule(),
uintptr_t arity, bool backtrackable = false)
YAPModule module = YAPModule(), : YAPPredicate(YAPAtom(name), arity, module) {
bool backtrackable = false
) : YAPPredicate( YAPAtom(name), arity, module) {
if (backtrackable) { if (backtrackable) {
Yap_InitCPredBackCut(name, arity, 0, 0, 0, 0, UserCPredFlag); Yap_InitCPredBackCut(name, arity, 0, 0, 0, 0, UserCPredFlag);
} else { } else {
YAP_UserCPredicate (name, YAP_UserCPredicate(name, 0, arity);
0, arity); }
}
}; };
bool addCall(CPredicate call) { bool addCall(CPredicate call) { return Yap_AddCallToFli(ap, call); }
return Yap_AddCallToFli( ap, call ); bool addRetry(CPredicate call) { return Yap_AddRetryToFli(ap, call); }
} bool addCut(CPredicate call) { return Yap_AddCutToFli(ap, call); }
bool addRetry(CPredicate call) {
return Yap_AddRetryToFli( ap, call );
}
bool addCut(CPredicate call) {
return Yap_AddCutToFli( ap, call );
}
}; };
#endif #endif

View File

@ -161,6 +161,17 @@ YAPApplTerm::YAPApplTerm(YAPFunctor f, YAPTerm ts[]) : YAPTerm() {
RECOVER_H(); RECOVER_H();
} }
YAPApplTerm::YAPApplTerm(const char *f, std::vector<YAPTerm> ts) : YAPTerm() {
BACKUP_H();
arity_t arity = ts.size();
std::vector<Term> tt(arity);
for (arity_t i = 0; i < arity; i++)
tt[i] = ts[i].term();
Functor ff = Yap_MkFunctor(Yap_LookupAtom(f), arity);
t = Yap_MkApplTerm(ff, arity, &tt[0]);
RECOVER_H();
}
YAPApplTerm::YAPApplTerm(YAPFunctor f) : YAPTerm() { YAPApplTerm::YAPApplTerm(YAPFunctor f) : YAPTerm() {
BACKUP_H(); BACKUP_H();
arity_t arity = ArityOfFunctor(f.f); arity_t arity = ArityOfFunctor(f.f);
@ -170,8 +181,6 @@ YAPApplTerm::YAPApplTerm(YAPFunctor f) : YAPTerm() {
YAPFunctor YAPApplTerm::getFunctor() { return YAPFunctor(FunctorOfTerm(gt())); } YAPFunctor YAPApplTerm::getFunctor() { return YAPFunctor(FunctorOfTerm(gt())); }
static YAPTerm tmp;
YAPTerm &YAPTerm::operator[](arity_t i) { YAPTerm &YAPTerm::operator[](arity_t i) {
BACKUP_MACHINE_REGS(); BACKUP_MACHINE_REGS();
Term t0 = gt(); Term t0 = gt();
@ -359,7 +368,7 @@ const char *YAPTerm::text() {
if (!(os = Yap_TermToString(Yap_GetFromSlot(t), &length, enc, if (!(os = Yap_TermToString(Yap_GetFromSlot(t), &length, enc,
Handle_vars_f))) { Handle_vars_f))) {
RECOVER_MACHINE_REGS(); RECOVER_MACHINE_REGS();
return nullptr; return 0;
} }
RECOVER_MACHINE_REGS(); RECOVER_MACHINE_REGS();
return os; return os;
@ -392,8 +401,36 @@ YAPTerm YAPListTerm::car() {
Term to = gt(); Term to = gt();
if (IsPairTerm(to)) if (IsPairTerm(to))
return YAPTerm(HeadOfTerm(to)); return YAPTerm(HeadOfTerm(to));
else else {
throw YAPError(TYPE_ERROR_LIST); Yap_Error(TYPE_ERROR_LIST, to, "");
throw YAPError();
}
}
YAPTerm::YAPTerm(YAPFunctor f, YAPTerm ts[]) {
CACHE_REGS
BACKUP_H();
Functor fun = f.f;
arity_t arity = ArityOfFunctor(fun);
while (HR + arity > ASP - 1024) {
RECOVER_H();
if (!Yap_dogc(0, NULL PASS_REGS)) {
t = TermNil;
}
BACKUP_H();
}
if (fun == FunctorDot) {
t = AbsPair(HR);
HR[0] = ts[0].term();
HR[1] = ts[1].term();
} else {
t = AbsAppl(HR);
*HR++ = (CELL)fun;
for (arity_t i = 0; i < arity; i++) {
HR[i] = ts[i].term();
}
RECOVER_H();
}
} }
YAPListTerm::YAPListTerm(YAPTerm ts[], arity_t n) { YAPListTerm::YAPListTerm(YAPTerm ts[], arity_t n) {
@ -445,8 +482,21 @@ const char *YAPAtom::getName(void) {
} }
} }
void YAPQuery::initOpenQ() { void YAPQuery::openQuery() {
CACHE_REGS CACHE_REGS
arity_t arity = ap->ArityOfPE;
if (arity) {
Term *ts;
Term t = goal.term();
if (IsPairTerm(t)) {
ts = RepPair(t);
} else {
ts = RepAppl(t) + 1;
}
for (arity_t i = 0; i < arity; i++) {
XREGS[i + 1] = ts[i];
}
}
// oq = LOCAL_execution; // oq = LOCAL_execution;
// LOCAL_execution = this; // LOCAL_execution = this;
q_open = true; q_open = true;
@ -459,69 +509,73 @@ void YAPQuery::initOpenQ() {
q_handles = Yap_StartSlots(); q_handles = Yap_StartSlots();
} }
int YAPError::get() { return errNo; } bool YAPEngine::call(YAPPredicate ap, YAPTerm ts[]) {
const char *YAPError::text() { return "YAP Error"; }
void YAPQuery::initQuery(Term t) {
CACHE_REGS CACHE_REGS
BACKUP_MACHINE_REGS(); BACKUP_MACHINE_REGS();
arity_t arity = ap->ArityOfPE; arity_t arity = ap.getArity();
goal = YAPTerm(t); bool result;
if (arity) { YAP_dogoalinfo q;
q_g = Yap_InitSlots(arity, RepAppl(t) + 1); Term terr;
} else { jmp_buf q_env;
q_g = 0; std::vector<Term> vt(arity);
} for (arity_t i = 0; i < arity; i++)
q_pe = ap; vt[i] = ts[i].term();
initOpenQ(); q.CurSlot = Yap_StartSlots();
RECOVER_MACHINE_REGS(); q.p = P;
} q.cp = CP;
// make sure this is safe
void YAPQuery::initQuery(YAPAtom at) { if (setjmp(q_env)) {
CACHE_REGS if ((terr = Yap_PeekException())) {
BACKUP_MACHINE_REGS(); YAP_LeaveGoal(false, &q);
PredEntry *ap = RepPredProp(PredPropByAtom(at.a, Yap_CurrentModule())); Yap_CloseHandles(q.CurSlot);
goal = YAPAtomTerm(at); throw YAPError();
q_g = 0;
q_pe = ap;
initOpenQ();
RECOVER_MACHINE_REGS();
}
void YAPQuery::initQuery(YAPTerm ts[], arity_t arity) {
CACHE_REGS
BACKUP_MACHINE_REGS();
if (arity) {
q_g = Yap_NewSlots(arity);
for (arity_t i = 0; i < arity; i++) {
Yap_PutInSlot(q_g + i, ts[i].term());
} }
Term t = Yap_MkApplTerm(ap->FunctorOfPred, ap->ArityOfPE, return false;
Yap_AddressFromSlot(q_g)); }
goal = YAPTerm(t); // don't forget, on success these guys may create slots
} else { __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "exec ");
q_g = 0; result = (bool)YAP_EnterGoal(ap.asPred(), &vt[0], &q);
goal = YAPTerm(MkAtomTerm((Atom)ap->FunctorOfPred)); if ((terr = Yap_GetException())) {
YAP_LeaveGoal(false, &q);
throw YAPError();
}
__android_log_print(ANDROID_LOG_INFO, "YAPDroid", "out %d", result);
if (!result) {
YAP_LeaveGoal(false, &q);
} else {
YAP_LeaveGoal(FALSE, &q);
} }
initOpenQ();
RECOVER_MACHINE_REGS(); RECOVER_MACHINE_REGS();
return result;
} }
YAPQuery::YAPQuery(YAPFunctor f, YAPTerm mod, YAPTerm ts[]) YAPQuery::YAPQuery(YAPFunctor f, YAPTerm mod, YAPTerm ts[])
: YAPPredicate(f, mod) { : YAPPredicate(f, mod) {
/* ignore flags for now */ /* ignore flags for now */
initQuery(ts, f.arity()); BACKUP_MACHINE_REGS();
goal = YAPTerm(f, ts);
vnames = YAPListTerm();
openQuery();
RECOVER_MACHINE_REGS();
} }
YAPQuery::YAPQuery(YAPFunctor f, YAPTerm ts[]) : YAPPredicate(f) { YAPQuery::YAPQuery(YAPFunctor f, YAPTerm ts[]) : YAPPredicate(f) {
/* ignore flags for now */ /* ignore flags for now */
initQuery(ts, f.arity()); BACKUP_MACHINE_REGS();
goal = YAPTerm(f, ts);
vnames = YAPListTerm();
openQuery();
RECOVER_MACHINE_REGS();
} }
YAPQuery::YAPQuery(YAPPredicate p, YAPTerm ts[]) : YAPPredicate(p.ap) { YAPQuery::YAPQuery(YAPPredicate p, YAPTerm ts[]) : YAPPredicate(p.ap) {
initQuery(ts, p.ap->ArityOfPE); BACKUP_MACHINE_REGS();
goal = YAPTerm(YAPFunctor(ap->FunctorOfPred), ts);
vnames = YAPListTerm();
openQuery();
RECOVER_MACHINE_REGS();
} }
YAPListTerm YAPQuery::namedVars() { YAPListTerm YAPQuery::namedVars() {
@ -541,36 +595,44 @@ YAPListTerm YAPQuery::namedVarsCopy() {
bool YAPQuery::next() { bool YAPQuery::next() {
CACHE_REGS CACHE_REGS
bool result; bool result;
Term terr;
BACKUP_MACHINE_REGS(); BACKUP_MACHINE_REGS();
if (!q_open) if (!q_open)
return false; return false;
if (setjmp(q_env)) { if (setjmp(q_env)) {
if ((terr = Yap_GetException())) {
YAP_LeaveGoal(false, &q_h);
Yap_CloseHandles(q_handles);
throw YAPError();
}
return false; return false;
} }
// don't forget, on success these guys may create slots // don't forget, on success these guys may create slots
__android_log_print(ANDROID_LOG_INFO, "YAPDroid", "exec "); __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "exec ");
if (q_state == 0) { if (q_state == 0) {
result = (bool)YAP_EnterGoal((YAP_PredEntryPtr)ap, q_g, &q_h); result = (bool)YAP_EnterGoal(ap, nullptr, &q_h);
} else { } else {
LOCAL_AllowRestart = q_open; LOCAL_AllowRestart = q_open;
result = (bool)YAP_RetryGoal(&q_h); result = (bool)YAP_RetryGoal(&q_h);
} }
if (result) { if (result) {
__android_log_print(ANDROID_LOG_INFO, "YAPDroid", "vnames %d %s %d", __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "vnames %d %s %d",
q_state, vnames.text(), LOCAL_CurSlot); q_state, vnames.text(), LOCAL_CurSlot);
} else { } else {
__android_log_print(ANDROID_LOG_INFO, "YAPDroid", "fail"); __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "fail");
} }
q_state = 1; q_state = 1;
if (Yap_GetException()) { if ((terr = Yap_GetException())) {
return false; YAP_LeaveGoal(false, &q_h);
Yap_CloseHandles(q_handles);
throw YAPError();
} }
__android_log_print(ANDROID_LOG_INFO, "YAPDroid", "out %d", result); __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "out %d", result);
if (!result) { if (!result) {
YAP_LeaveGoal(FALSE, &q_h); YAP_LeaveGoal(false, &q_h);
Yap_CloseHandles(q_handles); Yap_CloseHandles(q_handles);
q_open = false; q_open = false;
} else { } else {
@ -611,7 +673,7 @@ void YAPQuery::close() {
RECOVER_MACHINE_REGS(); RECOVER_MACHINE_REGS();
Yap_ResetException(worker_id); Yap_ResetException(worker_id);
/* need to implement backtracking here */ /* need to implement backtracking here */
if (q_open != 1 || q_state == 0) { if (q_open != true || q_state == 0) {
RECOVER_MACHINE_REGS(); RECOVER_MACHINE_REGS();
return; return;
} }
@ -674,7 +736,7 @@ void Yap_displayWithJava(int c) {
void YAPEngine::doInit(YAP_file_type_t BootMode) { void YAPEngine::doInit(YAP_file_type_t BootMode) {
if ((BootMode = YAP_Init(&init_args)) == YAP_FOUND_BOOT_ERROR) { if ((BootMode = YAP_Init(&init_args)) == YAP_FOUND_BOOT_ERROR) {
throw(YAPError(SYSTEM_ERROR_INTERNAL)); throw YAPError();
} }
/* Begin preprocessor code */ /* Begin preprocessor code */
/* live */ /* live */
@ -767,7 +829,11 @@ PredEntry *YAPPredicate::getPred(Term &t, Term *&outp) {
Term m = Yap_CurrentModule(); Term m = Yap_CurrentModule();
t = Yap_StripModule(t, &m); t = Yap_StripModule(t, &m);
if (IsVarTerm(t) || IsNumTerm(t)) { if (IsVarTerm(t) || IsNumTerm(t)) {
throw YAPError(TYPE_ERROR_NUMBER); if (IsVarTerm(t))
Yap_Error(INSTANTIATION_ERROR, t, 0);
else if (IsNumTerm(t))
Yap_Error(TYPE_ERROR_CALLABLE, t, 0);
throw YAPError();
} }
if (IsAtomTerm(t)) { if (IsAtomTerm(t)) {
ap = RepPredProp(PredPropByAtom(AtomOfTerm(t), m)); ap = RepPredProp(PredPropByAtom(AtomOfTerm(t), m));
@ -782,7 +848,9 @@ PredEntry *YAPPredicate::getPred(Term &t, Term *&outp) {
} }
Functor f = FunctorOfTerm(t); Functor f = FunctorOfTerm(t);
if (IsExtensionFunctor(f)) { if (IsExtensionFunctor(f)) {
throw YAPError(TYPE_ERROR_NUMBER); Yap_Error(TYPE_ERROR_CALLABLE, t, 0);
;
throw YAPError();
} else { } else {
ap = RepPredProp(PredPropByFunc(f, m)); ap = RepPredProp(PredPropByFunc(f, m));
outp = RepAppl(t) + 1; outp = RepAppl(t) + 1;
@ -877,3 +945,40 @@ void *YAPPrologPredicate::retractClause(YAPTerm skeleton, bool all) {
return 0; return 0;
} }
void *YAPPrologPredicate::clause(YAPTerm skeleton, YAPTerm &body) { return 0; } void *YAPPrologPredicate::clause(YAPTerm skeleton, YAPTerm &body) { return 0; }
const char *YAPError::text() {
std::string s = "";
if (LOCAL_ActiveError.prologPredLine) {
s += LOCAL_ActiveError.prologPredFile->StrOfAE;
s += ":";
s += LOCAL_ActiveError.prologPredLine;
s += ":0 error ";
s += Yap_errorClassName(getErrorClass());
s += ".";
s += Yap_errorName(getID());
s += " in ";
s += LOCAL_ActiveError.prologPredModule;
s += ":";
s += (LOCAL_ActiveError.prologPredName)->StrOfAE;
s += "/";
s += LOCAL_ActiveError.prologPredArity;
s += "\n";
}
if (LOCAL_ActiveError.errorFunction) {
s += LOCAL_ActiveError.errorFile;
s += ":";
s += LOCAL_ActiveError.errorLine;
s += ":0 C-code for error.";
s += "\n";
}
if (LOCAL_ActiveError.errorTerm) {
Term t = Yap_PopTermFromDB(LOCAL_ActiveError.errorTerm);
if (t) {
s += "error term is: ";
s += YAPTerm(t).text();
s += "\n";
}
}
printf("%s\n", s.c_str());
return s.c_str();
}

View File

@ -3,7 +3,7 @@
#define YAP_CPP_INTERFACE 1 #define YAP_CPP_INTERFACE 1
#include <gmpxx.h> #include <gmpxx.h>
#include <vector>
//! @{ //! @{
/** /**
@ -67,14 +67,13 @@ extern "C" {
#include "iopreds.h" #include "iopreds.h"
#ifdef SWIGPYTHON #ifdef SWIGPYTHON
extern PyObject *term_to_python(yhandle_t t, bool eval); extern PyObject *term_to_python(yhandle_t t, bool eval);
extern PyObject *deref_term_to_python(yhandle_t t); extern PyObject *deref_term_to_python(yhandle_t t);
X_API bool init_python(void); X_API bool init_python(void);
extern PyObject *py_Main; extern PyObject *py_Main;
extern inline PyObject *AtomToPy( const char *s) extern inline PyObject *AtomToPy(const char *s) {
{
if (strcmp(s, "true") == 0) if (strcmp(s, "true") == 0)
return Py_True; return Py_True;
if (strcmp(s, "false") == 0) if (strcmp(s, "false") == 0)
@ -85,7 +84,7 @@ extern inline PyObject *AtomToPy( const char *s)
return PyList_New(0); return PyList_New(0);
else if (strcmp(s, "{}") == 0) else if (strcmp(s, "{}") == 0)
return PyDict_New(); return PyDict_New();
/* return __main__,s */ /* return __main__,s */
else if (PyObject_HasAttrString(py_Main, s)) { else if (PyObject_HasAttrString(py_Main, s)) {
return PyObject_GetAttrString(py_Main, s); return PyObject_GetAttrString(py_Main, s);
} }
@ -97,17 +96,18 @@ extern inline PyObject *AtomToPy( const char *s)
X_API void YAP_UserCPredicate(const char *, YAP_UserCPred, YAP_Arity arity); X_API void YAP_UserCPredicate(const char *, YAP_UserCPred, YAP_Arity arity);
/* void UserCPredicateWithArgs(const char *name, int *fn(), unsigned int arity) */ /* void UserCPredicateWithArgs(const char *name, int *fn(), unsigned int arity)
X_API void YAP_UserCPredicateWithArgs(const char *, YAP_UserCPred, YAP_Arity, YAP_Term); */
X_API void YAP_UserCPredicateWithArgs(const char *, YAP_UserCPred, YAP_Arity,
YAP_Term);
/* void UserBackCPredicate(const char *name, int *init(), int *cont(), int /* void UserBackCPredicate(const char *name, int *init(), int *cont(), int
arity, int extra) */ arity, int extra) */
X_API void YAP_UserBackCPredicate(const char *, YAP_UserCPred, YAP_UserCPred, YAP_Arity, YAP_Arity); X_API void YAP_UserBackCPredicate(const char *, YAP_UserCPred, YAP_UserCPred,
YAP_Arity, YAP_Arity);
X_API Term Yap_StringToTerm(const char *s, size_t len, encoding_t *encp, int prio, Term *bindings_p);
X_API Term Yap_StringToTerm(const char *s, size_t len, encoding_t *encp,
int prio, Term *bindings_p);
} }
class YAPEngine; class YAPEngine;

View File

@ -1,11 +1,31 @@
#ifndef YAPIE_HH
#define YAPIE_HH
class YAPPPredicate;
class YAPTerm;
/// take information on a Prolog error:
class YAPError { class YAPError {
int errNo;
public: public:
YAPError() { errNo = YAP_NO_ERROR; }; /// error handling when receiving the error term
YAPError(int err) { errNo = err; }; YAPError(){};
int get(); /// we just know the error number
/// exact error ID
yap_error_number getID() { return LOCAL_ActiveError.errorNo; };
/// class of error
yap_error_class_number getErrorClass() {
return Yap_errorClass(LOCAL_ActiveError.errorNo);
};
/// where in the code things happened;
const char *getFile() { return LOCAL_ActiveError.errorFile; };
/// predicate things happened;
Int getLine() { return LOCAL_ActiveError.errorLine; };
/// the term that caused the bug
// YAPTerm getCulprit(LOCAL_ActiveError.errorFile){};
/// text describing the Error
const char *text(); const char *text();
}; };
#endif

View File

@ -17,7 +17,6 @@ class YAPQuery : public YAPPredicate {
bool q_open; bool q_open;
int q_state; int q_state;
yhandle_t q_g, q_handles; yhandle_t q_g, q_handles;
struct pred_entry *q_pe;
struct yami *q_p, *q_cp; struct yami *q_p, *q_cp;
jmp_buf q_env; jmp_buf q_env;
int q_flags; int q_flags;
@ -25,13 +24,10 @@ class YAPQuery : public YAPPredicate {
YAPQuery *oq; YAPQuery *oq;
YAPListTerm vnames; YAPListTerm vnames;
YAPTerm goal; YAPTerm goal;
Term names; // temporaries
Term t; Term tgoal, names;
void initOpenQ(); void openQuery();
void initQuery(Term t);
void initQuery(YAPAtom at);
void initQuery(YAPTerm ts[], arity_t arity);
public: public:
/// main constructor, uses a predicate and an array of terms /// main constructor, uses a predicate and an array of terms
@ -56,21 +52,24 @@ public:
/// It is given a string, calls the parser and obtains a Prolog term that /// It is given a string, calls the parser and obtains a Prolog term that
/// should be a callable /// should be a callable
/// goal. /// goal.
inline YAPQuery(const char *s) : YAPPredicate(s, t, names) { inline YAPQuery(const char *s): YAPPredicate(s, tgoal, names) {
BACKUP_H();
__android_log_print(ANDROID_LOG_INFO, "YAPDroid", "got game %d", __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "got game %d",
LOCAL_CurSlot); LOCAL_CurSlot);
goal = YAPTerm(tgoal);
vnames = YAPListTerm(names); vnames = YAPListTerm(names);
__android_log_print(ANDROID_LOG_INFO, "YAPDroid", "%s", vnames.text()); __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "%s", vnames.text());
initQuery(t); openQuery();
RECOVER_H();
}; };
/// string constructor with just an atom /// string constructor with just an atom
/// ///
/// It is given an atom, and a Prolog term that should be a callable /// It is given an atom, and a Prolog term that should be a callable
/// goal, say `main`, `init`, `live`. /// goal, say `main`, `init`, `live`.
inline YAPQuery(YAPAtom goal) : YAPPredicate(goal) { inline YAPQuery(YAPAtom g) : YAPPredicate( g ) {
vnames = YAPListTerm(TermNil); goal = YAPAtomTerm( g );
initQuery(goal); vnames = YAPListTerm(names);
openQuery();
}; };
/// set flags for query execution, currently only for exception handling /// set flags for query execution, currently only for exception handling
@ -164,8 +163,13 @@ public:
if (_callback) if (_callback)
_callback->run(s); _callback->run(s);
} }
/// stop yap
void close() {
Yap_exit(0);
}
/// execute the callback with a text argument. /// execute the callback with a text argument.
YAPError hasError() { return yerror.get(); } bool hasError() { return LOCAL_Error_TYPE != YAP_NO_ERROR; }
/// build a query on the engine /// build a query on the engine
YAPQuery *query(const char *s) { return new YAPQuery(s); }; YAPQuery *query(const char *s) { return new YAPQuery(s); };
/// current module for the engine /// current module for the engine
@ -173,6 +177,8 @@ public:
/// given a handle, fetch a term from the engine /// given a handle, fetch a term from the engine
inline YAPTerm getTerm(yhandle_t h) { return YAPTerm(h); } inline YAPTerm getTerm(yhandle_t h) { return YAPTerm(h); }
/// current directory for the engine /// current directory for the engine
bool call(YAPPredicate ap, YAPTerm ts[]);
const char *currentDir() { const char *currentDir() {
char dir[1024]; char dir[1024];
std::string s = Yap_getcwd(dir, 1024 - 1); std::string s = Yap_getcwd(dir, 1024 - 1);

View File

@ -4,6 +4,7 @@
extern "C" Term YAP_ReadBuffer(const char *s, Term *tp); extern "C" Term YAP_ReadBuffer(const char *s, Term *tp);
class YAPError;
/** /**
* @brief Generic Prolog Term * @brief Generic Prolog Term
*/ */
@ -27,8 +28,8 @@ public:
} /// private method to convert from Term (internal YAP representation) to } /// private method to convert from Term (internal YAP representation) to
/// YAPTerm /// YAPTerm
// do nothing constructor // do nothing constructor
YAPTerm() { t = 0; } YAPTerm() { mk(MkVarTerm()); }
YAPTerm(yhandle_t i) { t= i; }; YAPTerm(yhandle_t i) { t = i; };
/// pointer to term /// pointer to term
YAPTerm(void *ptr); YAPTerm(void *ptr);
/// parse string s and construct a term. /// parse string s and construct a term.
@ -36,6 +37,8 @@ public:
Term tp; Term tp;
mk(YAP_ReadBuffer(s, &tp)); mk(YAP_ReadBuffer(s, &tp));
} }
/// parse string s and construct a term.
YAPTerm(YAPFunctor f, YAPTerm ts[]);
/// extract the tag of a term, after dereferencing. /// extract the tag of a term, after dereferencing.
YAP_tag_t tag(); YAP_tag_t tag();
/// copy the term ( term copy ) /// copy the term ( term copy )
@ -76,7 +79,7 @@ public:
virtual bool isList() { return Yap_IsListTerm(gt()); } /// term is a list virtual bool isList() { return Yap_IsListTerm(gt()); } /// term is a list
/// extract the argument i of the term, where i in 1...arity /// extract the argument i of the term, where i in 1...arity
inline YAPTerm getArg(arity_t i) { virtual YAPTerm getArg(arity_t i) {
BACKUP_MACHINE_REGS(); BACKUP_MACHINE_REGS();
Term t0 = gt(); Term t0 = gt();
YAPTerm tf; YAPTerm tf;
@ -155,9 +158,10 @@ class YAPApplTerm : public YAPTerm {
public: public:
~YAPApplTerm() {} ~YAPApplTerm() {}
YAPApplTerm(YAPFunctor f, YAPTerm ts[]); YAPApplTerm(YAPFunctor f, YAPTerm ts[]);
YAPApplTerm(const char *s, std::vector<YAPTerm> ts);
YAPApplTerm(YAPFunctor f); YAPApplTerm(YAPFunctor f);
YAPFunctor getFunctor(); YAPFunctor getFunctor();
inline YAPTerm getArg(arity_t i) { YAPTerm getArg(arity_t i) {
BACKUP_MACHINE_REGS(); BACKUP_MACHINE_REGS();
Term t0 = gt(); Term t0 = gt();
YAPTerm tf; YAPTerm tf;
@ -254,7 +258,8 @@ public:
else if (to == TermNil) else if (to == TermNil)
return YAPListTerm(); return YAPListTerm();
/* error */ /* error */
throw YAPError(TYPE_ERROR_LIST); Yap_Error(TYPE_ERROR_LIST, t, 0);
throw YAPError();
} }
/// copy a list. /// copy a list.
/// ///
@ -303,7 +308,7 @@ public:
// Constructor: receives an atom; // Constructor: receives an atom;
YAPAtomTerm(YAPAtom a) : YAPTerm() { mk(MkAtomTerm(a.a)); } YAPAtomTerm(YAPAtom a) : YAPTerm() { mk(MkAtomTerm(a.a)); }
// Constructor: receives a sequence of ISO-LATIN1 codes; // Constructor: receives a sequence of ISO-LATIN1 codes;
YAPAtomTerm(char *s); YAPAtomTerm(char s[]);
// Constructor: receives a sequence of up to n ISO-LATIN1 codes; // Constructor: receives a sequence of up to n ISO-LATIN1 codes;
YAPAtomTerm(char *s, size_t len); YAPAtomTerm(char *s, size_t len);
// Constructor: receives a sequence of wchar_ts, whatever they may be; // Constructor: receives a sequence of wchar_ts, whatever they may be;