40 #ifdef EST_SIOD_ENABLE_PYTHON 49 static int tc_pyobject = -1;
52 int pyobject_p(LISP x) {
53 if (
TYPEP(x, tc_pyobject))
58 LISP pyobjectp(LISP x) {
67 static PyObject *get_c_pyobject(LISP x) {
68 if (
TYPEP(x, tc_pyobject)) {
69 PyObject *p =
reinterpret_cast<PyObject *
>(
USERVAL(x));
85 PyObject *pList = PyList_New(num_items);
90 ptr =
cdr(ptr), i++) {
91 PyList_SetItem(pList, i, get_c_pyobject(
car(ptr)));
96 err(
"wrong type of argument to get_c_pyobject", x);
100 static LISP siod_make_pyobject(PyObject *pyobj) {
101 if (pyobj ==
NULL || pyobj == Py_None)
104 if (PyLong_Check(pyobj) || PyFloat_Check(pyobj))
105 return flocons(PyFloat_AsDouble(pyobj));
107 if (PyBool_Check(pyobj))
108 return PyObject_IsTrue(pyobj)?
truth :
NIL;
110 if (PyUnicode_Check(pyobj)) {
113 pBytes = PyUnicode_AsUTF8String(pyobj);
117 ret =
strcons(PyBytes_Size(pBytes),
118 PyBytes_AsString(pBytes));
123 if (PyTuple_Check(pyobj) || PyList_Check(pyobj)) {
125 int size = PySequence_Size(pyobj);
128 for (
int i = size - 1; i >= 0; i--)
129 ret =
cons(siod_make_pyobject(PySequence_GetItem(pyobj, i)),
139 static void pyobject_free(LISP x) {
141 if (
TYPEP(x, tc_pyobject)) {
142 PyObject *p =
reinterpret_cast<PyObject *
>(
USERVAL(x));
147 static void pyobject_prin1(LISP v, FILE *
fp) {
148 if (
TYPEP(v, tc_pyobject)) {
149 PyObject *p =
reinterpret_cast<PyObject *
>(
USERVAL(v));
150 PyObject_Print(p, fp, Py_PRINT_RAW);
154 static void pyobject_print_string(LISP v,
char *
tkbuffer) {
155 if (
TYPEP(v, tc_pyobject)) {
156 PyObject *p =
reinterpret_cast<PyObject *
>(
USERVAL(v));
157 PyObject *pRepr = PyObject_Str(p);
159 snprintf(tkbuffer, 1024,
"#<UnknownPythonObject %p>", p);
163 LISP repr = siod_make_pyobject(pRepr);
164 snprintf(tkbuffer, 1024,
"PyObject %s",
get_c_string(repr));
168 snprintf(tkbuffer, 1024,
"#<UnknownObject>");
171 static LISP python_syspath_append(LISP path) {
173 err(
"Invalid Path", path);
177 PyObject* sysPath = PySys_GetObject(
"path");
178 int ret = PyList_Append(sysPath, PyUnicode_FromString(
get_c_string(path)));
186 static LISP python_import(LISP modulename) {
187 PyObject *pName, *pModule;
191 err(
"Invalid module name (expecting string)", modulename);
196 pModule = PyImport_Import(pName);
199 if (pModule ==
NULL) {
200 if (PyErr_Occurred()) {
204 err(
"Failed to load module", modulename);
207 ret = siod_make_pyobject(pModule);
212 static LISP python_attr_get(LISP lpobj, LISP attrname) {
213 if (!
TYPEP(lpobj, tc_pyobject)) {
214 err(
"Invalid Object for python_attr_get", lpobj);
218 PyObject *p =
reinterpret_cast<PyObject *
>(
USERVAL(lpobj));
221 err(
"Invalid Attribute Name (expecting string)", attrname);
225 PyObject *pAttr = PyObject_GetAttrString(p,
get_c_string(attrname));
227 if (PyErr_Occurred()) {
232 LISP ret = siod_make_pyobject(pAttr);
237 static LISP python_attr_set(LISP lpobj, LISP attrname, LISP value) {
238 if (!
TYPEP(lpobj, tc_pyobject)) {
239 err(
"Invalid Object for python_attr_set", lpobj);
243 PyObject *p =
reinterpret_cast<PyObject *
>(
USERVAL(lpobj));
246 err(
"Invalid Attribute Name (expecting string)", attrname);
250 PyObject *pValue = get_c_pyobject(value);
251 if (pValue ==
NULL) {
252 if (PyErr_Occurred()) {
256 err(
"Invalid Value for python_attr_set", value);
260 int result = PyObject_SetAttrString(p,
get_c_string(attrname), pValue);
264 err(
"Failed to set value", value);
270 static LISP python_call_object(LISP fpobj, LISP args) {
271 if (!
TYPEP(fpobj, tc_pyobject)) {
272 err(
"Invalid Object for python_callfunction", fpobj);
276 PyObject *p =
reinterpret_cast<PyObject *
>(
USERVAL(fpobj));
278 if (p ==
NULL || !PyCallable_Check(p)) {
279 err(
"Not a callable object", fpobj);
288 err(
"Invalid argument (expecting list)", args);
292 pArgs = get_c_pyobject(args);
294 err(
"Could not convert arguments", args);
299 PyObject *pArgsTuple =
NULL;
301 pArgsTuple = PyList_AsTuple(pArgs);
305 PyObject *pValue = PyObject_CallObject(p, pArgsTuple);
306 Py_XDECREF(pArgsTuple);
308 if (pValue ==
NULL) {
309 if (PyErr_Occurred()) {
313 err(
"Could not call object", fpobj);
316 LISP ret = siod_make_pyobject(pValue);
321 static LISP python_call_method(LISP lpobj, LISP methodname, LISP args) {
322 LISP callable = python_attr_get(lpobj, methodname);
323 return python_call_object(callable, args);
326 void init_subrs_python(
void) {
336 PyObject* sysPath = PySys_GetObject(
"path");
337 PyList_Append(sysPath, PyUnicode_FromString(
"."));
341 "Checks if obj is a Python Object");
344 init_subr_1(
"python_syspath_append", python_syspath_append,
345 "(python_addpath path)\n" 346 "Appends path (string) to sys.path");
349 "(python_import modulename)\n" 350 "Imports specified module and returns it");
353 "(python_attr_get object attrname)\n" 354 "Returns the specified attribute of the given PyObject");
357 "(python_attr_set object attrname value)\n" 358 "Set value of the given attribute of the given PyObject");
360 init_subr_3(
"python_call_method", python_call_method,
361 "(python_call_method object methodname args)\n" 362 "Calls object.methodname(args)\n" 363 "object is a PyObject, methodname is string. args is a list.");
365 init_subr_2(
"python_call_object", python_call_object,
366 "(python_call_object object args)\n" 367 "Calls object(args)\n" 368 "object is a callable PyObject, args is a list");
371 void python_tidy_up(
void) {
375 #endif // EST_SIOD_ENABLE_PYTHON
LISP siod_make_typed_cell(long type, void *s)
double get_c_double(LISP x)
int siod_llength(LISP list)
void init_subr_2(const char *name, LISP(*fcn)(LISP, LISP), const char *doc)
LISP strcons(long length, const char *data)
void set_print_hooks(long type, void(*prin1)(LISP, FILE *), void(*print_string)(LISP, char *))
void err(const char *message, LISP x) EST_NORETURN
int siod_register_user_type(const char *name)
const char * get_c_string(LISP x)
LISP cons(LISP x, LISP y)
void init_subr_1(const char *name, LISP(*fcn)(LISP), const char *doc)
void init_subr_3(const char *name, LISP(*fcn)(LISP, LISP, LISP), const char *doc)
void set_gc_hooks(long type, int gc_free_once, LISP(*rel)(LISP), LISP(*mark)(LISP), void(*scan)(LISP), void(*free)(LISP), void(*clear)(LISP), long *kind)