pyccel.codegen.printing.ccode module#

class pyccel.codegen.printing.ccode.CCodePrinter(filename, *, verbose, prefix_module=None)[source]#

Bases: CodePrinter

A printer for printing code in C.

A printer to convert Pyccel’s AST to strings of c code. As for all printers the navigation of this file is done via _print_X functions.

Parameters:
  • filename (str) – The name of the file being pyccelised.

  • verbose (int) – The level of verbosity.

  • prefix_module (str) – A prefix to be added to the name of the module.

arrayFill(expr)[source]#

Print the assignment of a NdArray.

Print the code necessary to create and fill an ndarray.

Parameters:

expr (Assign) – The Assign Node used to get the lhs and rhs.

Returns:

Return a str that contains a call to the C function array_fill.

Return type:

str

copy_NumpyArray_Data(lhs, rhs)[source]#

Get code which copies data from a Ndarray or a homogeneous tuple into a Ndarray.

When data is copied from a homogeneous tuple, the code declares and fills a dummy data_buffer and copies the data from it to a NdArray struct. When data is copied from a Ndarray this is done directly without an intermediate structure.

Parameters:
  • lhs (TypedAstNode) – The left-hand side of the assignment containing the array into which the NumPy array should be copied.

  • rhs (TypedAstNode) – The right-hand side of the assignment containing the array(s) which should be copied into the left-hand side.

Returns:

A string containing the code which allocates and copies the data.

Return type:

str

dtype_registry = {(<pyccel.ast.datatypes.PrimitiveBooleanType object>, -1): 'bool', (<pyccel.ast.datatypes.PrimitiveComplexType object>, 4): 'float complex', (<pyccel.ast.datatypes.PrimitiveComplexType object>, 8): 'double complex', (<pyccel.ast.datatypes.PrimitiveFloatingPointType object>, 4): 'float', (<pyccel.ast.datatypes.PrimitiveFloatingPointType object>, 8): 'double', (<pyccel.ast.datatypes.PrimitiveIntegerType object>, 1): 'int8_t', (<pyccel.ast.datatypes.PrimitiveIntegerType object>, 2): 'int16_t', (<pyccel.ast.datatypes.PrimitiveIntegerType object>, 4): 'int32_t', (<pyccel.ast.datatypes.PrimitiveIntegerType object>, 8): 'int64_t', (<pyccel.ast.datatypes.PrimitiveIntegerType object>, None): 'int', <pyccel.ast.datatypes.CharType object>: 'char', <pyccel.ast.datatypes.VoidType object>: 'void'}#
function_signature(expr, print_arg_names=True)[source]#

Get the C representation of the function signature.

Extract from the function definition expr all the information (name, input, output) needed to create the function signature and return a string describing the function.

This is not a declaration as the signature does not end with a semi-colon.

Parameters:
  • expr (FunctionDef) – The function definition for which a signature is needed.

  • print_arg_names (bool, default : True) – Indicates whether argument names should be printed.

Returns:

Signature of the function.

Return type:

str

get_c_type(dtype, in_container=False)[source]#

Find the corresponding C type of the PyccelType.

For scalar types, this function searches for the corresponding C data type in the dtype_registry. If the provided type is a container (like HomogeneousSetType or HomogeneousListType), it recursively identifies the type of an element of the container and uses it to calculate the appropriate type for the STC container. A PYCCEL_RESTRICTION_TODO error is raised if the dtype is not found in the registry.

Parameters:
  • dtype (PyccelType) – The data type of the expression. This can be a fixed-size numeric type, a primitive type, or a container type.

  • in_container (bool, default = False) – A boolean indicating whether the type will be stored in a container. If this is the case then an additional arc type may be created.

Returns:

The code which declares the data type in C or the corresponding STC container type.

Return type:

str

Raises:

PyccelCodegenError – If the dtype is not found in the dtype_registry.

get_declare_type(expr)[source]#

Get the string which describes the type in a declaration.

This function returns the code which describes the type of the expr object such that the declaration can be written as: f”{self.get_declare_type(expr)} {expr.name}” The function takes care of reporting errors for unknown types and importing any necessary additional imports (e.g. stdint/ndarrays).

Parameters:

