This commit is contained in:
Vitor Santos Costa 2018-07-23 17:13:51 +01:00
parent b4201dd0f3
commit bac1b63080
13 changed files with 123 additions and 79 deletions

View File

@ -17,6 +17,7 @@
#include "absmi.h" #include "absmi.h"
#include "yapio.h" #include "yapio.h"
#include "YapStreams.h"
#if HAVE_STDARG_H #if HAVE_STDARG_H
#include <stdarg.h> #include <stdarg.h>
#endif #endif

View File

@ -265,4 +265,13 @@ typedef struct stream_desc {
encoding_t encoding; /** current encoding for stream */ encoding_t encoding; /** current encoding for stream */
} StreamDesc; } StreamDesc;
extern bool Yap_set_stream_to_buf(StreamDesc *st, const char *bufi,
size_t nchars
#ifdef USES_REGS
USES_REGS
#endif
);
#endif #endif

View File

@ -221,8 +221,9 @@ X_API int PL_get_nchars(term_t l, size_t *lengthp, char **s, unsigned flags) {
if (s) { if (s) {
size_t len = strlen(out.val.c); size_t len = strlen(out.val.c);
if (flags & (BUF_DISCARDABLE | BUF_RING)) { if (flags & (BUF_DISCARDABLE | BUF_RING)) {
strncpy(LOCAL_FileNameBuf, out.val.c, YAP_FILENAME_MAX); if (!*s)
*s = LOCAL_FileNameBuf; *s = LOCAL_FileNameBuf;
strncpy(*s, out.val.c, YAP_FILENAME_MAX);
pop_text_stack(lvl); pop_text_stack(lvl);
return true; return true;
} }

View File

@ -22,8 +22,6 @@
#undef HAVE_LIBREADLINE #undef HAVE_LIBREADLINE
#endif #endif
#include "YapStreams.h"
#include <stdio.h> #include <stdio.h>
#include <wchar.h> #include <wchar.h>
@ -196,9 +194,5 @@ extern uint64_t Yap_StartOfWTimes;
extern bool Yap_HandleSIGINT(void); extern bool Yap_HandleSIGINT(void);
extern bool Yap_set_stream_to_buf(StreamDesc *st, const char *bufi,
size_t nchars USES_REGS);
#endif #endif

View File

@ -558,7 +558,7 @@ term_t t0 = python_acquire_GIL();
*s++ = '.'; *s++ = '.';
s[0] = '\0'; s[0] = '\0';
} else if (!PL_get_nchars(mname, &len, &s, } else if (!PL_get_nchars(mname, &len, &s,
CVT_ATOM | CVT_EXCEPTION | REP_UTF8)) { CVT_ATOM | CVT_STRING| CVT_EXCEPTION | REP_UTF8)) {
python_release_GIL(t0); python_release_GIL(t0);
pyErrorAndReturn(false, false); pyErrorAndReturn(false, false);
} else { } else {

View File

@ -1,7 +1,14 @@
#undef PASS_REGS
#undef USES_REGS
#ifndef PY4YAP_H #ifndef PY4YAP_H
#define PY4YAP_H 1 #define PY4YAP_H 1
#define PASS_REGS
#define USES_REGSg
//@{ //@{
/** @brief Prolog to Python library /** @brief Prolog to Python library

View File

@ -710,10 +710,9 @@ static bool legal_symbol(const char *s) {
} }
PyObject *term_to_nametuple(const char *s, arity_t arity, PyObject *tuple) { PyObject *term_to_nametuple(const char *s, arity_t arity, PyObject *tuple) {
PyObject *o, *d = NULL;
if (legal_symbol(s)) { if (legal_symbol(s)) {
PyTypeObject *typp; PyTypeObject *typp;
PyObject *key = PyUnicode_FromString(s); PyObject *key = PyUnicode_FromString(s), *d;
if (Py_f2p && (d = PyList_GetItem(Py_f2p, arity)) && if (Py_f2p && (d = PyList_GetItem(Py_f2p, arity)) &&
PyDict_Contains(d, key)) { PyDict_Contains(d, key)) {
typp = (PyTypeObject *)PyDict_GetItem(d, key); typp = (PyTypeObject *)PyDict_GetItem(d, key);
@ -737,10 +736,10 @@ PyObject *term_to_nametuple(const char *s, arity_t arity, PyObject *tuple) {
// PyModule_AddGObject(py_Main, s, (PyObject *)typp); // PyModule_AddGObject(py_Main, s, (PyObject *)typp);
if (d && !PyDict_Contains(d, key)) if (d && !PyDict_Contains(d, key))
PyDict_SetItem(d, key, (PyObject *)typp); PyDict_SetItem(d, key, (PyObject *)typp);
Py_DECREF(key); Py_INCREF(key);
Py_INCREF(typp); Py_INCREF(typp);
} }
o = PyStructSequence_New(typp); PyObject *o = PyStructSequence_New(typp);
Py_INCREF(typp); Py_INCREF(typp);
arity_t i; arity_t i;
for (i = 0; i < arity; i++) { for (i = 0; i < arity; i++) {

View File

@ -1,4 +1,6 @@
#include "Yap.h"
#include "py4yap.h" #include "py4yap.h"
PyObject *py_Main; PyObject *py_Main;
@ -544,36 +546,46 @@ static int python_import(term_t mname, term_t mod) {
PyObject *pName; PyObject *pName;
bool do_as = false; bool do_as = false;
term_t arg = PL_new_term_ref(); char s0[MAXPATHLEN], *s = s0;
char s0[MAXPATHLEN], *s = s0, *t; const char*sn;
functor_t f; Term t = Deref(ARG1), sm;
while (true) { if (IsApplTerm(t)) {
size_t len; Functor f = FunctorOfTerm(t);
//PyErr_Clear(); if (f != Yap_MkFunctor(Yap_LookupAtom("as"),2))
len = (MAXPATHLEN - 1) - (s - s0); return false;
if (PL_is_pair(mname)) { do_as = true;
char *sa = NULL; sm = ArgOfTerm(2,t);
if (!PL_get_arg(1, mname, arg) || !PL_get_chars(arg, &sa, CVT_ALL | CVT_EXCEPTION | REP_UTF8) || if (IsAtomTerm(sm))
!PL_get_arg(2, mname, mname)) { sn = RepAtom(AtomOfTerm(sm))->StrOfAE;
pyErrorAndReturn(false); else if (IsStringTerm(sm))
} sn = StringOfTerm(sm);
PL_get_chars(arg, &sa, CVT_ALL | CVT_EXCEPTION | REP_UTF8); else
strcpy(s, sa); return false;
s += strlen(s);
*s++ = '.';
s[0] = '\0';
} else if (PL_get_functor(mname, &f) && f == FUNCTOR_as2 && PL_get_arg(2, mname,arg) &&
PL_get_chars(arg, &t, CVT_ALL | CVT_EXCEPTION | REP_UTF8)) {
do_as = true;
PL_get_arg(1, mname,mname);
} else if (!PL_get_nchars(mname, &len, &s,
CVT_ALL | CVT_EXCEPTION | REP_UTF8)) {
pyErrorAndReturn(false);
} else {
break;
}
} }
term_t t0 = python_acquire_GIL(); while (IsPairTerm(t)) {
Term ti = HeadOfTerm(t);
Term t2 = TailOfTerm(t);
if (IsAtomTerm(ti))
sn = RepAtom(AtomOfTerm(ti))->StrOfAE;
else if (IsStringTerm(ti))
sn = StringOfTerm(ti);
else
return false;
strcat(s,sn);
if (IsPairTerm(t2)) {
strcat(s,".");
continue;
}
sm = ArgOfTerm(2,t);
}
sm = t;
if (IsAtomTerm(sm))
sn = RepAtom(AtomOfTerm(sm))->StrOfAE;
else if (IsStringTerm(sm))
sn = StringOfTerm(sm);
else
return false;
term_t t0 = python_acquire_GIL();
#if PY_MAJOR_VERSION < 3 #if PY_MAJOR_VERSION < 3
pName = PyString_FromString(s0); pName = PyString_FromString(s0);
#else #else
@ -595,7 +607,7 @@ static int python_import(term_t mname, term_t mod) {
{ {
foreign_t rc = address_to_term(pModule, mod); foreign_t rc = address_to_term(pModule, mod);
if (do_as && PyObject_SetAttrString(py_Main, t, pModule) <0) if (do_as && PyObject_SetAttrString(py_Main, sn, pModule) <0)
return false; return false;
python_release_GIL(t0); python_release_GIL(t0);
pyErrorAndReturn(rc); pyErrorAndReturn(rc);

View File

@ -3,6 +3,8 @@
#include "py4yap.h" #include "py4yap.h"
#include <VFS.h> #include <VFS.h>
#define USES_REGS
#include "YapStreams.h" #include "YapStreams.h"
atom_t ATOM_true, ATOM_false, ATOM_colon, ATOM_dot, ATOM_none, ATOM_t, atom_t ATOM_true, ATOM_false, ATOM_colon, ATOM_dot, ATOM_none, ATOM_t,

View File

@ -71,21 +71,20 @@ argi(N,I,I1) :-
python_query( Caller, String ) :- python_query( Caller, String ) :-
atomic_to_term( String, Goal, VarNames ), atomic_to_term( String, Goal, VarNames ),
query_to_answer( Goal, VarNames, Status, Bindings), query_to_answer( Goal, VarNames, Status, Bindings),
atom_to_string( Status, SStatus ), Caller.port := Status,
% Caller.port := SStatus,
write_query_answer( Bindings ), write_query_answer( Bindings ),
nl(user_error), nl(user_error),
Caller.answer := {}, Caller.answer := {},
maplist(in_dict(Caller.answer), Bindings). maplist(in_dict(Caller.answer), Bindings).
in_dict(Dict, var([V0,V|Vs])) :- !, in_dict(Dict, var([V0,V|Vs])) :- !,
Dict[V] := V0, Dict[V] := V0,
in_dict( Dict, var([V0|Vs])). in_dict( Dict, var([V0|Vs])).
in_dict(_Dict, var([_],_G)) :- !. in_dict(_Dict, var([_],_G)) :- !.
in_dict(Dict, nonvar([V0|Vs],G)) :- !, in_dict(Dict, nonvar([V0|Vs],G)) :- !,
Dict[V0] := G, term_to_atom(G,A,_),
Dict[V0] := A,
in_dict( Dict, nonvar(Vs, G) ). in_dict( Dict, nonvar(Vs, G) ).
in_dict(_Dict, nonvar([],_G)) :- !. in_dict(_Dict, nonvar([],_G)) :- !.
in_dict(_, _) in_dict(_, _)

View File

@ -287,12 +287,6 @@ set(FILES ${PYTHON_SOURCES} ${PL_SOURCES} ${EXTRAS} ${RESOURCES})
set(SETUP_PY ${CMAKE_CURRENT_BINARY_DIR}/setup.py) set(SETUP_PY ${CMAKE_CURRENT_BINARY_DIR}/setup.py)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/yap.tgz
COMMAND ${CMAKE_COMMAND} -E tar czf ${CMAKE_CURRENT_BINARY_DIR}/yap.tgz ${FILES}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS ${FILES}
)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/yap_kernel/resources/logo-32x32.png add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/yap_kernel/resources/logo-32x32.png
COMMAND ${CMAKE_COMMAND} -E make_directory yap_kernel/resources COMMAND ${CMAKE_COMMAND} -E make_directory yap_kernel/resources
@ -315,16 +309,23 @@ add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/yap_kernel/resources/prolo
DEPENDS ${CMAKE_SOURCE_DIR}/misc/editors/yap.js DEPENDS ${CMAKE_SOURCE_DIR}/misc/editors/yap.js
) )
foreach(f ${FILES})
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${f}
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/${f} ${CMAKE_CURRENT_BINARY_DIR}/${f}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${f}
)
list(APPEND OUTS ${CMAKE_CURRENT_BINARY_DIR}/${f} )
endforeach()
add_custom_target(YAP_KERNEL ALL add_custom_target(YAP_KERNEL ALL
COMMAND ${CMAKE_COMMAND} -E tar xzf ${CMAKE_CURRENT_BINARY_DIR}/yap.tgz COMMAND ${PYTHON_EXECUTABLE} ${SETUP_PY} build sdist bdist
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/yap_kernel/resources/logo-32x32.png ${CMAKE_CURRENT_BINARY_DIR}/yap_kernel/resources/logo-64x64.png yap.tgz ${CMAKE_CURRENT_BINARY_DIR}/yap_kernel/resources/kernel.js ${CMAKE_CURRENT_BINARY_DIR}/yap_kernel/resources/prolog.js ${CMAKE_CURRENT_BINARY_DIR}/yap.tgz DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/yap_kernel/resources/logo-32x32.png ${CMAKE_CURRENT_BINARY_DIR}/yap_kernel/resources/logo-64x64.png ${CMAKE_CURRENT_BINARY_DIR}/yap_kernel/resources/kernel.js ${CMAKE_CURRENT_BINARY_DIR}/yap_kernel/resources/prolog.js ${OUTS}
) )
install(CODE "execute_process( install(CODE "execute_process(
COMMAND ${PYTHON_EXECUTABLE} ${SETUP_PY} build sdist bdist COMMAND ${PYTHON_EXECUTABLE} -m pip install ${PYTHON_USER_INSTALL} --ignore-installed --no-deps .
COMMAND ${PYTHON_EXECUTABLE} -m pip install ${PYTHON_USER_INSTALL} --ignore-installed --no-deps .
COMMAND ${PYTHON_EXECUTABLE} -m yap_kernel.kernelspec COMMAND ${PYTHON_EXECUTABLE} -m yap_kernel.kernelspec
ERROR_VARIABLE setupErr ERROR_VARIABLE setupErr
OUTPUT_VARIABLE setupOut OUTPUT_VARIABLE setupOut

View File

@ -33,14 +33,14 @@ jupyter_query(Caller, Cell, Line ) :-
jupyter_cell(_Caller, Cell, _Line) :- jupyter_cell(_Caller, Cell, _Line) :-
jupyter_consult(Cell), %stack_dump, jupyter_consult(Cell), %stack_dump,
fail. fail.
jupyter_cell( _Caller, _, `` ) :- !. jupyter_cell( _Caller, _, ¨¨ ) :- !.
jupyter_cell( _Caller, _, Line ) :- jupyter_cell( _Caller, _, Line ) :-
blank( Line ), blank( Line ),
!. !.
jupyter_cell(Caller, _, Line ) :- jupyter_cell(Caller, _, Line ) :-
Self := Caller.query, Query = Caller,
catch( catch(
python_query(Self,Line), python_query(Query,Line),
E=error(A,B), E=error(A,B),
system_error(A,B) system_error(A,B)
). ).

View File

@ -16,6 +16,7 @@ from yap_ipython.core.interactiveshell import *
from yap_ipython.core import interactiveshell from yap_ipython.core import interactiveshell
from collections import namedtuple from collections import namedtuple
import traceback
use_module = namedtuple('use_module', 'file') use_module = namedtuple('use_module', 'file')
bindvars = namedtuple('bindvars', 'list') bindvars = namedtuple('bindvars', 'list')
@ -516,13 +517,22 @@ class YAPRun:
self.query = None self.query = None
self.os = None self.os = None
self.it = None self.it = None
self.port = None
self.answers = None
self.bindings = dicts = []
self.shell.yapeng = self.yapeng self.shell.yapeng = self.yapeng
self._get_exc_info = shell._get_exc_info self._get_exc_info = shell._get_exc_info
def showtraceback(self, tuple): def showtraceback(self, exc_info):
return None try:
(etype, value, tb) = e
traceback.print_exception(etype, value, tb)
except:
print(e)
pass
def syntaxErrors(self, text): def syntaxErrors(self, text):
"""Return whether a legal query """Return whether a legal query
""" """
@ -545,28 +555,34 @@ class YAPRun:
# sys.settrace(tracefunc) # sys.settrace(tracefunc)
if self.query and self.os == program+squery: if self.query and self.os == program+squery:
howmany += self.iterations howmany += self.iterations
found = howmany != 0
else: else:
if self.query: if self.query:
self.query.close() self.query.close()
self.query = None
self.port = None
self.answers = None
self.os = program+squery self.os = program+squery
self.iterations = 0 self.iterations = 0
self.bindings = []
pg = jupyter_query( self, program, squery) pg = jupyter_query( self, program, squery)
self.query = self.yapeng.query(pg) self.query = self.yapeng.query(pg)
self.query.answer = {} self.answers = []
self.port = "call"
self.answer = {}
while self.query.next(): while self.query.next():
answer = self.query.answer #sys.stderr.write('B '+str( self.answer) +'\n')
#sys.stderr.write('C '+ str(self.port) +'\n'+'\n')
found = True found = True
self.bindings += [answer] self.answers += [self.answer]
self.iterations += 1 self.iterations += 1
if self.query.port == "exit": if self.port == "exit":
self.os = None self.os = None
sys.stderr.writeln('Done, with', self.bindings) sys.stderr.write('Done, with'+str(self.answers)+'\n')
return True,self.bindings return True,self.bindings
if stop or howmany == self.iterations: if stop or howmany == self.iterations:
return True, self.bindings return True, self.answers
if found: if found:
sys.stderr.writeln('Done, with ', self.bindings) sys.stderr.write('Done, with '+str(self.answers)+'\n')
else: else:
self.os = None self.os = None
self.query.close() self.query.close()
@ -574,7 +590,7 @@ class YAPRun:
sys.stderr.write('Fail\n') sys.stderr.write('Fail\n')
return True,self.bindings return True,self.bindings
except Exception as e: except Exception as e:
sys.stderr.write('Exception after', self.bindings, '\n') sys.stderr.write('Exception '+str(e)+' after '+str( self.bindings)+ '\n')
has_raised = True has_raised = True
return False,[] return False,[]
@ -660,7 +676,7 @@ class YAPRun:
for i in self.syntaxErrors(raw_cell): for i in self.syntaxErrors(raw_cell):
try: try:
(what,lin,_,text) = i (what,lin,_,text) = i
e = SyntaxError(what, ("<string>", lin, 1, text)) e = SyntaxError(what, ("<string>", lin, 1, text+'\n'))
raise e raise e
except SyntaxError: except SyntaxError:
self.shell.showsyntaxerror( ) self.shell.showsyntaxerror( )
@ -712,7 +728,6 @@ class YAPRun:
has_raised = False has_raised = False
try: try:
self.yapeng.mgoal(streams(True),"user", True) self.yapeng.mgoal(streams(True),"user", True)
self.bindings = dicts = []
if cell.strip('\n \t'): if cell.strip('\n \t'):
#create a Trace object, telling it what to ignore, and whether to #create a Trace object, telling it what to ignore, and whether to
# do tracing or line-counting or both. # do tracing or line-counting or both.
@ -731,14 +746,17 @@ class YAPRun:
self.jupyter_query( cell ) self.jupyter_query( cell )
# state = tracer.runfunc(jupyter_query( self, cell ) ) # state = tracer.runfunc(jupyter_query( self, cell ) )
self.shell.last_execution_succeeded = True self.shell.last_execution_succeeded = True
self.result.result = (True, dicts)
except Exception as e: except Exception as e:
has_raised = True has_raised = True
self.result.result = False self.result.result = False
self.yapeng.mgoal(streams(False),"user", True) try:
(etype, value, tb) = e
traceback.print_exception(etype, value, tb)
except:
print(e)
pass
self.yapeng.mgoal(streams(False),"user", True)
self.shell.last_execution_succeeded = not has_raised self.shell.last_execution_succeeded = not has_raised
# Reset this so later displayed values do not modify the # Reset this so later displayed values do not modify the
@ -755,6 +773,7 @@ class YAPRun:
# Each cell is a *single* input, regardless of how many lines it has # Each cell is a *single* input, regardless of how many lines it has
self.shell.execution_count += 1 self.shell.execution_count += 1
self.yapeng.mgoal(streams(False),"user", True)
return self.result return self.result
def clean_end(self,s): def clean_end(self,s):
@ -796,7 +815,7 @@ class YAPRun:
last line if the last line is non-empty and does not terminate last line if the last line is non-empty and does not terminate
on a dot. You can also finish with on a dot. You can also finish with
- `;`: you request all solutions - `*`: you request all solutions
- ';'[N]: you want an answer; optionally you want N answers - ';'[N]: you want an answer; optionally you want N answers
If the line terminates on a `*/` or starts on a `%` we assume the line If the line terminates on a `*/` or starts on a `%` we assume the line