@@ -502,6 +502,86 @@ R"(#include <stdio.h>
502502 return " \n template <" + template_for_Kokkos + " >\n " + func;
503503 }
504504
505+ std::string get_arg_conv_bind_python (const ASR::Function_t &x) {
506+ // args for bind python not yet supported
507+ LCOMPILERS_ASSERT (x.n_args == 0 );
508+
509+ std::string arg_conv = R"(
510+ pArgs = PyTuple_New()" + std::to_string (x.n_args ) + R"( );
511+ )" ;
512+ for (size_t i = 0 ; i < x.n_args ; ++i) {
513+ arg_conv += R"(
514+ // Use appropriate Py* Function for x.m_arg[i] conversion
515+ pValue = PyLong_FromLong(x.m_arg[i]);
516+ if (!pValue) {
517+ Py_DECREF(pArgs);
518+ Py_DECREF(pModule);
519+ fprintf(stderr, "Cannot convert argument\n");
520+ exit(1);
521+ }
522+ /* pValue reference stolen here: */
523+ PyTuple_SetItem(pArgs, )" + std::to_string (i) + R"( , pValue);
524+ )" ;
525+ }
526+ return arg_conv;
527+ }
528+
529+ std::string get_func_body_bind_python (const ASR::Function_t &x) {
530+ user_headers.insert (" Python.h" );
531+ std::string indent (indentation_level*indentation_spaces, ' ' );
532+ std::string var_decls = " PyObject *pName, *pModule, *pFunc; PyObject *pArgs, *pValue;\n " ;
533+ std::string func_body = R"(
534+ /*
535+ Python Environment initialization and function evaluation
536+ should ideally happen once and not for every function call
537+ */
538+
539+ Py_Initialize();
540+ wchar_t* argv1 = Py_DecodeLocale("", NULL);
541+ wchar_t** argv = {&argv1};
542+ PySys_SetArgv(1, argv);
543+ pName = PyUnicode_FromString(")" + std::string (x.m_module_file ) + R"( ");
544+ // TODO: check for error in pName
545+
546+ pModule = PyImport_Import(pName);
547+ Py_DECREF(pName);
548+ if (pModule == NULL) {
549+ PyErr_Print();
550+ fprintf(stderr, "Failed to load python module )" + std::string (x.m_module_file ) + R"( \n");
551+ exit(1);
552+ }
553+
554+ pFunc = PyObject_GetAttrString(pModule, ")" + std::string (x.m_name ) + R"( ");
555+ if (!pFunc || !PyCallable_Check(pFunc)) {
556+ if (PyErr_Occurred()) PyErr_Print();
557+ fprintf(stderr, "Cannot find function )" + std::string (x.m_name ) + R"( \n");
558+ Py_XDECREF(pFunc);
559+ Py_DECREF(pModule);
560+ exit(1);
561+ }
562+
563+ )" + get_arg_conv_bind_python (x) + R"(
564+
565+ pValue = PyObject_CallObject(pFunc, pArgs);
566+ Py_DECREF(pArgs);
567+ if (pValue == NULL) {
568+ Py_DECREF(pFunc);
569+ Py_DECREF(pModule);
570+ PyErr_Print();
571+ fprintf(stderr,"Call failed\n");
572+ exit(1);
573+ }
574+ // TODO: handle/convert the return value here
575+ Py_DECREF(pValue);
576+
577+ if (Py_FinalizeEx() < 0) {
578+ fprintf(stderr,"BindPython: Unknown Error\n");
579+ exit(1);
580+ }
581+ )" ;
582+ return " {\n " + indent + var_decls + func_body + " }\n " ;
583+ }
584+
505585 std::string declare_all_functions (const SymbolTable &scope) {
506586 std::string code, t;
507587 for (auto &item : scope.get_scope ()) {
@@ -551,14 +631,19 @@ R"(#include <stdio.h>
551631 return ;
552632 }
553633 ASR::FunctionType_t *f_type = ASRUtils::get_FunctionType (x);
554- if (f_type->m_abi == ASR::abiType::BindC
555- && f_type->m_deftype == ASR::deftypeType::Interface) {
556- if (x.m_module_file ) {
557- user_headers.insert (std::string (x.m_module_file ));
558- src = " " ;
559- return ;
560- } else {
561- sub += " ;\n " ;
634+ if (f_type->m_deftype == ASR::deftypeType::Interface) {
635+ if (f_type->m_abi == ASR::abiType::BindC) {
636+ if (x.m_module_file ) {
637+ user_headers.insert (std::string (x.m_module_file ));
638+ src = " " ;
639+ return ;
640+ } else {
641+ sub += " ;\n " ;
642+ }
643+ } else if (f_type->m_abi == ASR::abiType::BindPython) {
644+ indentation_level += 1 ;
645+ sub += " \n " + get_func_body_bind_python (x);
646+ indentation_level -= 1 ;
562647 }
563648 } else {
564649 sub += " \n " ;
0 commit comments