expr (Variable) – The variable whose type should be described.

Returns:

The code describing the type.

Return type:

str

Raises:

PyccelCodegenError – If the type is not supported in the C code.

Examples

>>> v = Variable(PythonNativeInt(), 'x')
>>> self.get_declare_type(v)
'int64_t'

For an object accessed via a pointer: >>> v = Variable(NumpyNDArrayType(PythonNativeInt(), 1, None), ‘x’, is_optional=True) >>> self.get_declare_type(v) ‘array_int64_1d*’

get_print_format_and_arg(var)[source]#

Get the C print format string for the object var.

Get the C print format string which will allow the generated code to print the variable passed as argument.

Parameters:

var (TypedAstNode) – The object which will be printed.

Returns:

  • arg_format (str) – The format which should be printed in the format string of the generated print expression.

  • arg (str) – The code which should be printed in the arguments of the generated print expression to print the object.

get_stc_init_elements(class_type, elements)[source]#

Get the elements that can be passed to a c_make call.

Get the elements that can be passed to a c_make call. For some types this calculation is non-trivial. For example for elements that may be pointers an arc type must be created in order to ensure correct memory deallocation.

From a STC point of view this method constructs types that are saved in the container (e.g. i_key) from the equivalent raw type (e.g. i_keyraw).

Parameters:
  • class_type (PyccelType) – The type of the elements in the c_make call.

  • elements (list[TypedAstNode]) – The elements that should be printed in the c_make call.

Returns:

A list whose elements describe the c code which gets an element of the container from a raw object.

Return type:

list[str]

indent_code(code)[source]#

Add the necessary indentation to a string of code or a list of code lines.

Add the necessary indentation to a string of code or a list of code lines.

Parameters:

code (str | iterable[str]) – The code which needs indenting.

Returns:

The indented code. The type matches the type of the argument.

Return type:

str | list[str]

init_stc_container(expr, class_type)[source]#

Generate the initialization of an STC container in C.

This method generates and prints the C code for initializing a container using the STC c_make() method.

Parameters:
  • expr (TypedAstNode) – The object representing the container being printed (e.g., PythonList, PythonSet).

  • class_type (PyccelType) – The type of the Python container being created.

Returns:

The generated C code for the container initialization.

Return type:

str

is_c_pointer(a)[source]#

Indicate whether the object is a pointer in C code.

Some objects are accessed via a C pointer so that they can be modified in their scope and that modification can be retrieved elsewhere. This information cannot be found trivially so this function provides that information while avoiding easily outdated code to be repeated.

The main reasons for this treatment are: 1. It is the actual memory address of an object 2. It is a reference to another object (e.g. an alias, an optional argument, or one of multiple return arguments)

See codegen_stage.md in the developer docs for more details.

Parameters:

a (TypedAstNode) – The object whose storage we are enquiring about.

Returns:

True if a C pointer, False otherwise.

Return type:

bool

language = 'C'#
printmethod = '_ccode'#
rename_imported_methods(expr)[source]#

Rename class methods from user-defined imports.

This function is responsible for renaming methods of classes from the imported modules, ensuring that the names are correct by prefixing them with their class names.

Parameters:

expr (iterable[ClassDef]) – The ClassDef objects found in the module being renamed.

sort_imports(imports)[source]#

Sort imports to avoid any errors due to bad ordering.

Sort imports. This is important so that types exist before they are used to create container types. E.g. it is important that complex or inttypes be imported before vec_int or vec_double_complex is declared.

Parameters:

imports (list[Import]) – A list of the imports.

Returns:

A sorted list of the imports.

Return type:

list[Import]

type_to_format = {(<pyccel.ast.datatypes.PrimitiveFloatingPointType object>, 4): '%.6f', (<pyccel.ast.datatypes.PrimitiveFloatingPointType object>, 8): '%.15lf', (<pyccel.ast.datatypes.PrimitiveIntegerType object>, 1): '%'PRId8, (<pyccel.ast.datatypes.PrimitiveIntegerType object>, 2): '%'PRId16, (<pyccel.ast.datatypes.PrimitiveIntegerType object>, 4): '%d', (<pyccel.ast.datatypes.PrimitiveIntegerType object>, 8): '%'PRId64}#