// parse a term representing argument types - types can be a list // as accepted by get_types_list() above or the atom 'any' static int get_types(term_t types, char *buffer, int len, char **typespec) { if (PL_is_list(types)) { *typespec=buffer; return get_types_list(types,buffer,len); } else if (PL_is_atom(types)) { char *a; PL_get_atom_chars(types,&a); if (strcmp(a,"any")==0) { *typespec=NULL; return TRUE; } else return type_error(types,"list or 'any'"); } else return type_error(types,"list or 'any'"); }
static int init_prolog_goal(prolog_goal *g, term_t goal, int acknowledge) { term_t plain = PL_new_term_ref(); g->module = NULL; g->acknowledge = acknowledge; g->state = G_WAITING; if ( !PL_strip_module(goal, &g->module, plain) ) return FALSE; if ( !(PL_is_compound(plain) || PL_is_atom(plain)) ) return type_error(goal, "callable"); g->goal = PL_record(plain); return TRUE; }
static foreign_t python_f(term_t tmod, term_t fname, term_t tf) { char *s; size_t len; PyObject *pF, *pModule; /* if an atom, fetch again */ if (PL_is_atom(tmod)) { PyObject *pName; if (!PL_get_nchars(fname, &len, &s, CVT_ALL | CVT_EXCEPTION)) { return FALSE; } #if PY_MAJOR_VERSION < 3 pName = PyString_FromString(s); #else pName = PyUnicode_FromString(s); #endif if (pName == NULL) { { return false; } } pModule = PyImport_Import(pName); PyErr_Clear(); } else if (!(pModule = term_to_python(tmod, true))) { PyErr_Clear(); { return false; } } if (!PL_get_nchars(fname, &len, &s, CVT_ALL | CVT_EXCEPTION)) { { return false; } } pF = PyObject_GetAttrString(pModule, s); PyErr_Print(); Py_DECREF(pModule); if (pF == NULL || !PyCallable_Check(pF)) { { return false; } } { foreign_t rc = python_to_ptr(pF, tf); return rc; } }
static void rewrite_callable(atom_t *expected, term_t actual) { GET_LD term_t a = 0; int loops = 0; while ( PL_is_functor(actual, FUNCTOR_colon2) ) { if ( !a ) a = PL_new_term_ref(); _PL_get_arg(1, actual, a); if ( !PL_is_atom(a) ) { *expected = ATOM_atom; PL_put_term(actual, a); return; } else { _PL_get_arg(2, actual, a); PL_put_term(actual, a); } if ( ++loops > 100 && !PL_is_acyclic(actual) ) break; } }
word pl_current_functor(term_t name, term_t arity, control_t h) { GET_LD atom_t nm = 0; size_t index; int i, last=FALSE; int ar; fid_t fid; switch( ForeignControl(h) ) { case FRG_FIRST_CALL: if ( PL_get_atom(name, &nm) && PL_get_integer(arity, &ar) ) return isCurrentFunctor(nm, ar) ? TRUE : FALSE; if ( !(PL_is_integer(arity) || PL_is_variable(arity)) ) return PL_error("current_functor", 2, NULL, ERR_DOMAIN, ATOM_integer, arity); if ( !(PL_is_atom(name) || PL_is_variable(name)) ) return PL_error("current_functor", 2, NULL, ERR_DOMAIN, ATOM_atom, name); index = 1; break; case FRG_REDO: PL_get_atom(name, &nm); index = ForeignContextInt(h); break; case FRG_CUTTED: default: succeed; } fid = PL_open_foreign_frame(); LOCK(); for(i=MSB(index); !last; i++) { size_t upto = (size_t)2<<i; FunctorDef *b = GD->functors.array.blocks[i]; if ( upto >= GD->functors.highest ) { upto = GD->functors.highest; last = TRUE; } for(; index<upto; index++) { FunctorDef fd = b[index]; if ( fd && fd->arity > 0 && (!nm || nm == fd->name) ) { if ( PL_unify_atom(name, fd->name) && PL_unify_integer(arity, fd->arity) ) { UNLOCK(); ForeignRedoInt(index+1); } else { PL_rewind_foreign_frame(fid); } } } } UNLOCK(); return FALSE; }
static foreign_t python_access(term_t obj, term_t f, term_t out) { PyObject *o = term_to_python(obj, true), *pValue, *pArgs, *pF; atom_t name; char *s; int i, arity; term_t targ = PL_new_term_ref(); if (o == NULL) { return false; } if (PL_is_atom(f)) { if (!PL_get_atom_chars(f, &s)) { return false; } if ((pValue = PyObject_GetAttrString(o, s)) == NULL) { PyErr_Print(); { return false; } } { return python_to_term(pValue, out); } } if (!PL_get_name_arity(f, &name, &arity)) { { return false; } } /* follow chains of the form a.b.c.d.e() */ while (name == ATOM_dot && 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, true); if ((o = PyObject_GetAttr(o, lhs)) == NULL) { PyErr_Print(); { 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) { return false; } if ((pF = PyObject_GetAttrString(o, s)) == NULL) { PyErr_Print(); { return false; } } pArgs = PyTuple_New(arity); for (i = 0; i < arity; i++) { PyObject *pArg; if (!PL_get_arg(i + 1, f, targ)) { return false; } /* ignore (_) */ if (i == 0 && PL_is_variable(targ)) { pArgs = Py_None; } pArg = term_to_python(targ, true); if (pArg == NULL) { return false; } /* pArg reference stolen here: */ PyTuple_SetItem(pArgs, i, pArg); } pValue = PyObject_CallObject(pF, pArgs); Py_DECREF(pArgs); Py_DECREF(pF); if (pValue == NULL) { { return false; } } { return python_to_term(pValue, out); } }
static foreign_t python_apply(term_t tin, term_t targs, term_t keywds, term_t tf) { PyObject *pF; PyObject *pArgs, *pKeywords; PyObject *pValue; int i, arity; atom_t aname; foreign_t out; term_t targ = PL_new_term_ref(); pF = term_to_python(tin, true); PyErr_Clear(); if (pF == NULL) { { return false; } } if (PL_is_atom(targs)) { pArgs = NULL; } else { if (!PL_get_name_arity(targs, &aname, &arity)) { { return false; } } if (arity == 1 && PL_get_arg(1, targs, targ) && PL_is_variable(targ)) { /* ignore (_) */ pArgs = NULL; } else { pArgs = PyTuple_New(arity); if (!pArgs) { return false; } for (i = 0; i < arity; i++) { PyObject *pArg; if (!PL_get_arg(i + 1, targs, targ)) { return false; } pArg = term_to_python(targ, true); if (pArg == NULL) { return false; } /* pArg reference stolen here: */ PyTuple_SetItem(pArgs, i, pArg); } } } if (PL_is_atom(keywds)) { pKeywords = NULL; } else { pKeywords = term_to_python(keywds, true); } if (PyCallable_Check(pF)) { pValue = PyEval_CallObjectWithKeywords(pF, pArgs, pKeywords); // PyObject_Print(pF,stderr,0);fprintf(stderr, "\n"); // PyObject_Print(pArgs,stderr,0);fprintf(stderr, " "); // PyObject_Print(pKeywords,stderr,0);fprintf(stderr, "\n"); if (!pValue) PyErr_Print(); else Py_IncRef(pValue); } else if (pArgs == NULL) { pValue = pF; if (pF) { Py_IncRef(pValue); } } else { PyErr_Print(); { return false; } } if (pArgs) Py_DECREF(pArgs); Py_DECREF(pF); if (pValue == NULL) { return false; } out = python_to_ptr(pValue, tf); return out; }