@@ -502,6 +502,86 @@ R"(#include <stdio.h>
502
502
return " \n template <" + template_for_Kokkos + " >\n " + func;
503
503
}
504
504
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
+
505
585
std::string declare_all_functions (const SymbolTable &scope) {
506
586
std::string code, t;
507
587
for (auto &item : scope.get_scope ()) {
@@ -551,14 +631,19 @@ R"(#include <stdio.h>
551
631
return ;
552
632
}
553
633
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 ;
562
647
}
563
648
} else {
564
649
sub += " \n " ;
0 commit comments