imprive python interface
This commit is contained in:
parent
683032432c
commit
3c0e16030c
@ -5,27 +5,28 @@
|
|||||||
|
|
||||||
setup_dir :-
|
setup_dir :-
|
||||||
prolog_load_context(directory, Dir),
|
prolog_load_context(directory, Dir),
|
||||||
atom_concat(Dir,'/pyx/',Base),
|
atom_concat(Dir,'pyx/',Base),
|
||||||
assert(base(Base)).
|
assert(base(Base)).
|
||||||
|
|
||||||
:- setup_dir.
|
:- setup_dir.
|
||||||
|
|
||||||
main :-
|
main :-
|
||||||
|
python_import(pyx),
|
||||||
ex(X),
|
ex(X),
|
||||||
flush_output,
|
flush_output,
|
||||||
fail.
|
fail.
|
||||||
main.
|
main.
|
||||||
|
|
||||||
ex(hello_world) :-
|
ex(hello) :-
|
||||||
c := pyx:canvas:canvas,
|
c := canvas:canvas(_),
|
||||||
:= $c:text(0, 0, 'Hello, world!'),
|
:= $c:text(0, 0, 'Hello, world!'),
|
||||||
:= $c:stroke(path:line(0, 0, 2, 0)),
|
:= $c:stroke(path:line(0, 0, 2, 0)),
|
||||||
:= $c:writePDFfile('hello').
|
:= $c:writePDFfile('hello').
|
||||||
|
|
||||||
ex(changebar) :-
|
ex(changebar) :-
|
||||||
g := pyx:graph:graphxy(width=8, x=graph:axis:bar),
|
g := graph:graphxy(width=8, x=graph:axis:bar(_)),
|
||||||
atomic_concat(Source, 'minimal.dat', Data),
|
base(Source), atomic_concat(Source, 'minimal.dat', Data),
|
||||||
:= $g:plot(graph:data:file(Data, xname=0, y=2), [graph:style:changebar]),
|
:= $g:plot(graph:data:file(Data, xname=0, y=2), [graph:style:changebar(_)]),
|
||||||
:= $g:writePDFfile(changebar).
|
:= $g:writePDFfile(changebar).
|
||||||
|
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ ex(home) :-
|
|||||||
).
|
).
|
||||||
|
|
||||||
ex(site) :-
|
ex(site) :-
|
||||||
X := site:getusersitepackages,
|
X := site:getusersitepackages(_),
|
||||||
format('site packages=~a~n',[X]).
|
format('site packages=~a~n',[X]).
|
||||||
|
|
||||||
ex(arith) :-
|
ex(arith) :-
|
||||||
@ -122,10 +122,10 @@ ex(lists) :-
|
|||||||
:= $a:remove(333),
|
:= $a:remove(333),
|
||||||
B := $a,
|
B := $a,
|
||||||
format('a=~w~n', [B]),
|
format('a=~w~n', [B]),
|
||||||
:= $a:reverse,
|
:= $a:reverse(_),
|
||||||
C := $a,
|
C := $a,
|
||||||
format('a=~w~n', [C]),
|
format('a=~w~n', [C]),
|
||||||
:= $a:sort,
|
:= $a:sort(_),
|
||||||
D := $a,
|
D := $a,
|
||||||
format('a=~w~n', [D]).
|
format('a=~w~n', [D]).
|
||||||
|
|
||||||
|
@ -43,6 +43,9 @@ static functor_t FUNCTOR_dollar1,
|
|||||||
static PyObject *py_Main;
|
static PyObject *py_Main;
|
||||||
static PyObject *term_to_python(term_t t);
|
static PyObject *term_to_python(term_t t);
|
||||||
|
|
||||||
|
static PyObject *ActiveModules[32];
|
||||||
|
static int active_modules = 0;
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
proper_ascii_string(char *s)
|
proper_ascii_string(char *s)
|
||||||
{
|
{
|
||||||
@ -67,6 +70,37 @@ get_p_int(PyObject *o, Py_ssize_t def) {
|
|||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
find_obj(PyObject *ob, term_t lhs)
|
||||||
|
{
|
||||||
|
char *s;
|
||||||
|
PyObject *out, *pName;
|
||||||
|
int arity = 0;
|
||||||
|
|
||||||
|
if (!PL_get_atom_chars(lhs, &s)) {
|
||||||
|
atom_t name;
|
||||||
|
if (!PL_get_name_arity(lhs, &name, &arity) )
|
||||||
|
return NULL;
|
||||||
|
s = PL_atom_chars(name);
|
||||||
|
}
|
||||||
|
if (ob) {
|
||||||
|
out = PyObject_GetAttrString(ob, s);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
if (!ob && !arity) {
|
||||||
|
pName = PyString_FromString(s);
|
||||||
|
if (pName == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (( out = PyImport_Import(pName))) {
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!ob && py_Main && (out = PyObject_GetAttrString(py_Main, s) ) )
|
||||||
|
return out;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
copy_to_dictionary(PyObject *dict, term_t targ, term_t taux)
|
copy_to_dictionary(PyObject *dict, term_t targ, term_t taux)
|
||||||
{
|
{
|
||||||
@ -647,6 +681,7 @@ term_to_python(term_t t)
|
|||||||
return NULL;
|
return NULL;
|
||||||
if (!PL_get_pointer(targ, &ptr))
|
if (!PL_get_pointer(targ, &ptr))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
Py_INCREF((PyObject *)ptr);
|
||||||
/* return __main__,s */
|
/* return __main__,s */
|
||||||
return (PyObject *)ptr;
|
return (PyObject *)ptr;
|
||||||
} else if (fun == FUNCTOR_abs1) {
|
} else if (fun == FUNCTOR_abs1) {
|
||||||
@ -839,6 +874,61 @@ term_to_python(term_t t)
|
|||||||
rhs = term_to_python(trhs);
|
rhs = term_to_python(trhs);
|
||||||
return PyObject_GetItem(lhs, rhs);
|
return PyObject_GetItem(lhs, rhs);
|
||||||
}
|
}
|
||||||
|
} else if (fun == FUNCTOR_colon2) {
|
||||||
|
term_t tleft = PL_new_term_ref();
|
||||||
|
PyObject *pArgs, *o;
|
||||||
|
long i;
|
||||||
|
int arity;
|
||||||
|
atom_t name;
|
||||||
|
|
||||||
|
o = NULL;
|
||||||
|
while (fun == FUNCTOR_colon2) {
|
||||||
|
if (! PL_get_arg(1, t, tleft) )
|
||||||
|
return FALSE;
|
||||||
|
o = find_obj(o, tleft);
|
||||||
|
if (!o)
|
||||||
|
return FALSE;
|
||||||
|
if (! PL_get_arg(2, t, t) )
|
||||||
|
return FALSE;
|
||||||
|
if (!PL_get_functor(t, &fun))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (! PL_get_name_arity( t, &name, &arity) ) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!arity) {
|
||||||
|
char *s;
|
||||||
|
PyObject *pValue;
|
||||||
|
|
||||||
|
if (!PL_get_atom_chars(t, &s))
|
||||||
|
return NULL;
|
||||||
|
if ((pValue = PyObject_GetAttrString(o, s)) == NULL) {
|
||||||
|
PyErr_Print();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return pValue;
|
||||||
|
}
|
||||||
|
o = PyObject_GetAttrString(o, PL_atom_chars(name));
|
||||||
|
if (!o || ! PyCallable_Check(o)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
pArgs = PyTuple_New(arity);
|
||||||
|
for (i = 0 ; i < arity; i++) {
|
||||||
|
PyObject *pArg;
|
||||||
|
if (! PL_get_arg(i+1, t, tleft) )
|
||||||
|
return NULL;
|
||||||
|
/* ignore (_) */
|
||||||
|
if (i == 0 && PL_is_variable(tleft)) {
|
||||||
|
Py_DECREF(pArgs);
|
||||||
|
pArgs = NULL;
|
||||||
|
}
|
||||||
|
pArg = term_to_python(tleft);
|
||||||
|
if (pArg == NULL)
|
||||||
|
return NULL;
|
||||||
|
/* pArg reference stolen here: */
|
||||||
|
PyTuple_SetItem(pArgs, i, pArg);
|
||||||
|
}
|
||||||
|
return PyObject_CallObject(o, pArgs);
|
||||||
} else {
|
} else {
|
||||||
atom_t name;
|
atom_t name;
|
||||||
int len;
|
int len;
|
||||||
@ -975,6 +1065,16 @@ assign_python(PyObject *root, term_t t, PyObject *e)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static foreign_t
|
||||||
|
address_to_term(PyObject *pVal, term_t t)
|
||||||
|
{
|
||||||
|
term_t to = PL_new_term_ref(), t1 = PL_new_term_ref();
|
||||||
|
PL_put_pointer(t1, (void *)pVal);
|
||||||
|
PL_cons_functor(to, FUNCTOR_pointer1, t1);
|
||||||
|
Py_INCREF(pVal);
|
||||||
|
return PL_unify(t, to);
|
||||||
|
}
|
||||||
|
|
||||||
static foreign_t
|
static foreign_t
|
||||||
python_to_term(PyObject *pVal, term_t t)
|
python_to_term(PyObject *pVal, term_t t)
|
||||||
{
|
{
|
||||||
@ -1067,11 +1167,7 @@ python_to_term(PyObject *pVal, term_t t)
|
|||||||
PL_cons_functor(to, FUNCTOR_curly1, to);
|
PL_cons_functor(to, FUNCTOR_curly1, to);
|
||||||
return PL_unify(t, to);
|
return PL_unify(t, to);
|
||||||
} else {
|
} else {
|
||||||
term_t to = PL_new_term_ref(), t1 = PL_new_term_ref();
|
return address_to_term(pVal, t);
|
||||||
PL_put_pointer(t1, (void *)pVal);
|
|
||||||
PL_cons_functor(to, FUNCTOR_pointer1, t1);
|
|
||||||
Py_INCREF(pVal);
|
|
||||||
return PL_unify(t, to);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1095,6 +1191,7 @@ python_import(term_t mname, term_t mod)
|
|||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
ActiveModules[active_modules++] = pModule;
|
||||||
return python_to_term(pModule, mod);
|
return python_to_term(pModule, mod);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1187,96 +1284,68 @@ python_is(term_t tobj, term_t tf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static foreign_t
|
static foreign_t
|
||||||
python_apply(term_t tin, term_t targs, term_t tf)
|
python_apply(term_t tin, term_t targs, term_t keywds, term_t tf)
|
||||||
{
|
{
|
||||||
PyObject *pF, *pValue;
|
PyObject *pF, *pValue;
|
||||||
PyObject *pArgs;
|
PyObject *pArgs, *pKeywords;
|
||||||
int i, arity, j;
|
int i, arity;
|
||||||
atom_t aname;
|
atom_t aname;
|
||||||
foreign_t out;
|
foreign_t out;
|
||||||
term_t targ = PL_new_term_ref();
|
term_t targ = PL_new_term_ref();
|
||||||
|
|
||||||
pF = term_to_python(tin);
|
pF = term_to_python(tin);
|
||||||
|
if (PL_is_atom(keywds) )
|
||||||
|
pKeywords = NULL;
|
||||||
|
else
|
||||||
|
pKeywords = term_to_python(keywds);
|
||||||
if ( pF == NULL ) {
|
if ( pF == NULL ) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (! PL_get_name_arity( targs, &aname, &arity) ) {
|
if (! PL_get_name_arity( targs, &aname, &arity) ) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
/* follow chains of the form a.b.c.d.e() */
|
PyObject_Print(pF,stderr,0);fprintf(stderr, "\n");
|
||||||
while (aname == ATOM_colon && arity == 2) {
|
if (aname == ATOM_t) {
|
||||||
term_t tleft = PL_new_term_ref();
|
if (arity == 0)
|
||||||
PyObject *lhs;
|
pArgs = NULL;
|
||||||
|
else
|
||||||
if (! PL_get_arg(1, targs, tleft) )
|
pArgs = term_to_python( targs );
|
||||||
|
PyObject_Print(pArgs,stderr,0);fprintf(stderr, " ");
|
||||||
|
PyObject_Print(pKeywords,stderr,0);fprintf(stderr, "\n");
|
||||||
|
} else {
|
||||||
|
pArgs = PyTuple_New(arity);
|
||||||
|
if (!pArgs)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
lhs = term_to_python(tleft);
|
for (i = 0 ; i < arity; i++) {
|
||||||
if ((pF = PyObject_GetAttr(pF, lhs)) == NULL) {
|
|
||||||
PyErr_Print();
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if (! PL_get_arg(2, targs, targs) )
|
|
||||||
return FALSE;
|
|
||||||
if (! PL_get_name_arity( targs, &aname, &arity) ) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (PyFunction_Check(pF)) {
|
|
||||||
int tuple_inited = FALSE;
|
|
||||||
PyObject *pOpt = NULL;
|
|
||||||
for (j = arity ; j > 0; j--) {
|
|
||||||
term_t tsubarg = PL_new_term_ref();
|
|
||||||
PyObject *pArg;
|
PyObject *pArg;
|
||||||
int posx;
|
if (! PL_get_arg(i+1, targs, targ) )
|
||||||
Py_ssize_t pos;
|
|
||||||
|
|
||||||
if (! PL_get_arg(j, targs, targ) )
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (! PL_is_functor(targ, FUNCTOR_equal2) )
|
/* ignore (_) */
|
||||||
|
if (i == 0 && PL_is_variable(targ)) {
|
||||||
|
Py_DECREF(pArgs);
|
||||||
|
pArgs = NULL;
|
||||||
break;
|
break;
|
||||||
if (! PL_get_arg(1, targ, tsubarg) || !PL_get_integer(tsubarg, &posx) )
|
|
||||||
break;
|
|
||||||
pos = posx;
|
|
||||||
if (!tuple_inited) {
|
|
||||||
if ((pOpt = PyFunction_GetDefaults(pF)) == NULL)
|
|
||||||
break;
|
|
||||||
tuple_inited = TRUE;
|
|
||||||
}
|
}
|
||||||
if (! PL_get_arg(2, targ, tsubarg) )
|
pArg = term_to_python(targ);
|
||||||
break;
|
|
||||||
pArg = term_to_python(tsubarg);
|
|
||||||
if (pArg == NULL)
|
if (pArg == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
/* pArg reference stolen here: */
|
/* pArg reference stolen here: */
|
||||||
PyTuple_SetItem(pOpt, pos, pArg);
|
PyTuple_SetItem(pArgs, i, pArg);
|
||||||
}
|
}
|
||||||
if (tuple_inited) {
|
|
||||||
if (PyFunction_SetDefaults(pF, pOpt) < 0) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
arity = j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pArgs = PyTuple_New(arity);
|
|
||||||
for (i = 0 ; i < arity; i++) {
|
|
||||||
PyObject *pArg;
|
|
||||||
if (! PL_get_arg(i+1, targs, targ) )
|
|
||||||
return FALSE;
|
|
||||||
pArg = term_to_python(targ);
|
|
||||||
if (pArg == NULL)
|
|
||||||
return FALSE;
|
|
||||||
/* pArg reference stolen here: */
|
|
||||||
PyTuple_SetItem(pArgs, i, pArg);
|
|
||||||
}
|
}
|
||||||
if (PyCallable_Check(pF)) {
|
if (PyCallable_Check(pF)) {
|
||||||
pValue = PyObject_CallObject(pF, pArgs);
|
if (!arity)
|
||||||
PyErr_Print();
|
pValue = PyObject_CallObject(pF, NULL);
|
||||||
|
else
|
||||||
|
pValue = PyObject_Call(pF, pArgs, pKeywords);
|
||||||
|
if (!pValue)
|
||||||
|
PyErr_Print();
|
||||||
} else {
|
} else {
|
||||||
PyErr_Print();
|
PyErr_Print();
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
PyErr_Print();
|
if (pArgs)
|
||||||
Py_DECREF(pArgs);
|
Py_DECREF(pArgs);
|
||||||
Py_DECREF(pF);
|
Py_DECREF(pF);
|
||||||
if (pValue == NULL)
|
if (pValue == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -1313,11 +1382,6 @@ python_access(term_t obj, term_t f, term_t out)
|
|||||||
PyErr_Print();
|
PyErr_Print();
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if ( PyCallable_Check(pValue) )
|
|
||||||
pValue = PyObject_CallObject(pValue, NULL);
|
|
||||||
PyErr_Print();
|
|
||||||
if (!pValue)
|
|
||||||
return FALSE;
|
|
||||||
return python_to_term(pValue, out);
|
return python_to_term(pValue, out);
|
||||||
}
|
}
|
||||||
if (! PL_get_name_arity( f, &name, &arity) ) {
|
if (! PL_get_name_arity( f, &name, &arity) ) {
|
||||||
@ -1351,6 +1415,11 @@ python_access(term_t obj, term_t f, term_t out)
|
|||||||
PyObject *pArg;
|
PyObject *pArg;
|
||||||
if (! PL_get_arg(i+1, f, targ) )
|
if (! PL_get_arg(i+1, f, targ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
/* ignore (_) */
|
||||||
|
if (i == 0 && PL_is_variable(targ)) {
|
||||||
|
Py_DECREF(pArgs);
|
||||||
|
pArgs = NULL;
|
||||||
|
}
|
||||||
pArg = term_to_python(targ);
|
pArg = term_to_python(targ);
|
||||||
if (pArg == NULL)
|
if (pArg == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -1368,6 +1437,66 @@ python_access(term_t obj, term_t f, term_t out)
|
|||||||
return python_to_term(pValue, out);
|
return python_to_term(pValue, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static foreign_t
|
||||||
|
python_field(term_t f, term_t tobj, term_t tname, term_t tout)
|
||||||
|
{
|
||||||
|
PyObject *o = NULL, *pF;
|
||||||
|
atom_t name;
|
||||||
|
char *s;
|
||||||
|
int arity;
|
||||||
|
|
||||||
|
if (! PL_get_name_arity( f, &name, &arity) ) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
/* follow chains of the form a.b.c.d.e() */
|
||||||
|
while (name == ATOM_colon && arity == 2) {
|
||||||
|
term_t tleft = PL_new_term_ref();
|
||||||
|
PyObject *lhs;
|
||||||
|
|
||||||
|
if (! PL_get_arg(1, f, tleft) )
|
||||||
|
return FALSE;
|
||||||
|
lhs = term_to_python(tleft);
|
||||||
|
if (o == NULL) {
|
||||||
|
o = lhs;
|
||||||
|
} else if ((o = PyObject_GetAttr(o, lhs)) == NULL) {
|
||||||
|
// PyErr_Print();
|
||||||
|
PyErr_Clear();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (! PL_get_arg(2, f, f) )
|
||||||
|
return FALSE;
|
||||||
|
if (! PL_get_name_arity( f, &name, &arity) ) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s = PL_atom_chars(name);
|
||||||
|
if (!s || !o) {
|
||||||
|
return FALSE;
|
||||||
|
} else if ((pF = PyObject_GetAttrString(o, s)) == NULL) {
|
||||||
|
// PyErr_Print();
|
||||||
|
PyErr_Clear();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return
|
||||||
|
address_to_term(pF, tobj) &&
|
||||||
|
PL_unify_atom(tname, name) &&
|
||||||
|
PL_unify(tout, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static foreign_t
|
||||||
|
python_main_module(term_t mod)
|
||||||
|
{
|
||||||
|
return address_to_term(py_Main, mod);
|
||||||
|
}
|
||||||
|
|
||||||
|
static foreign_t
|
||||||
|
python_function(term_t tobj)
|
||||||
|
{
|
||||||
|
PyObject *obj = term_to_python(tobj);
|
||||||
|
|
||||||
|
return PyFunction_Check(obj);
|
||||||
|
}
|
||||||
|
|
||||||
static foreign_t
|
static foreign_t
|
||||||
python_run_command(term_t cmd)
|
python_run_command(term_t cmd)
|
||||||
{
|
{
|
||||||
@ -1447,9 +1576,12 @@ install_python(void)
|
|||||||
PL_register_foreign("python_len", 2, python_len, 0);
|
PL_register_foreign("python_len", 2, python_len, 0);
|
||||||
PL_register_foreign("python_is", 2, python_is, 0);
|
PL_register_foreign("python_is", 2, python_is, 0);
|
||||||
PL_register_foreign("python_dir", 2, python_dir, 0);
|
PL_register_foreign("python_dir", 2, python_dir, 0);
|
||||||
PL_register_foreign("python_apply", 3, python_apply, 0);
|
PL_register_foreign("python_apply", 4, python_apply, 0);
|
||||||
PL_register_foreign("python_access", 3, python_access, 0);
|
PL_register_foreign("python_access", 3, python_access, 0);
|
||||||
|
PL_register_foreign("python_field", 4, python_field, 0);
|
||||||
PL_register_foreign("python_assign", 2, python_assign, 0);
|
PL_register_foreign("python_assign", 2, python_assign, 0);
|
||||||
|
PL_register_foreign("python_function", 1, python_function, 0);
|
||||||
PL_register_foreign("python_run_command", 1, python_run_command, 0);
|
PL_register_foreign("python_run_command", 1, python_run_command, 0);
|
||||||
|
PL_register_foreign("python_main_module", 1, python_main_module, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,8 +59,7 @@ Data types are
|
|||||||
:- use_module(library(lists)).
|
:- use_module(library(lists)).
|
||||||
:- use_module(library(apply_macros)).
|
:- use_module(library(apply_macros)).
|
||||||
:- use_module(library(charsio)).
|
:- use_module(library(charsio)).
|
||||||
|
:- dynamic python_mref_cache/2, python_obj_cache/2.
|
||||||
:- dynamic python_mref_cache/2.
|
|
||||||
|
|
||||||
:= F :- python(F,_).
|
:= F :- python(F,_).
|
||||||
|
|
||||||
@ -91,51 +90,127 @@ module_extend(M0, M:E, MF, EF, MRef0, MRef) :-
|
|||||||
module_extend(MM, E, MF, EF, MRef1, MRef).
|
module_extend(MM, E, MF, EF, MRef1, MRef).
|
||||||
module_extend(M, E, M, E, MRef, MRef).
|
module_extend(M, E, M, E, MRef, MRef).
|
||||||
|
|
||||||
% given an object, detect its len method
|
object_prefix('__obj__'(_)).
|
||||||
python_eval_term(Expression, O) :-
|
object_prefix('$'(_)).
|
||||||
fetch_module(Expression, Module, Exp, MRef), !,
|
object_prefix('__obj__'(_):_).
|
||||||
|
object_prefix('$'(_):_).
|
||||||
|
|
||||||
|
% from an exp take an object, and its corresponding Prolog representation
|
||||||
|
descend_exp(V, _Obj, _F, _S) :-
|
||||||
|
var(V), !,
|
||||||
|
throw(error(instantiation_error,_)).
|
||||||
|
descend_exp(Exp, Obj, F, S) :-
|
||||||
|
object_prefix(Exp),
|
||||||
|
!,
|
||||||
|
python_field(Exp, Obj, F, S).
|
||||||
|
descend_exp(Exp, Obj, F, S) :-
|
||||||
|
python_mref_cache(_, MObj),
|
||||||
|
python_field(MObj:Exp, Obj, F, S), !.
|
||||||
|
descend_exp(Mod:Exp, Obj, F, S) :-
|
||||||
|
atom(Mod),
|
||||||
|
python_import(Mod, MObj),
|
||||||
|
python_field(MObj:Exp, Obj, F, S), !.
|
||||||
|
|
||||||
|
python_class(Obj) :-
|
||||||
|
python_obj_cache(inspect:isclass(_), F),
|
||||||
|
python_apply(F, isclass(Obj), {}, true).
|
||||||
|
|
||||||
|
process_obj(Obj, _, S, Obj, NS, Dict) :-
|
||||||
|
python_callable(Obj), !,
|
||||||
|
python_check_args(Obj, Obj, S, NS, Dict).
|
||||||
|
process_obj(Obj, _, S, Obj, NS, Dict) :-
|
||||||
|
python_class(Obj),
|
||||||
|
descend_object(Obj:'__init__', FObj, _, _),
|
||||||
|
python_check_args(Obj, FObj, S, NS, Dict).
|
||||||
|
|
||||||
|
python_eval_term(Obj, Obj) :-
|
||||||
|
var(Obj), !.
|
||||||
|
python_eval_term('__obj__'(Obj), '__obj__'(Obj)) :- !.
|
||||||
|
python_eval_term($Name, Obj) :- !,
|
||||||
|
python_is($Name, Obj).
|
||||||
|
python_eval_term([H|T], [NH|NT]) :- !,
|
||||||
|
python_eval_term(H, NH),
|
||||||
|
python_eval_term(T, NT).
|
||||||
|
python_eval_term(N, N) :- atomic(N), !.
|
||||||
|
python_eval_term(Exp, O) :-
|
||||||
|
descend_exp(Exp, Obj, Old, S), !,
|
||||||
(
|
(
|
||||||
% avoid looking at : as field of module.
|
python_function(Obj)
|
||||||
Exp = Obj:Field
|
|
||||||
->
|
->
|
||||||
python_access(MRef, Exp, O)
|
python_check_args(Obj, Obj, S, NS, Dict),
|
||||||
|
python_apply(Ob, NS, Dict, O)
|
||||||
;
|
;
|
||||||
functor(Exp, F, _),
|
descend_exp(Obj:im_func, FObj, _, _)
|
||||||
python_f(MRef, F, FRef),
|
|
||||||
python_check_args(FRef, Exp, NExp)
|
|
||||||
->
|
->
|
||||||
python_apply(FRef, NExp, O)
|
python_check_args(FObj, Obj, S, NS, Dict),
|
||||||
;
|
python_apply(Obj, NS, Dict, O)
|
||||||
python_access(MRef, Exp, O)
|
;
|
||||||
|
descend_exp(Obj:'__init__':im_func, FObj, _, _)
|
||||||
|
->
|
||||||
|
python_check_args(FObj, Obj, S, NS, Dict),
|
||||||
|
python_apply(Obj, NS, Dict, O)
|
||||||
|
;
|
||||||
|
python_check_args('.', '.', S, NS, {}),
|
||||||
|
python_is(NS, O)
|
||||||
).
|
).
|
||||||
python_eval_term(Obj:Field, O) :- !,
|
python_eval_term(S, O) :-
|
||||||
python_access(Obj, Field, O).
|
python_check_args('.', '.', S, NS, {}),
|
||||||
python_eval_term(Obj, O) :-
|
python_is(NS, O).
|
||||||
python_is(Obj, O).
|
|
||||||
|
|
||||||
|
python_check_args(_FRef, _Ref, Exp, t, {}) :-
|
||||||
python_check_args(FRef, Exp, NExp) :-
|
Exp =.. [_,V], var(V), !.
|
||||||
|
python_check_args(FRef, Ref, Exp, NExp, Dict) :-
|
||||||
functor(Exp, _, Arity),
|
functor(Exp, _, Arity),
|
||||||
arg(Arity, Exp, _=_), !,
|
arg(Arity, Exp, A), nonvar(A), A = (_=_), !,
|
||||||
fetch_args(FRef, Dict),
|
fetch_args(FRef, ArgNames0, Kwd, Defaults),
|
||||||
Exp =.. [F|LArgs],
|
Exp =.. [_F|LArgs],
|
||||||
match_args(LArgs, Dict, NLArgs, _),
|
Defaults =.. [t|DefsL],
|
||||||
NExp =.. [F|NLArgs].
|
splice_class(FRef, Ref, ArgNames0, ArgNames),
|
||||||
python_check_args(FRef, Exp, Exp).
|
match_args(LArgs, ArgNames, DefsL, NLArgs, Dict),
|
||||||
|
NExp =.. [t|NLArgs].
|
||||||
|
python_check_args(FRef, _, Exp, NExp, {}) :-
|
||||||
|
Exp =.. [F|L],
|
||||||
|
maplist(python_eval_term, L, LF),
|
||||||
|
NExp =.. [F|LF].
|
||||||
|
|
||||||
fetch_args(FRef, Args) :-
|
% in case it is __init__ from __new__
|
||||||
python_import('inspect', M),
|
splice_class(Ref, Ref, ArgNames, ArgNames) :- !.
|
||||||
python_f(M, getargspec, F),
|
splice_class(_FRef, _Ref, [_|ArgNames], ArgNames).
|
||||||
python_apply(F, getargspec(FRef), Args),
|
|
||||||
ExtraArgs=t(Args, _, _, _).
|
match_args([], _ArgNames, _Defaults, [], {}).
|
||||||
|
match_args([V=A|LArgs], ArgNames, Defaults, NLArgs, Dict) :- !,
|
||||||
|
match_named_args([V=A|LArgs], ArgNames, Defaults, NLArgs, Map),
|
||||||
|
map_to_dict(Map, Dict).
|
||||||
|
match_args([A|LArgs], [_|ArgNames], [_|Defaults], [VA|NLArgs], Dict) :-
|
||||||
|
python_eval_term(A, VA),
|
||||||
|
match_args(LArgs, ArgNames, Defaults, NLArgs, Dict).
|
||||||
|
|
||||||
|
match_named_args([], _ArgNames, Defaults, Defaults, []).
|
||||||
|
match_named_args([K=A|LArgs], ArgNames, Defaults, NLArgs, Map) :-
|
||||||
|
match_from_anames(ArgNames, K, VA, Defaults, NDefaults), !,
|
||||||
|
python_eval_term(A, VA),
|
||||||
|
match_named_args(LArgs, ArgNames, NDefaults, NLArgs, Map).
|
||||||
|
match_named_args([K=A|LArgs], ArgNames, Defaults, NLArgs, [K=VA|Map]) :-
|
||||||
|
python_eval_term(A, VA),
|
||||||
|
match_named_args(LArgs, ArgNames, Defaults, NLArgs, Map).
|
||||||
|
|
||||||
|
|
||||||
match_args([], _, [], ok).
|
map_to_dict([X=V], {X:V}) :- !.
|
||||||
match_args([A=V|LArgs], Dict, [I=V|NLArgs], OK) :-
|
map_to_dict([X=V|Map], {X:V,NDict}) :-
|
||||||
match_args(LArgs, Dict, NLArgs, ok), !,
|
map_to_dict(Map, {NDict}).
|
||||||
( nth0(I, Dict, A) -> true ; throw(type_error(argument(A=V))) ).
|
|
||||||
match_args([A|LArgs], Dict, [A|NLArgs], not_ok) :-
|
match_from_anames([K|_ArgNames], K, VA, [_|Defaults], [VA|Defaults]) :- !.
|
||||||
match_args(LArgs, Dict, NLArgs, _).
|
match_from_anames([_|ArgNames], K, VA, [V|Defaults], [V|NDefaults]) :-
|
||||||
|
match_from_anames(ArgNames, K, VA, Defaults, NDefaults).
|
||||||
|
|
||||||
|
fetch_args(FRef, Args, Kwd, Defaults) :-
|
||||||
|
FRef = '__obj__'(_), !,
|
||||||
|
python_mref_cache('inspect', M),
|
||||||
|
python_obj_cache(inspect:getargspec(_), F),
|
||||||
|
python_apply(F, getargspec(FRef), {}, ExtraArgs),
|
||||||
|
ExtraArgs=t(Args, _, Kwd, Defaults).
|
||||||
|
fetch_args(_, []).
|
||||||
|
|
||||||
|
|
||||||
python(Obj, Out) :-
|
python(Obj, Out) :-
|
||||||
python_eval_term(Obj, Out).
|
python_eval_term(Obj, Out).
|
||||||
@ -146,8 +221,15 @@ python_command(Cmd) :-
|
|||||||
start_python :-
|
start_python :-
|
||||||
use_foreign_library(foreign(python)),
|
use_foreign_library(foreign(python)),
|
||||||
init_python,
|
init_python,
|
||||||
|
python_main_module(MRef),
|
||||||
|
assert(python_mref_cache('__main__', MRef)),
|
||||||
python_command('import sys'),
|
python_command('import sys'),
|
||||||
python_command('import inspect').
|
python_import('inspect'),
|
||||||
|
python_mref_cache(inspect, InspRef),
|
||||||
|
python_field(InspRef:isclass(_), IsClass, _, _),
|
||||||
|
assert(python_obj_cache(inspect:isclass(_), IsClass)),
|
||||||
|
python_field(InspRef:getargspec(_), GetArgSpec, _, _),
|
||||||
|
assert(python_obj_cache(inspect:getargspec(_), GetArgSpec)).
|
||||||
|
|
||||||
add_cwd_to_python :-
|
add_cwd_to_python :-
|
||||||
unix(getcwd(Dir)),
|
unix(getcwd(Dir)),
|
||||||
|
Reference in New Issue
Block a user