diff --git a/C/atomic.c b/C/atomic.c index 045177b7a..870998527 100755 --- a/C/atomic.c +++ b/C/atomic.c @@ -1440,8 +1440,8 @@ restart_aux: if (!Yap_Concat_Text(n, inpv, out PASS_REGS)) { goto error; } - pop_text_stack(l); at = out->val.a; + pop_text_stack(l); if (at) { bool rc = Yap_unify(ARG2, MkAtomTerm(at)); return rc; diff --git a/C/c_interface.c b/C/c_interface.c index 10fd376f3..b808c66da 100755 --- a/C/c_interface.c +++ b/C/c_interface.c @@ -1723,8 +1723,11 @@ X_API bool YAP_EnterGoal(YAP_PredEntryPtr ape, CELL *ptr, YAP_dogoalinfo *dgi) { bool out; BACKUP_MACHINE_REGS(); + LOCAL_ActiveError->errorNo = YAP_NO_ERROR; LOCAL_PrologMode = UserMode; - dgi->p = P; + if( LOCAL_CommittedError) + LOCAL_CommittedError->errorNo = YAP_NO_ERROR; + dgi->p = P; dgi->cp = CP; dgi->CurSlot = LOCAL_CurSlot; // ensure our current ENV receives current P. @@ -1734,7 +1737,7 @@ X_API bool YAP_EnterGoal(YAP_PredEntryPtr ape, CELL *ptr, YAP_dogoalinfo *dgi) { // __android_log_print(ANDROID_LOG_INFO, "YAP ", "ap=%p %d %x %x args=%x,%x // slot=%d", pe, pe->CodeOfPred->opc, FAILCODE, Deref(ARG1), Deref(ARG2), // LOCAL_CurSlot); - dgi->b = LCL0 - (CELL *)B; + dgi->b = dgi->b0 = LCL0 - (CELL *)B; out = Yap_exec_absmi(true, false); if (out) { dgi->EndSlot = LOCAL_CurSlot; @@ -1749,16 +1752,21 @@ X_API bool YAP_EnterGoal(YAP_PredEntryPtr ape, CELL *ptr, YAP_dogoalinfo *dgi) { X_API bool YAP_RetryGoal(YAP_dogoalinfo *dgi) { CACHE_REGS - choiceptr myB; + choiceptr myB, myB0; bool out; BACKUP_MACHINE_REGS(); myB = (choiceptr)(LCL0 - dgi->b); + myB0 = (choiceptr)(LCL0 - dgi->b0); CP = myB->cp_cp; /* sanity check */ - if (B >= myB) { + if (B >= myB0) { return false; } + if (B < myB) { + // get rid of garbage choice-points + B = myB; + } P = FAILCODE; /* make sure we didn't leave live slots when we backtrack */ ASP = (CELL *)B; @@ -1766,6 +1774,7 @@ X_API bool YAP_RetryGoal(YAP_dogoalinfo *dgi) { out = run_emulator(PASS_REGS1); if (out) { dgi->EndSlot = LOCAL_CurSlot; + dgi->b = LCL0-(CELL *)B; } else { LOCAL_CurSlot = dgi->CurSlot; // ignore any slots created within the called goal @@ -1774,25 +1783,25 @@ X_API bool YAP_RetryGoal(YAP_dogoalinfo *dgi) { return out; } -X_API bool YAP_LeaveGoal(bool backtrack, YAP_dogoalinfo *dgi) { +X_API bool YAP_LeaveGoal(bool successful, YAP_dogoalinfo *dgi) { CACHE_REGS choiceptr myB; BACKUP_MACHINE_REGS(); - myB = (choiceptr)(LCL0 - dgi->b); + myB = (choiceptr)(LCL0 - dgi->b0); if (B >= myB) { /* someone cut us */ return false; } /* prune away choicepoints */ - if (B != myB) { + while (B != myB) { #ifdef YAPOR CUT_prune_to(myB); #endif B = myB; } /* if backtracking asked for, recover space and bindings */ - if (backtrack) { + if (!successful) { P = FAILCODE; Yap_exec_absmi(true, YAP_EXEC_ABSMI); /* recover stack space */ diff --git a/C/computils.c b/C/computils.c index 1d4181e14..ec70e1ef0 100644 --- a/C/computils.c +++ b/C/computils.c @@ -721,7 +721,7 @@ ShowOp (compiler_vm_op ic, const char *f, struct PSEUDO *cpc) Yap_DebugPlWrite (MkIntTerm (rn & 1)); break; case 'w': - Yap_DebugPlWrite (arg); + Yap_DebugPlWrite (MkIntTerm(arg)); break; case 'o': Yap_DebugPlWrite ((Term) * cptr++); diff --git a/C/errors.c b/C/errors.c index 2b3753e7a..ed64f8aa4 100755 --- a/C/errors.c +++ b/C/errors.c @@ -686,7 +686,7 @@ bool Yap_MkErrorRecord( yap_error_descriptor_t *r, Yap_exit(1); } // fprintf(stderr, "warning: "); - if (s[0]) { + if (s && s[0]) { r->errorMsgLen = strlen(s) + 1; r->errorMsg = malloc(r->errorMsgLen); strcpy(r->errorMsg, s); @@ -852,7 +852,7 @@ yamop *Yap_Error__(bool throw, const char *file, const char *function, return P; if (LOCAL_DoingUndefp) { LOCAL_Signals = 0; - Yap_PrintWarning(MkErrorTerm(Yap_GetException())); + Yap_PrintWarning(MkErrorTerm(Yap_GetException(LOCAL_ActiveError))); return P; } //LOCAL_ActiveError = Yap_GetException(); @@ -941,9 +941,9 @@ const char *Yap_errorClassName(yap_error_class_number e) { return c_error_class_name[e]; } -yap_error_descriptor_t *Yap_GetException(void) { +yap_error_descriptor_t *Yap_GetException(yap_error_descriptor_t *i ) { CACHE_REGS - if (LOCAL_ActiveError->errorNo != YAP_NO_ERROR) { + if(i->errorNo != YAP_NO_ERROR) { yap_error_descriptor_t *t = LOCAL_ActiveError, *nt = malloc(sizeof(yap_error_descriptor_t)); memcpy(nt, t, sizeof(yap_error_descriptor_t)); @@ -1025,13 +1025,13 @@ static Int committed_exception(USES_REGS1) { return Yap_unify(ARG1, t); } -static Int get_exception(USES_REGS1) { +static Int get_exception( USES_REGS1) { yap_error_descriptor_t *i; Term t; - LOCAL_CommittedError = i = LOCAL_ActiveError; + i = LOCAL_ActiveError; if (i && i->errorNo != YAP_NO_ERROR) { - i = Yap_GetException(); + i = Yap_GetException(LOCAL_CommittedError); Yap_ResetException(LOCAL_ActiveError); LOCAL_PrologMode = UserMode; if (i->errorRawTerm && diff --git a/C/text.c b/C/text.c index 8f82d425c..e4c7dd20a 100644 --- a/C/text.c +++ b/C/text.c @@ -695,14 +695,15 @@ static Atom write_atom(void *s0, seq_tv_t *out USES_REGS) { } void *write_buffer(unsigned char *s0, seq_tv_t *out USES_REGS) { + int l = push_text_stack(); size_t leng = strlen((char *)s0); size_t min = 0, max = leng; if (out->enc == ENC_ISO_UTF8) { if (out->val.uc == NULL) { // this should always be the case - out->val.uc = BaseMalloc(leng + 1); + out->val.uc = Malloc(leng + 1); strcpy(out->val.c, (char *)s0); } else if (out->val.uc != s0) { - out->val.c = BaseMalloc(leng + 1); + out->val.c = Malloc(leng + 1); strcpy(out->val.c, (char *)s0); } } else if (out->enc == ENC_ISO_LATIN1) { @@ -710,13 +711,18 @@ void *write_buffer(unsigned char *s0, seq_tv_t *out USES_REGS) { unsigned char *s = s0; unsigned char *cp = s; unsigned char *buf = out->val.uc; - if (!buf) + if (!buf) { + pop_text_stack(l); return NULL; + } while (*cp) { utf8proc_int32_t chr; int off = get_utf8(cp, -1, &chr); - if (off <= 0 || chr > 255) + if (off <= 0 || chr > 255) { + pop_text_stack(l); return NULL; + + } if (off == max) break; cp += off; @@ -737,8 +743,10 @@ void *write_buffer(unsigned char *s0, seq_tv_t *out USES_REGS) { wchar_t *buf0, *buf; buf = buf0 = out->val.w; - if (!buf) + if (!buf) { + pop_text_stack(l); return NULL; + } while (*cp && cp < lim) { utf8proc_int32_t chr; cp += get_utf8(cp, -1, &chr); @@ -756,8 +764,10 @@ void *write_buffer(unsigned char *s0, seq_tv_t *out USES_REGS) { *buf = '\0'; } else { // no other encodings are supported. + pop_text_stack(l); return NULL; } + out->val.c = pop_output_text_stack__(l, out->val.c); return out->val.c; } diff --git a/C/threads.c b/C/threads.c index 7360251e7..a7a4136ce 100644 --- a/C/threads.c +++ b/C/threads.c @@ -1174,9 +1174,9 @@ p_with_mutex( USES_REGS1 ) rc = TRUE; } end: - excep = Yap_GetException(); + excep = Yap_GetException(LOCAL_ComiittedError); if ( !UnLockMutex(mut PASS_REGS) ) { - return FALSE; + return FALSE;c } if (creeping) { Yap_signal( YAP_CREEP_SIGNAL ); diff --git a/C/yap-args.c b/C/yap-args.c index a5beb4889..2e25615a9 100755 --- a/C/yap-args.c +++ b/C/yap-args.c @@ -204,7 +204,8 @@ static void consult(const char *b_file USES_REGS) { YAP_CompileClause(t); } yap_error_descriptor_t *errd; - if ((errd = Yap_GetException())) { + if ((errd = + Yap_GetException(LOCAL_CommittedError))) { fprintf(stderr, "%s:%ld:0: Error %s %s Found\n", errd->errorFile, (long int) errd->errorLine, errd->classAsText, errd->errorAsText); } diff --git a/CXX/yapi.cpp b/CXX/yapi.cpp index 3086e47f6..5c43bad9a 100644 --- a/CXX/yapi.cpp +++ b/CXX/yapi.cpp @@ -35,14 +35,13 @@ X_API bool do_init_python(void); static void YAPCatchError() { - if (LOCAL_CommittedError != nullptr && + if (false && LOCAL_CommittedError != nullptr && LOCAL_CommittedError->errorNo != YAP_NO_ERROR ) { // Yap_PopTermFromDB(info->errorTerm); // throw throw YAPError( ); Term es[2]; es[0] = TermError; es[1] = MkErrorTerm(LOCAL_CommittedError); - LOCAL_CommittedError = nullptr; Functor f = Yap_MkFunctor(Yap_LookupAtom("print_message"), 2); YAP_RunGoalOnce(Yap_MkApplTerm(f, 2, es)); // Yap_PopTermFromDB(info->errorTerm); @@ -550,21 +549,11 @@ bool YAPEngine::mgoal(Term t, Term tmod) { __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "exec "); result = (bool)YAP_EnterGoal(ap, nullptr, &q); - if (LOCAL_CommittedError != nullptr && - LOCAL_CommittedError->errorNo != YAP_NO_ERROR) { - throw YAPError(LOCAL_CommittedError); - } - { YAP_LeaveGoal(result, &q); - if (LOCAL_CommittedError != nullptr && - LOCAL_CommittedError->errorNo != YAP_NO_ERROR) { - throw YAPError(LOCAL_CommittedError); - } // PyEval_RestoreThread(_save); RECOVER_MACHINE_REGS(); return result; - } - } catch (...) { + } catch (...) { YAPCatchError(); // free(LOCAL_CommittedError); @@ -697,12 +686,12 @@ YAPQuery::YAPQuery(YAPTerm t) : YAPPredicate(t) { } openQuery(); names = YAPPairTerm(TermNil); - RECOVER_MACHINE_REGS(); } YAPQuery::YAPQuery(YAPPredicate p, YAPTerm ts[]) : YAPPredicate(p.ap) { BACKUP_MACHINE_REGS(); - arity_t arity = p.ap->ArityOfPE; + try { + arity_t arity = p.ap->ArityOfPE; if (arity) { goal = YAPApplTerm(YAPFunctor(p.ap->FunctorOfPred), ts).term(); for (arity_t i = 0; i < arity; i++) @@ -713,7 +702,10 @@ YAPQuery::YAPQuery(YAPPredicate p, YAPTerm ts[]) : YAPPredicate(p.ap) { openQuery(); } names = TermNil; - RECOVER_MACHINE_REGS(); +} catch (...) { + + } +RECOVER_MACHINE_REGS(); } bool YAPQuery::next() { @@ -774,7 +766,7 @@ void YAPQuery::cut() { BACKUP_MACHINE_REGS(); if (!q_open || q_state == 0) return; - YAP_LeaveGoal(FALSE, &q_h); + YAP_LeaveGoal(true, &q_h); q_open = false; // LOCAL_execution = this; RECOVER_MACHINE_REGS(); @@ -803,7 +795,7 @@ void YAPQuery::close() { RECOVER_MACHINE_REGS(); return; } - YAP_LeaveGoal(FALSE, &q_h); + YAP_LeaveGoal(false, &q_h); q_open = 0; Yap_CloseHandles(q_handles); // LOCAL_execution = this; diff --git a/H/Yatom.h b/H/Yatom.h index 0c8857c84..33a0a99ff 100755 --- a/H/Yatom.h +++ b/H/Yatom.h @@ -1605,7 +1605,7 @@ extern Term MkErrorTerm(yap_error_descriptor_t *t); extern bool Yap_ResetException(yap_error_descriptor_t *i); extern bool Yap_HasException(void); -extern yap_error_descriptor_t * Yap_GetException(void); +extern yap_error_descriptor_t * Yap_GetException(); extern void Yap_PrintException(void); INLINE_ONLY inline EXTERN bool Yap_HasException(void) { return LOCAL_ActiveError->errorNo != YAP_NO_ERROR; diff --git a/include/YapDefs.h b/include/YapDefs.h index 9fe877ba3..d7e848eda 100755 --- a/include/YapDefs.h +++ b/include/YapDefs.h @@ -292,7 +292,7 @@ typedef struct yap_boot_params { /* this should be opaque to the user */ typedef struct { - unsigned long b; //> choice-point at entry + unsigned long b, b0; //> choice-point at entry YAP_handle_t CurSlot; //> variables at entry YAP_handle_t EndSlot; //> variables at successful execution struct yami *p; //> Program Counter at entry diff --git a/include/YapError.h b/include/YapError.h index 7342cd337..93eed3834 100644 --- a/include/YapError.h +++ b/include/YapError.h @@ -240,6 +240,7 @@ INLINE_ONLY extern inline Term Yap_ensure_atom__(const char *fu, const char *fi, #define LOCAL_RawTerm LOCAL_ActiveError->errorRawTerm #define LOCAL_ErrorMessage LOCAL_ActiveError->errorMsg + extern void Yap_CatchError(void); extern void Yap_ThrowExistingError(void); extern bool Yap_MkErrorRecord( yap_error_descriptor_t *r, const char *file, const char *function, diff --git a/packages/python/swig/prolog/yapi.yap b/packages/python/swig/prolog/yapi.yap index 39a2aea97..ca91d7f2e 100644 --- a/packages/python/swig/prolog/yapi.yap +++ b/packages/python/swig/prolog/yapi.yap @@ -66,7 +66,7 @@ argi(N,I,I1) :- I1 is I+1. python_query( Caller, String ) :- - atomic_to_term( String, Goal, VarNames ), + atomic_to_term( String, Goal, VarNames ), query_to_answer( Goal, VarNames, Status, Bindings), Caller.port := Status, % := print( gc.get_referrers(Caller.port)), diff --git a/packages/python/swig/yap4py/__init__.py b/packages/python/swig/yap4py/__init__.py deleted file mode 100644 index e6f73887c..000000000 --- a/packages/python/swig/yap4py/__init__.py +++ /dev/null @@ -1,33 +0,0 @@ -import imp -import os -import ctypes -import glob -import os.path -import platform -import sys - -global yap_lib_path -yap_lib_path = "/usr/local/lib" - -if platform.system() == 'Windows': - def load( dll ): - dll = glob.glob(os.path.join(yap_lib_path,dll))[0] - dll = os.path.abspath(dll) - ctypes.WinDLL(dll) -elif platform.system() == 'Darwin': - def load( dll ): - dll = glob.glob(os.path.join(os.path.dirname(__file__),dll))[0] - dll = os.path.abspath(dll) - ctypes.CDLL(dll) - print('loaded ',dll) - - # try: - # load( '_yap*.so' ) - # except: - # load( '_yap*.dylib' ) -else: - def load( dll ): - dll = glob.glob(os.path.join(os.path.dirname(__file__),dll))[0] - dll = os.path.abspath(dll) - ctypes.CDLL(dll) - #load('_yap*.so') diff --git a/packages/python/swig/yap4py/yapi.py b/packages/python/swig/yap4py/yapi.py index 6dfa19f67..fc05175c2 100644 --- a/packages/python/swig/yap4py/yapi.py +++ b/packages/python/swig/yap4py/yapi.py @@ -72,8 +72,7 @@ class Query: if self.q.next(): rc = self.answer if self.port == "exit": - self.close() - return rc + return rc else: if self: self.close() @@ -106,7 +105,7 @@ class v(YAPVarTerm,v0): class YAPShell: - + def numbervars( self ): Dict = {} self.engine.goal(show_answer( self, Dict)) @@ -135,7 +134,7 @@ class YAPShell: # # vs is the list of variables # you can print it out, the left-side is the variable name, # the right side wraps a handle to a variable - # pdb.set_trace() + import pdb; pdb.set_trace() # #pdb.set_trace() # atom match either symbols, or if no symbol exists, sttrings, In this case # variable names should match strings @@ -148,12 +147,12 @@ class YAPShell: bindings = [] loop = False g = python_query(self, query) - self.q = Query( engine, g ) - for bind in self.q: + q = Query( engine, g ) + for bind in q: bindings += [bind] if loop: continue - if not self.q.port == "exit": + if not q.port == "exit": break s = input("more(;), all(*), no(\\n), python(#) ?").lstrip() if s.startswith(';') or s.startswith('y'): @@ -168,13 +167,15 @@ class YAPShell: continue else: break - if self.q: + if q: self.os = query if bindings: return True,bindings print("No (more) answers") return False, None except Exception as e: + if not q: + return False, None print("Exception") print(dir(e)) return False, None @@ -209,7 +210,7 @@ class YAPShell: def __init__(self, engine, **kwargs): self.engine = engine self.live(engine) - + self.q = None def main(): diff --git a/pl/dialect.yap b/pl/dialect.yap index 2aef183bf..1c9aade0f 100644 --- a/pl/dialect.yap +++ b/pl/dialect.yap @@ -111,4 +111,4 @@ exports(In, Exports) :- read(In, Term), Term = (:- module(_Name, Exports)). -@} +%% @} diff --git a/pl/errors.yap b/pl/errors.yap index 47b641a3a..ef3c8e8c3 100644 --- a/pl/errors.yap +++ b/pl/errors.yap @@ -86,6 +86,13 @@ system_error(Type,Goal) :- '$Error'(E) :- '$LoopError'(E, top). +%% +% error_handler(+Error,+ Level) +% +% process a````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````n error term. +% +errorv_handler(Error, Level) :- + '$LoopError'(Error, Level). '$LoopError'(_, _) :- flush_output(user_output), @@ -124,7 +131,9 @@ system_error(Type,Goal) :- throw(error(permission_error(module,redefined,A),B)). '$process_error'(Error, _Level) :- functor(Error, Severity, _), - print_message(Severity, Error), !. + print_message(Severity, Error), + !, + '$close_error'. '$process_error'(error(Type,Info), _, _) :- print_message(error,error(unhandled_exception(Type),Info)). diff --git a/pl/hacks.yap b/pl/hacks.yap index f3eb6bb43..fb28e5881 100644 --- a/pl/hacks.yap +++ b/pl/hacks.yap @@ -170,7 +170,7 @@ show_env(Env,Cont,NCont) --> ['~@.~n' - write_term(G,Opts)]. clean_goal(G,Mod,NG) :- - beautify_hidden_goal(G,Mod,[NG],[]), !. + fail, beautify_hidden_goal(G,Mod,[NG],[]), !. clean_goal(G,_,G). scratch_goal(N,0,Mod,Mod:N) :- @@ -179,7 +179,7 @@ scratch_goal(N,A,Mod,NG) :- list_of_qmarks(A,L), G=..[N|L], ( - beautify_hidden_goal(G,Mod,[NG],[]) + fail,beautify_hidden_goal(G,Mod,[NG],[]) ; G = NG ), diff --git a/pl/meta.yap b/pl/meta.yap index 4d152e7d7..637ae28df 100644 --- a/pl/meta.yap +++ b/pl/meta.yap @@ -408,7 +408,17 @@ o:p(B) :- n:g, X is 2+3, call(B). ). '$user_expansion'(MG, MG). + '$match_mod'(G, HMod, SMod, M, O) :- + '$is_system_predicate'(G,M), + !, + O = G. + '$match_mod'(G, M, M, M, G) :- !. + '$match_mod'(G, _HM, _M, M, M:G). + + +/* +'$match_mod'(G, HMod, SMod, M, O) :- ( % \+ '$is_multifile'(G1,M), %-> @@ -420,8 +430,10 @@ o:p(B) :- n:g, X is 2+3, call(B). -> O = G ; + stop_low_level_trace, O = M:G ). +*/ '$build_up'(HM, NH, SM, true, NH, true, NH) :- HM == SM, !. '$build_up'(HM, NH, _SM, true, HM:NH, true, HM:NH) :- !. @@ -503,4 +515,4 @@ expand_goal(Input, Output) :- '$expand_goals'(IG, _, GF0, M, SM, M, HVars-G), '$yap_strip_module'(M:GF0, MF, GF). -%% @} \ No newline at end of file +%% @} diff --git a/pl/top.yap b/pl/top.yap index 7cb725c83..a6113e41b 100644 --- a/pl/top.yap +++ b/pl/top.yap @@ -17,17 +17,15 @@ % @pred live % % start a Prolog engine. -live :- '$live'. - -'$live' :- - repeat, - '$current_module'(Module), - ( Module==user -> - true % '$compile_mode'(_,0) - ; - format(user_error,'[~w]~n', [Module]) - ), - '$system_catch'('$enter_top_level',Module,Error,'$Error'(Error)). +live :- + repeat, + '$current_module'(Module), + ( Module==user -> + true % '$compile_mode'(_,0) + ; + format(user_error,'[~w]~n', [Module]) + ), + '$system_catch'('$enter_top_level',Module,Error,'$Error'(Error)). % Start file for yap @@ -74,7 +72,7 @@ live :- '$live'. '$run_atom_goal'(GA), fail. '$enter_top_level' :- - flush_output, + flush_output, '$run_toplevel_hooks', prompt1(' ?- '), '$read_toplevel'(Command,Varnames,Pos), @@ -976,7 +974,7 @@ catch(G, C, A) :- -> ! ; - true + true ). '$catch'(_,C,A) :- '$get_exception'(C0),