diff --git a/C/cmppreds.c b/C/cmppreds.c index 8b4c800c1..da947221f 100644 --- a/C/cmppreds.c +++ b/C/cmppreds.c @@ -117,12 +117,12 @@ cmp_atoms(Atom a1, Atom a2) } } -static int compare_complex(register CELL *pt0, register CELL *pt0_end, register +static Int compare_complex(register CELL *pt0, register CELL *pt0_end, register CELL *pt1) { CACHE_REGS register CELL **to_visit = (CELL **)HR; - register int out = 0; + register Int out = 0; loop: while (pt0 < pt0_end) { diff --git a/C/flags.c b/C/flags.c index e7c22d3af..4b850c0d9 100644 --- a/C/flags.c +++ b/C/flags.c @@ -47,9 +47,13 @@ static Term sys_pid(Term inp); static bool mkprompt(Term inp); static Term synerr(Term inp); static Term indexer(Term inp); +static Term stream(Term inp); static bool getenc(Term inp); static bool typein(Term inp); static bool dqf(Term t2); +static bool set_error_stream( Term inp ); +static bool set_input_stream( Term inp ); +static bool set_output_stream( Term inp ); static void newFlag(Term fl, Term val); static Int current_prolog_flag(USES_REGS1); @@ -168,6 +172,43 @@ static Term isaccess(Term inp) { return TermZERO; } +static Term stream(Term inp) { + if ( IsVarTerm(inp) ) + return inp; + if (Yap_CheckStream( inp, Input_Stream_f | Output_Stream_f | + Append_Stream_f | Socket_Stream_f, "yap_flag/3" ) >= 0) + return inp; + return 0; + +} + +static bool +set_error_stream( Term inp ) { + if( IsVarTerm(inp) ) + return Yap_unify( inp, Yap_StreamUserName( LOCAL_c_error_stream ) ); + LOCAL_c_error_stream = Yap_CheckStream( inp, Output_Stream_f | + Append_Stream_f | Socket_Stream_f, "yap_flag/3" ); + return true; +} + +static bool +set_input_stream( Term inp ) { + if( IsVarTerm(inp) ) + return Yap_unify( inp, Yap_StreamUserName( LOCAL_c_input_stream ) ); + LOCAL_c_input_stream = Yap_CheckStream( inp, Input_Stream_f | Socket_Stream_f, "yap_flag/3" ); + return true; +} + +static bool +set_output_stream( Term inp ) { + if( IsVarTerm(inp) ) + return Yap_unify( inp, Yap_StreamUserName( LOCAL_c_output_stream ) ); + LOCAL_c_output_stream = Yap_CheckStream( inp, Output_Stream_f | + Append_Stream_f | Socket_Stream_f, "yap_flag/3" ); + return true; +} + + static Term isground(Term inp) { return Yap_IsGroundTerm(inp) ? inp : TermZERO; } @@ -1473,7 +1514,7 @@ static void newFlag(Term fl, Term val) { GLOBAL_flagCount++; f.name = (char *)RepAtom(AtomOfTerm(fl))->StrOfAE; f.writable = true; - f.helper = 0; + f.helper = NULL; f.def = ok; initFlag(&f, i, true); if (IsAtomOrIntTerm(val)) { diff --git a/C/heapgc.c b/C/heapgc.c index 6b02980cf..6159b19d6 100644 --- a/C/heapgc.c +++ b/C/heapgc.c @@ -463,8 +463,14 @@ push_registers(Int num_regs, yamop *nextop USES_REGS) while (curslot < topslot) { // printf("%p <- %p\n", TR, topslot); ret = check_pr_trail(ret PASS_REGS); - TrailTerm(TR++) = *curslot++; - } + if (!IsVarTerm(*curslot) && + ( + (*curslot < (CELL)LOCAL_GlobalBase && + *curslot > (CELL)HR))) { + *curslot++ = TermNil; + } + TrailTerm(TR++) = (CELL)curslot++; + } } for (i = 1; i <= num_regs; i++) { ret = check_pr_trail(ret PASS_REGS); @@ -573,6 +579,7 @@ pop_registers(Int num_regs, yamop *nextop USES_REGS) while (curslot < topslot) { *curslot++ = TrailTerm(ptr++); } + } for (i = 1; i <= num_regs; i++) @@ -1193,7 +1200,7 @@ mark_variable(CELL_PTR current USES_REGS) char *local_bp = LOCAL_bp; begin: - if (UNMARKED_MARK(current,local_bp)) { + if (current == 0 || UNMARKED_MARK(current,local_bp)) { POP_CONTINUATION(); } if (current >= H0 && current < HR) { diff --git a/C/scanner.c b/C/scanner.c index e5a786240..1f54342e0 100755 --- a/C/scanner.c +++ b/C/scanner.c @@ -1267,6 +1267,8 @@ const char *Yap_tokRep(TokEntry *tokptr, encoding_t encoding) { case QuasiQuotes_tok: case WQuasiQuotes_tok: return ""; + default: + return "??"; } } diff --git a/C/stack.c b/C/stack.c index 97b92ef6a..21a5ef335 100644 --- a/C/stack.c +++ b/C/stack.c @@ -779,19 +779,25 @@ static PredEntry *found_expand(yamop *pc, void **startp, return pp; } -static PredEntry *found_ystop(yamop *pc, int clause_code, void **startp, - void **endp, PredEntry *pp USES_REGS) { +static PredEntry *found_ystop(yamop *pc, int clause_code, void **startp, void **endp, PredEntry *pp USES_REGS) { if (pc == YESCODE) { pp = RepPredProp(Yap_GetPredPropByAtom(AtomTrue, CurrentModule)); - *startp = (CODEADDR)YESCODE; - *endp = (CODEADDR)YESCODE + (CELL)(NEXTOP((yamop *)NULL, e)); + if (startp) + *startp = (CODEADDR)YESCODE; + if (endp) + *endp = (CODEADDR)YESCODE + (CELL)(NEXTOP((yamop *)NULL, e)); return pp; - } - if (!pp) { - /* must be an index */ + } + if (!pp) { + yamop *o = PREVOP(pc,pp); + if (o->opc ==Yap_opcode(_execute_cpred)) { + pp = o->y_u.pp.p0; + } else { + /* must be an index */ PredEntry **pep = (PredEntry **)pc->y_u.l.l; pp = pep[-1]; } + } if (pp->PredFlags & LogUpdatePredFlag) { if (clause_code) { LogUpdClause *cl = ClauseCodeToLogUpdClause(pc->y_u.l.l); diff --git a/CMakeLists.txt b/CMakeLists.txt index e6eff0a80..ebfd177ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -142,5 +142,5 @@ set_target_properties(libYap ) - include(Config NO_POLICY_SCOPE) MY_include(Packages NO_POLICY_SCOPE) + include(Config NO_POLICY_SCOPE) diff --git a/CXX/CMakeLists.txt b/CXX/CMakeLists.txt index 3c9a1efd3..105fbb8e6 100644 --- a/CXX/CMakeLists.txt +++ b/CXX/CMakeLists.txt @@ -8,23 +8,23 @@ set (CXX_SOURCES yapi.cpp ) + list(APPEND LIBYAP_SOURCES ${CXX_SOURCES} PARENT_SCOPE) - if (ANDROID OR WIN32) -add_component (Yap++ ${CXX_SOURCES} ) + add_component (Yap++ ${CXX_SOURCES} ) else() -add_external (Yap++ ${CXX_SOURCES} ) -MY_target_link_libraries(Yap++ ${CMAKE_DL_LIBS} libYap) + add_external (Yap++ ${CXX_SOURCES} ) + MY_target_link_libraries(Yap++ ${CMAKE_DL_LIBS} libYap) -MY_install(TARGETS Yap++ - LIBRARY DESTINATION ${libdir} - ARCHIVE DESTINATION ${libdir} - ) + MY_install(TARGETS Yap++ + LIBRARY DESTINATION ${libdir} + ARCHIVE DESTINATION ${libdir} + ) endif() -include_directories ( . ${CMAKE_BINARY_DIR} ${GMP_INCLUDE_DIRS}) +include_directories ( . ${CMAKE_BINARY_DIR} ${GMP_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS}) set( CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${GMP_INCLUDE_DIRS} ) diff --git a/CXX/yapi.cpp b/CXX/yapi.cpp index 28f6ac379..96ad0815f 100644 --- a/CXX/yapi.cpp +++ b/CXX/yapi.cpp @@ -231,10 +231,11 @@ YAPPairTerm::YAPPairTerm() : YAPTerm() { RECOVER_H(); } -void YAPTerm::mk(Term t0) { CACHE_REGS t = Yap_InitSlot(t0); } - Term YAPTerm::gt() { CACHE_REGS return Yap_GetFromSlot(t); } +void YAPTerm::mk(Term t0) { CACHE_REGS t= Yap_InitSlot(t0); } + + YAP_tag_t YAPTerm::tag() { Term tt = gt(); if (IsVarTerm(tt)) { @@ -465,32 +466,36 @@ const char *YAPAtom::getName(void) { return Yap_AtomToUTF8Text( a, nullptr ); } -void YAPQuery::openQuery() { - 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; - // LOCAL_execution = this; - q_open = true; - q_state = 0; - q_flags = true; // PL_Q_PASS_EXCEPTION; - q_p = P; - q_cp = CP; - // make sure this is safe - q_handles = Yap_StartSlots(); -} + + + void YAPQuery::openQuery() { + 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; + // LOCAL_execution = this; + q_open = true; + q_state = 0; + q_flags = true; // PL_Q_PASS_EXCEPTION; + + q_p = P; + q_cp = CP; + // make sure this is safe + q_handles = Yap_StartSlots(); + } + bool YAPEngine::call(YAPPredicate ap, YAPTerm ts[]) { CACHE_REGS @@ -501,12 +506,11 @@ bool YAPEngine::call(YAPPredicate ap, YAPTerm ts[]) { Term terr; jmp_buf q_env; for (arity_t i = 0; i < arity; i++) - XREGS[i + 1] = ts[i].term(); + Yap_XREGS[i + 1] = ts[i].term(); q.CurSlot = Yap_StartSlots(); q.p = P; q.cp = CP; // make sure this is safe - if (setjmp(q_env)) { if ((terr = Yap_PeekException())) { YAP_LeaveGoal(false, &q); @@ -515,16 +519,8 @@ bool YAPEngine::call(YAPPredicate ap, YAPTerm ts[]) { } return false; } - // don't forget, on success these guys may create slots - __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "exec "); - result = (bool)YAP_EnterGoal(ap.asPred(), nullptr, &q); - if ((terr = Yap_GetException())) { - YAP_LeaveGoal(false, &q); - throw YAPError(); - } - __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "out %d", result); - - if (!result) { + // don't forget, on success these l); +if (!result) { YAP_LeaveGoal(false, &q); } else { YAP_LeaveGoal(FALSE, &q); @@ -533,14 +529,18 @@ bool YAPEngine::call(YAPPredicate ap, YAPTerm ts[]) { return result; } -bool YAPEngine::goal(YAPTerm Yt) { +bool YAPEngine::goalt(YAPTerm Yt) { + return Yt.term(); + } + + +bool YAPEngine::goal(Term t) { CACHE_REGS BACKUP_MACHINE_REGS(); - Term t = Yt.term(), terr, tmod = CurrentModule, *ts = nullptr; + Term terr, tmod = CurrentModule, *ts = nullptr; PredEntry *ap = Yap_get_pred(t, tmod, "C++"); arity_t arity = ap->ArityOfPE; bool result; - YAP_dogoalinfo q; jmp_buf q_env; if (IsApplTerm(t)) { @@ -565,6 +565,8 @@ bool YAPEngine::goal(YAPTerm Yt) { } // don't forget, on success these guys may create slots __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "exec "); + + result = (bool)YAP_EnterGoal(ap, nullptr, &q); if ((terr = Yap_GetException())) { YAP_LeaveGoal(false, &q); @@ -581,6 +583,84 @@ bool YAPEngine::goal(YAPTerm Yt) { return result; } +void YAPEngine::release() { + + BACKUP_MACHINE_REGS(); + YAP_LeaveGoal(FALSE, &q); + RECOVER_MACHINE_REGS(); + } + +Term YAPEngine::fun(Term t) { + CACHE_REGS + BACKUP_MACHINE_REGS(); + Term tmod = CurrentModule, *ts = nullptr; + PredEntry *ap ; + arity_t arity = arity; + Functor f; + jmp_buf q_env; + Atom name; + + + BACKUP_MACHINE_REGS(); + if (IsApplTerm(t)) { + ts = RepAppl(t) + 1; + f = (Functor)ts[-1]; + name = NameOfFunctor(f); + arity =ArityOfFunctor(f); + for (arity_t i = 0; i < arity; i++) + XREGS[i + 1] = ts[i]; + } else if (IsAtomTerm(t)) { + name = AtomOfTerm(t); + f = nullptr; + } else if (IsAtomTerm(t)) { + XREGS[1] = ts[0]; + XREGS[2] = ts[1]; + name = AtomDot; + f = FunctorDot; + } + XREGS[arity+1] = MkVarTerm(); + arity ++; + f = Yap_MkFunctor(name,arity); + ap = (PredEntry *)(PredPropByFunc(f,tmod)); + q.CurSlot = Yap_StartSlots(); + q.p = P; + q.cp = CP; + // make sure this is safe + yhandle_t o = Yap_InitHandle(XREGS[arity]); + + if (setjmp(q_env)) { + Term terr; + if ((terr = Yap_PeekException())) { + YAP_LeaveGoal(false, &q); + Yap_CloseHandles(q.CurSlot); + throw YAPError(); + } + return 0; + } + // don't forget, on success these guys may create slots + __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "exec "); + + if ((o = (Term)YAP_EnterGoal(ap, nullptr, &q))==0) + return 0; + Term terr; + if ((terr = Yap_GetException())) { + YAP_LeaveGoal(false, &q); + Yap_CloseHandles(q.CurSlot); + throw YAPError(); + } + __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "out %d", result); + + Term result; + t = Yap_GetFromSlot(q.CurSlot); + Yap_CloseHandles(q.CurSlot); + if (!t) { + YAP_LeaveGoal(false, &q); + result = 0; + } + RECOVER_MACHINE_REGS(); + return t; +} + YAPQuery::YAPQuery(YAPFunctor f, YAPTerm mod, YAPTerm ts[]) : YAPPredicate(f, mod) { /* ignore flags for now */ @@ -592,7 +672,7 @@ YAPQuery::YAPQuery(YAPFunctor f, YAPTerm mod, YAPTerm ts[]) } YAPQuery::YAPQuery(YAPFunctor f, YAPTerm ts[]) : YAPPredicate(f) { - /* ignore flags for now */ + /* ignore flags for now */ BACKUP_MACHINE_REGS(); goal = YAPTerm(f, ts); vnames = YAPListTerm(); @@ -987,3 +1067,24 @@ const char *YAPError::text() { printf("%s\n", s.c_str()); return s.c_str(); } + +void YAPEngine::reSet() + { + /* ignore flags for now */ + BACKUP_MACHINE_REGS(); + Yap_RebootHandles(worker_id); + while (B->cp_b) B= B->cp_b; + P = FAILCODE; + Yap_exec_absmi(true, YAP_EXEC_ABSMI); + /* recover stack space */ + HR = B->cp_h; + TR = B->cp_tr; +#ifdef DEPTH_LIMIT + DEPTH = B->cp_depth; +#endif /* DEPTH_LIMIT */ + YENV = ENV = B->cp_env; + + RECOVER_MACHINE_REGS(); + } + + diff --git a/CXX/yapi.hh b/CXX/yapi.hh index ae0971bbb..b7549a370 100644 --- a/CXX/yapi.hh +++ b/CXX/yapi.hh @@ -1,5 +1,6 @@ + #define YAP_CPP_INTERFACE 1 #include @@ -67,6 +68,7 @@ extern "C" { #include "iopreds.h" #ifdef SWIGPYTHON +extern PyObject *yap_to_pythond(YAP_Term t, bool eval); extern PyObject *term_to_python(yhandle_t t, bool eval); extern PyObject *deref_term_to_python(yhandle_t t); X_API bool init_python(void); @@ -93,6 +95,8 @@ extern inline PyObject *AtomToPy(const char *s) { return NULL; } +X_API extern PyObject *yap_to_python(YAP_Term t, bool eval); + #endif X_API void YAP_UserCPredicate(const char *, YAP_UserCPred, YAP_Arity arity); @@ -102,13 +106,9 @@ X_API void YAP_UserCPredicate(const char *, YAP_UserCPred, YAP_Arity arity); X_API void YAP_UserCPredicateWithArgs(const char *, YAP_UserCPred, YAP_Arity, YAP_Term); -/* void UserBackCPredicate(const char *name, int *init(), int *cont(), int - arity, int extra) */ -X_API void YAP_UserBackCPredicate(const char *, YAP_UserCPred, YAP_UserCPred, - YAP_Arity, YAP_Arity); +X_API void UserBackCPredicate(const char *name, int *init(), int *cont(), int + arity, int extra); -X_API Term Yap_StringToTerm(const char *s, size_t len, encoding_t *encp, - int prio, Term *bindings_p); } class YAPEngine; diff --git a/CXX/yapq.hh b/CXX/yapq.hh index 164bf520a..3304e82c5 100644 --- a/CXX/yapq.hh +++ b/CXX/yapq.hh @@ -135,6 +135,7 @@ private: YAP_init_args init_args; YAPError yerror; void doInit(YAP_file_type_t BootMode); + YAP_dogoalinfo q; public: /// construct a new engine; may use a variable number of arguments @@ -179,7 +180,17 @@ public: /// current directory for the engine bool call(YAPPredicate ap, YAPTerm ts[]); /// current directory for the engine - bool goal(YAPTerm t); + bool goalt(YAPTerm t); + /// current directory for the engine + bool goal(Term t); +#if SWIGPYTHON + bool unlockedGoal(Term t) {bool rc;Py_BEGIN_ALLOW_THREADS; rc = goal(t);Py_END_ALLOW_THREADS; return rc; } +#endif + /// reset Prolog state + void reSet(); + /// release: assune that there are no stack pointers, just release memory + // for last execution + void release(); const char *currentDir() { char dir[1024]; @@ -191,11 +202,7 @@ public: std::string s = Yap_version(); return s.c_str(); }; -#ifdef SWIGPYTHON - inline void share(PyObject *arg) { - LOCAL_shared = arg; - }; -#endif + Term fun(Term t); }; #endif /* YAPQ_HH */ diff --git a/H/YapHandles.h b/H/YapHandles.h index 47b9af43a..c6c822b3c 100755 --- a/H/YapHandles.h +++ b/H/YapHandles.h @@ -216,6 +216,10 @@ INLINE_ONLY inline EXTERN yhandle_t Yap_InitHandle__(Term t USES_REGS) { yhandle_t old_slots = LOCAL_CurHandle; ensure_slots(1 PASS_REGS); + if (IsVarTerm(t) && (H0 > (CELL*)t || (CELL*)t > HR)) { + RESET_VARIABLE(HR); + Yap_unify(t,(CELL)HR); t = (CELL)HR++; + } LOCAL_HandleBase[old_slots] = t; LOCAL_CurHandle++; return old_slots; diff --git a/H/YapLFlagInfo.h b/H/YapLFlagInfo.h index 9260b2385..4fa1e16ee 100644 --- a/H/YapLFlagInfo.h +++ b/H/YapLFlagInfo.h @@ -83,7 +83,7 @@ which must be an atom. If unbound, unify the argument with the current working module. */ -YAP_FLAG( USER_ERROR_FLAG, "user_error", true, isatom, "user_error" , NULL ), /**< `user_error1` + YAP_FLAG( USER_ERROR_FLAG, "user_error", true, stream, "user_error" , set_error_stream ), /**< `user_error1` If the second argument is bound to a stream, set user_error to this stream. If the second argument is unbound, unify the argument with @@ -114,5 +114,5 @@ prompts from the system were redirected to the stream automatically redirects the user_error alias to the original `stderr`. */ -YAP_FLAG( USER_INPUT_FLAG, "user_input", true, isatom, "user_input" , NULL ), - YAP_FLAG( USER_OUTPUT_FLAG, "user_output", true, isatom, "user_output" , NULL ), +YAP_FLAG( USER_INPUT_FLAG, "user_input", true, stream, "user_input" , set_input_stream ), + YAP_FLAG( USER_OUTPUT_FLAG, "user_output", true, stream, "user_output" , set_output_stream ), diff --git a/Packages.cmake b/Packages.cmake index 5935cb5bf..97b5c7ce8 100644 --- a/Packages.cmake +++ b/Packages.cmake @@ -2,10 +2,6 @@ message(STATUS "Building YAP packages version ${YAP_VERSION}") -include (cudd NO-POLICY-SCOPE) -include (python NO-POLICY-SCOPE) -include (java NO-POLICY-SCOPE) - if (NOT WIN32) @@ -156,7 +152,6 @@ target_link_libraries(yap-bin libYap ) ) - CMAKE_DEPENDENT_OPTION (WITH_SYSTEM_MMAP "Use MMAP for shared memory allocation" ON "NOT WITH_YAPOR_THOR" OFF) diff --git a/Prelims.cmake b/Prelims.cmake index 55e7c1341..f7c9de1db 100644 --- a/Prelims.cmake +++ b/Prelims.cmake @@ -174,3 +174,8 @@ set(YAP_ROOTDIR "${prefix}") # include( Sources NO_POLICY_SCOPE ) # # include( Model NO_POLICY_SCOPE ) + +include (cudd NO-POLICY-SCOPE) +include (python NO-POLICY-SCOPE) +include (java NO-POLICY-SCOPE) + diff --git a/cmake/python.cmake b/cmake/python.cmake index a5bef070e..3898249b1 100644 --- a/cmake/python.cmake +++ b/cmake/python.cmake @@ -25,4 +25,9 @@ find_package(PythonLibs) macro_log_feature (PYTHONLIBS_FOUND "Python" "Use Python System" - "http://www.python.org" FALSE) + "http://www.python.org" FALSE) + +#include_directories( ${PYTHON_INCLUDE_DIRS} ) + +set( CMAKE_REQUIRED_INCLUDES ${PYTHON_INCLUDE_DIRS} ${CMAKE_REQUIRED_INCLUDES} ) +check_include_file(Python.h HAVE_PYTHON_H) diff --git a/config.h.cmake b/config.h.cmake index 5df4a3b9e..9f34be495 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -1013,6 +1013,11 @@ function. */ #cmakedefine HAVE_PWD_H ${HAVE_PWD_H} #endif +/* Define to 1 if you have the header file. */ +#ifndef HAVE_PYTHON_H +#cmakedefine HAVE_PYTHON_H ${HAVE_PYTHON_H} +#endif + /* Define to 1 if you have the `rand' function. */ #ifndef HAVE_RAND #cmakedefine HAVE_RAND ${HAVE_RAND} @@ -1033,7 +1038,6 @@ function. */ #cmakedefine HAVE_RAPTOR_H ${HAVE_RAPTOR_H} #endif - /* Define to 1 if you have the `readlink' function. */ #ifndef HAVE_READLINK #cmakedefine HAVE_READLINK ${HAVE_READLINK} diff --git a/library/dialect/swi/fli/swi.c b/library/dialect/swi/fli/swi.c index ac03d6702..5dda192de 100755 --- a/library/dialect/swi/fli/swi.c +++ b/library/dialect/swi/fli/swi.c @@ -258,7 +258,7 @@ X_API int PL_unify_chars(term_t l, int flags, size_t length, const char *s) { if (flags & REP_UTF8) { inp.val.c0 = s; - inp.type = YAP_STRING_CHARS | ENC_ISO_LATIN1; + inp.type = YAP_STRING_CHARS | ENC_ISO_UTF8; if (length != (size_t)-1) { inp.type |= YAP_STRING_NCHARS; } diff --git a/os/CMakeLists.txt b/os/CMakeLists.txt index dd5e1c492..6915be592 100644 --- a/os/CMakeLists.txt +++ b/os/CMakeLists.txt @@ -110,7 +110,7 @@ include(CheckVariableExists) check_function_exists( rl_reset_after_signal HAVE_RL_RESET_AFTER_SIGNAL ) check_function_exists( rl_set_keyboard_input_timeout HAVE_RL_SET_KEYBOARD_INPUT_TIMEOUT ) check_function_exists( rl_set_prompt HAVE_RL_SET_PROMPT) - check_symbol_exists( rl_catch_signals "readline/readline.h" HAVE_DECL_RL_CATCH_SIGNALS ) + check_symbol_exists( rl_catch_signals "stdio.h;readline/readline.h" HAVE_DECL_RL_CATCH_SIGNALS ) check_type_size( rl_completion_func_t RL_COMPLETION_FUNC_T ) check_symbol_exists( rl_done stdio.h;readline/readline.h HAVE_DECL_RL_DONE ) CHECK_TYPE_SIZE( rl_hook_func_t RL_HOOK_FUNC_T ) diff --git a/os/streams.c b/os/streams.c index 0f32b6ab6..bfb356f05 100644 --- a/os/streams.c +++ b/os/streams.c @@ -1061,7 +1061,7 @@ static Int line_count(USES_REGS1) { /* '$current_line_number'(+Stream,-N) */ return (Yap_unify_constant(ARG2, tout)); } -static Int p_line_position(USES_REGS1) { /* '$line_position'(+Stream,-N) */ +static Int line_position(USES_REGS1) { /* '$line_position'(+Stream,-N) */ Term tout; int sno = Yap_CheckStream(ARG1, Input_Stream_f | Output_Stream_f | Append_Stream_f, @@ -1084,7 +1084,7 @@ static Int p_line_position(USES_REGS1) { /* '$line_position'(+Stream,-N) */ return (Yap_unify_constant(ARG2, tout)); } -static Int p_character_count(USES_REGS1) { /* '$character_count'(+Stream,-N) */ +static Int character_count(USES_REGS1) { /* '$character_count'(+Stream,-N) */ Term tout; int sno = Yap_CheckStream(ARG1, Input_Stream_f | Output_Stream_f | Append_Stream_f, @@ -1420,9 +1420,9 @@ void Yap_InitIOStreams(void) { SafePredFlag | SyncPredFlag | HiddenPredFlag); Yap_InitCPred("$check_stream", 1, p_check_if_stream, SafePredFlag | SyncPredFlag | HiddenPredFlag | HiddenPredFlag); - Yap_InitCPred("$line_position", 2, p_line_position, + Yap_InitCPred("line_position", 2, line_position, SafePredFlag | SyncPredFlag | HiddenPredFlag); - Yap_InitCPred("$character_count", 2, p_character_count, + Yap_InitCPred("character_count", 2, character_count, SafePredFlag | SyncPredFlag | HiddenPredFlag); Yap_InitCPred("$show_stream_flags", 2, p_show_stream_flags, SafePredFlag | SyncPredFlag | HiddenPredFlag); diff --git a/packages/python/CMakeLists.txt b/packages/python/CMakeLists.txt index a87d919be..127307e9b 100644 --- a/packages/python/CMakeLists.txt +++ b/packages/python/CMakeLists.txt @@ -15,7 +15,7 @@ set (PYTHON_HEADERS target_link_libraries(YAPPython libYap ${PYTHON_LIBRARIES}) -set(SETUP_PY "${CMAKE_CURRENT_BINARY_DIR}/setup.py") + set(SETUP_PY "${CMAKE_CURRENT_BINARY_DIR}/setup.py") add_custom_target ( YAPex ALL COMMAND ${PYTHON_EXECUTABLE} setup.py build -f diff --git a/packages/python/pl2py.c b/packages/python/pl2py.c index 2378c459b..739d4dcba 100644 --- a/packages/python/pl2py.c +++ b/packages/python/pl2py.c @@ -2,18 +2,23 @@ #include "python.h" +PyObject *yap_to_python(YAP_Term t, bool eval) { + term_t yt = PL_new_term_ref(); + PyObject *o = term_to_python(yt, eval); + PL_reset_term_refs(yt); + return o; +} /** * term_to_python translates and evaluates from Prolog to Python * * @param t handle to Prolog term -* @param t whether should try to evaluate evaluables. +* @param t whether should try to evaluate evaluables. * * @return a Python object descriptor or NULL if failed */ PyObject *term_to_python(term_t t, bool eval) { // Yap_DebugPlWrite(YAP_GetFromSlot(t)); fprintf(stderr, " here I - // am\n"); YAP_Term yt = YAP_GetFromSlot(t); switch (PL_term_type(t)) { case PL_VARIABLE: { @@ -64,7 +69,7 @@ PyObject *term_to_python(term_t t, bool eval) { if (!c && PyObject_HasAttrString(py_Yapex, "A")) c = PyObject_GetAttrString(py_Yapex, "A"); if (!c || !PyCallable_Check(c)) { - return NULL; + return o; } else { PyObject *t = PyTuple_New(1); PyTuple_SET_ITEM(t, 0, PyUnicode_FromString(s)); @@ -79,7 +84,7 @@ PyObject *term_to_python(term_t t, bool eval) { case PL_STRING: { char *s = NULL; if (!PL_get_chars(t, &s, - REP_UTF8 | CVT_ATOM | CVT_STRING | BUF_DISCARDABLE)) { + REP_UTF8 | CVT_ATOM | CVT_STRING | BUF_MALLOC)) { return NULL; } #if PY_MAJOR_VERSION < 3 @@ -90,6 +95,10 @@ PyObject *term_to_python(term_t t, bool eval) { { PyObject *pobj = PyUnicode_DecodeUTF8(s, strlen(s), NULL); // fprintf(stderr, "%s\n", s); + free(s); + if (pobj) { + Py_IncRef(pobj); + } return pobj; } } break; diff --git a/packages/python/py2pl.c b/packages/python/py2pl.c index 5c61e0af3..691b16a3e 100644 --- a/packages/python/py2pl.c +++ b/packages/python/py2pl.c @@ -254,7 +254,7 @@ foreign_t python_to_term(PyObject *pVal, term_t t) { return rc; #else // new interface - char *s = PyUnicode_AsUTF8AndSize(pVal, &sz); + char *s = PyUnicode_AsUTF8AndSize(pValR, &sz); return repr_term(s, sz, t); #endif } diff --git a/packages/python/pybips.c b/packages/python/pybips.c index 478dfef3b..c1ccbbad7 100644 --- a/packages/python/pybips.c +++ b/packages/python/pybips.c @@ -651,7 +651,7 @@ term_to_nametuple( const char *s, int arity, term_t t) { PyTypeObject *typp; PyObject *o; PyObject *key = PyUnicode_FromString(s); -if (PyDict_Contains(py_F2P, key)) { + if (py_F2P && PyDict_Contains(py_F2P, key)) { typp = (PyTypeObject*)PyDict_GetItem(py_F2P, key); } else { @@ -670,7 +670,8 @@ if (PyDict_Contains(py_F2P, key)) { Py_INCREF(typp); // typp->tp_flags |= Py_TPFLAGS_HEAPTYPE; PyModule_AddObject(py_Yapex, s, (PyObject *)typp); - PyDict_SetItem(py_F2P, key, (PyObject *)typp); + if (py_F2P) + PyDict_SetItem(py_F2P, key, (PyObject *)typp); } o = PyStructSequence_New(typp); term_t tleft = PL_new_term_ref(); @@ -1264,7 +1265,9 @@ PyObject *compound_to_pyeval(term_t t, functor_t fun) { /* pArg reference stolen here: */ PyTuple_SetItem(pArgs, i, pArg); } - return PyObject_CallObject(o, pArgs); + PyObject *rc; + rc = PyObject_CallObject(o, pArgs); + return rc; } else { atom_t name; int len; diff --git a/packages/python/python.h b/packages/python/python.h index 5eb42d7e5..8046b38d3 100644 --- a/packages/python/python.h +++ b/packages/python/python.h @@ -94,6 +94,8 @@ static inline PyObject *atom_to_python_string(term_t t) { extern PyObject *compound_to_pyeval(term_t t, functor_t fun); extern PyObject *compound_to_pytree(term_t t, functor_t fun); + +extern PyObject *yap_to_python(YAP_Term t, bool eval); extern PyObject *term_to_python(term_t t, bool eval); extern foreign_t python_to_ptr(PyObject *pVal, term_t t); diff --git a/packages/swig/python/setup.py.cmake b/packages/swig/python/setup.py.cmake index fd828553b..bdb24cada 100644 --- a/packages/swig/python/setup.py.cmake +++ b/packages/swig/python/setup.py.cmake @@ -14,7 +14,8 @@ setup( ext_modules=[Extension('_yap', ['yap.i'], define_macros = [('MAJOR_VERSION', '1'), ('MINOR_VERSION', '0'), - ('_YAP_NOT_INSTALLED_', '1')], + ('_YAP_NOT_INSTALLED_', '1'), + ('YAP_PYTHON', '1')], runtime_library_dirs=['${dlls}'], swig_opts=['-modern','-outcurrentdir', '-c++', '-py3','-I${CMAKE_SOURCE_DIR}/CXX'], library_dirs=['../../..','../../../CXX', diff --git a/packages/swig/yap.i b/packages/swig/yap.i index 1daa27544..fea00716d 100644 --- a/packages/swig/yap.i +++ b/packages/swig/yap.i @@ -14,51 +14,49 @@ class YAPEngine; #ifdef SWIGPYTHON -%typemap(typecheck) YAPTerm* { +%typemap(typecheck) Term* { $1 = PySequence_Check($input); } // Map a Python sequence into any sized C double array -%typemap(in) YAPTerm* { +%typemap(in) Term* { int i; if (!PySequence_Check($input)) { PyErr_SetString(PyExc_TypeError,"Expecting a sequence"); $1 = nullptr; } else { int sz = PyObject_Length($input); - std::vector v(sz); + std::vector v(sz); for (i =0; i < sz; i++) { PyObject *o = PySequence_GetItem($input,i); - v[i] = YAPTerm(pythonToYAP(o)); + v[i] = Term(pythonToYAP(o)); Py_DECREF(o); - } + } $1 = &v[0]; } } -%typemap(typecheck) YAPTerm { +%typemap(typecheck) YPTerm { $1 = true; } +%typemap(in) Term { $1 = pythonToYAP($input); } -%typemap(in) YAPTerm { $1 = YAPTerm(pythonToYAP($input)); } +%typemap(out) Term { return $result = yap_to_python($1, false);} - -%typemap(out) YAPTerm {$result = term_to_python($1.handle(), false);} - - -%extend(out) YAPTerm{YAPTerm & __getitem__(size_t i){Term t0 = $self->term(); + +%extend(out) Term{Term & __getitem__(size_t i){Term t0 = $self; if (IsApplTerm(t0)) { Functor f = FunctorOfTerm(t0); if (!IsExtensionFunctor(f)) - return *new YAPTerm(ArgOfTerm(i + 1, t0)); + return (ArgOfTerm(i + 1, t0); } else if (IsPairTerm(t0)) { if (i == 0) - return *new YAPTerm(HeadOfTerm(t0)); + return HeadOfTerm(t0); else if (i == 1) - return *new YAPTerm(TailOfTerm(t0)); + return TailOfTerm(t0); } } } diff --git a/pl/listing.yap b/pl/listing.yap index 3678f5d18..d8ac5c6d6 100644 --- a/pl/listing.yap +++ b/pl/listing.yap @@ -32,7 +32,7 @@ /** @pred listing -Lists in the current output stream all the clauses for which source code +vxuLists in the current output stream all the clauses for which source code is available (these include all clauses for dynamic predicates and clauses for static predicates compiled when source mode was `on`).