@@ -637,7 +637,8 @@ def get_rtlib_dir():
637637
638638 def get_type_info (arg ):
639639 # return_type -> (`type_format`, `variable type`, `array struct name`)
640- # See: https://docs.python.org/3/c-api/arg.html for more info on type_format
640+ # See: https://docs.python.org/3/c-api/arg.html for more info on `type_format`
641+ # `array struct name`: used by the C backend
641642 if arg == f64 :
642643 return ('d' , "double" , 'r64' )
643644 elif arg == f32 :
@@ -652,7 +653,10 @@ def get_type_info(arg):
652653 t = get_type_info (arg ._type )
653654 if t [2 ] == '' :
654655 raise NotImplementedError ("Type %r not implemented" % arg )
655- return ('O' , ["PyArrayObject *" , "struct " + t [2 ]+ " *" , t [1 ]+ " *" ], '' )
656+ n = ''
657+ if not isinstance (arg ._dims , slice ):
658+ n = arg ._dims ._name
659+ return ('O' , ["PyArrayObject *" , "struct " + t [2 ]+ " *" , t [1 ]+ " *" , n ], '' )
656660 else :
657661 raise NotImplementedError ("Type %r not implemented" % arg )
658662
@@ -684,7 +688,6 @@ def get_data_type(t):
684688 self .return_type_format = ""
685689 self .array_as_return_type = ()
686690 self .arg_types = {}
687- counter = 1
688691 for t in types .keys ():
689692 if t == "return" :
690693 type = get_type_info (types [t ])
@@ -697,18 +700,19 @@ def get_data_type(t):
697700 else :
698701 type = get_type_info (types [t ])
699702 self .arg_type_formats += type [0 ]
700- self .arg_types [counter ] = type [1 ]
701- counter += 1
703+ self .arg_types [t ] = type [1 ]
702704 # ----------------------------------------------------------------------
703- # `arg_0` is used as the return variable
704- # arguments are declared as `arg_1`, `arg_2`, ...
705+ # `_<fn_name>_return_value`: used as the return variables
705706 variables_decl = "// Declare return variables and arguments\n "
706707 if self .return_type != "" :
707- variables_decl += " " + get_data_type (self .return_type ) + "arg_" \
708- + str ( 0 ) + " ;\n "
708+ variables_decl += " " + get_data_type (self .return_type ) \
709+ + "_" + self . fn_name + "_return_value ;\n "
709710 elif self .array_as_return_type :
710711 variables_decl += " " + get_data_type ( \
711- self .array_as_return_type [1 ][1 ][:- 2 ]) + "arg_" + str (0 ) + ";\n "
712+ self .array_as_return_type [1 ][1 ][:- 2 ]) + "_" + self .fn_name \
713+ + "_return_value;\n "
714+ else :
715+ variables_decl = ""
712716 # ----------------------------------------------------------------------
713717 # `PyArray_AsCArray` is used to convert NumPy Arrays to C Arrays
714718 # `fill_array_details` contains array operations to be
@@ -719,16 +723,18 @@ def get_data_type(t):
719723 parse_args = ""
720724 pass_args = ""
721725 numpy_init = ""
726+ prefix_comma = False
722727 for i , t in self .arg_types .items ():
723- if i > 1 :
728+ if prefix_comma :
724729 parse_args += ", "
725730 pass_args += ", "
731+ prefix_comma = True
726732 if isinstance (t , list ):
727733 if numpy_init == "" :
728734 numpy_init = "// Initialize NumPy\n import_array();\n \n "
729735 fill_array_details += f"""\n
730- // fill array details for args[ { i - 1 } ]
731- if (PyArray_NDIM(arg_ { i } ) != 1) {{
736+ // fill array details for { i }
737+ if (PyArray_NDIM({ i } ) != 1) {{
732738 PyErr_SetString(PyExc_TypeError,
733739 "Only 1 dimension is implemented for now.");
734740 return NULL;
@@ -738,9 +744,9 @@ def get_data_type(t):
738744 {{
739745 { t [2 ]} array;
740746 // Create C arrays from numpy objects:
741- PyArray_Descr *descr = PyArray_DescrFromType(PyArray_TYPE(arg_ { i } ));
747+ PyArray_Descr *descr = PyArray_DescrFromType(PyArray_TYPE({ i } ));
742748 npy_intp dims[1];
743- if (PyArray_AsCArray((PyObject **)&arg_ { i } , (void *)&array, dims, 1, descr) < 0) {{
749+ if (PyArray_AsCArray((PyObject **)&{ i } , (void *)&array, dims, 1, descr) < 0) {{
744750 PyErr_SetString(PyExc_TypeError, "error converting to c array");
745751 return NULL;
746752 }}
@@ -751,11 +757,11 @@ def get_data_type(t):
751757 s_array_{ i } ->dims[0].length = dims[0];
752758 s_array_{ i } ->is_allocated = false;
753759 }}"""
754- pass_args += "s_array_" + str ( i )
760+ pass_args += "s_array_" + i
755761 else :
756- pass_args += "arg_" + str ( i )
757- variables_decl += " " + get_data_type (t ) + "arg_" + str ( i ) + ";\n "
758- parse_args += "&arg_ " + str ( i )
762+ pass_args += i
763+ variables_decl += " " + get_data_type (t ) + i + ";\n "
764+ parse_args += "&" + i
759765
760766 if parse_args != "" :
761767 parse_args = f"""\n // Parse the arguments from Python
@@ -768,24 +774,24 @@ def get_data_type(t):
768774 fill_return_details = ""
769775 if self .return_type != "" :
770776 fill_return_details = f"""\n \n // Call the C function
771- arg_0 = { self .fn_name } ({ pass_args } );
777+ _ { self . fn_name } _return_value = { self .fn_name } ({ pass_args } );
772778
773779 // Build and return the result as a Python object
774- return Py_BuildValue("{ self .return_type_format } ", arg_0 );"""
780+ return Py_BuildValue("{ self .return_type_format } ", _ { self . fn_name } _return_value );"""
775781 else :
776782 if self .array_as_return_type :
777783 fill_return_details = f"""
778- arg_0 .data = malloc(sizeof({ self .array_as_return_type [1 ][2 ][:- 2 ]} ));
779- arg_0 .n_dims = 1;
780- arg_0 .dims[0].lower_bound = 0;
781- arg_0. dims[0].length = arg_1 ;
782- arg_0 .is_allocated = false;
783- { self .fn_name } ({ pass_args } , &arg_0 );
784+ _ { self . fn_name } _return_value .data = malloc(sizeof({ self .array_as_return_type [1 ][2 ][:- 2 ]} ));
785+ _ { self . fn_name } _return_value .n_dims = 1;
786+ _ { self . fn_name } _return_value .dims[0].lower_bound = 0;
787+ _ { self . fn_name } _return_value. dims[0].length = { self . array_as_return_type [ 1 ][ 3 ] } ;
788+ _ { self . fn_name } _return_value .is_allocated = false;
789+ { self .fn_name } ({ pass_args } , &_ { self . fn_name } _return_value );
784790
785791 // Build and return the result as a Python object
786- PyObject* list_obj = PyList_New(arg_1 );
787- for (int i = 0; i < arg_1 ; i++) {{
788- PyObject* element = PyFloat_FromDouble(arg_0 .data[i]);
792+ PyObject* list_obj = PyList_New({ self . array_as_return_type [ 1 ][ 3 ] } );
793+ for (int i = 0; i < { self . array_as_return_type [ 1 ][ 3 ] } ; i++) {{
794+ PyObject* element = PyFloat_FromDouble(_ { self . fn_name } _return_value .data[i]);
789795 PyList_SetItem(list_obj, i, element);
790796 }}
791797 return list_obj;"""
0 commit comments