Skip to content

Commit 7f0de97

Browse files
mustapha-belbiadFarouk-EcharefEmilyBourne
authored
Support variable declarations in c (pyccel#1847)
This feature pull request adds the appropriate C language equivalent for declaring `list` and `set` containers in Python, as well as freeing their memory, with the help of the STC library. This fixes pyccel#1655 and pyccel#1659. **Commit Summary** - Copy STC files to the destination path using `copy_internal_library()`. - Change the order of printing the module and the module header in `codegen` to determine the appropriate STC macros. - Perform the appropriate class method renaming in `_print_Module()` instead of `_print_Module_Header()`. - Determine the right STC container type and construct its macros, as well as the container variable name (`i_type` macro). - Generate the deallocation node of a container using the STC method `container_X_drop(&container_var)`. - Generate the initialization of an STC container in C using the method `c_init()`. - Add tests to check the initialization of `list` and `set` using different data types. --------- Co-authored-by: Farouk-Echaref <[email protected]> Co-authored-by: mustapha-belbiad <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> Co-authored-by: EmilyBourne <[email protected]>
1 parent f4543ba commit 7f0de97

17 files changed

+377
-63
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ All notable changes to this project will be documented in this file.
1919
- #1787 : Ensure `STC` is installed with Pyccel.
2020
- #1656 : Ensure `gFTL` is installed with Pyccel.
2121
- #1844 : Add line numbers and code to errors from built-in function calls.
22+
- #1655 : Add the appropriate C language equivalent for declaring a Python `list` container using the `STC` library.
23+
- #1659 : Add the appropriate C language equivalent for declaring a Python `set` container using the `STC` library.
2224
- \[INTERNALS\] Added `container_rank` property to `ast.datatypes.PyccelType` objects.
2325
- \[DEVELOPER\] Added an improved traceback to the developer-mode errors for errors in function calls.
2426
- #1893 : Add Python support for set initialisation with `set()`.

pyccel/ast/datatypes.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,16 @@ class PyccelType:
149149
is expected when calling a bitwise comparison operator on objects of these types.
150150
"""
151151
__slots__ = ()
152+
_name = None
153+
154+
@property
155+
def name(self):
156+
"""
157+
Get the name of the pyccel type.
158+
159+
Get the name of the pyccel type.
160+
"""
161+
return self._name
152162

153163
def __init__(self): #pylint: disable=useless-parent-delegation
154164
# This __init__ function is required so the ArgumentSingleton can
@@ -433,6 +443,12 @@ class GenericType(FixedSizeType):
433443
def __add__(self, other):
434444
return other
435445

446+
def __eq__(self, other):
447+
return True
448+
449+
def __hash__(self):
450+
return hash(self.__class__)
451+
436452
class SymbolicType(FixedSizeType):
437453
"""
438454
Class representing the datatype of a placeholder symbol.
@@ -745,6 +761,13 @@ def __init__(self, element_type):
745761
self._order = 'C' if (element_type.order == 'C' or element_type.rank == 1) else None
746762
super().__init__()
747763

764+
def __eq__(self, other):
765+
return isinstance(other, self.__class__) and self._element_type == other._element_type \
766+
and self._order == other._order
767+
768+
def __hash__(self):
769+
return hash((self.__class__, self._element_type, self._order))
770+
748771
class HomogeneousSetType(HomogeneousContainerType, metaclass = ArgumentSingleton):
749772
"""
750773
Class representing the homogeneous set type.
@@ -767,6 +790,12 @@ def __init__(self, element_type):
767790
self._element_type = element_type
768791
super().__init__()
769792

793+
def __eq__(self, other):
794+
return isinstance(other, self.__class__) and self._element_type == other._element_type
795+
796+
def __hash__(self):
797+
return hash((self.__class__, self._element_type))
798+
770799
#==============================================================================
771800

772801
class CustomDataType(ContainerType, metaclass=Singleton):

pyccel/ast/utilities.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
Concatenate, Module, PyccelFunctionDef)
1818

1919
from .builtins import (builtin_functions_dict,
20-
PythonRange, PythonList, PythonTuple)
20+
PythonRange, PythonList, PythonTuple, PythonSet)
2121
from .cmathext import cmath_mod
2222
from .datatypes import HomogeneousTupleType, PythonNativeInt
2323
from .internals import PyccelFunction, Slice
@@ -409,7 +409,7 @@ def collect_loops(block, indices, new_index, language_has_vectors = False, resul
409409
if result is None:
410410
result = []
411411
current_level = 0
412-
array_creator_types = (Allocate, PythonList, PythonTuple, Concatenate, Duplicate)
412+
array_creator_types = (Allocate, PythonList, PythonTuple, Concatenate, Duplicate, PythonSet)
413413
is_function_call = lambda f: ((isinstance(f, FunctionCall) and not f.funcdef.is_elemental)
414414
or (isinstance(f, PyccelFunction) and not f.is_elemental and not hasattr(f, '__getitem__')
415415
and not isinstance(f, (NumpyTranspose))))

pyccel/codegen/codegen.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -216,19 +216,19 @@ def export(self, filename):
216216
header_filename = f'{filename}.{header_ext}'
217217
filename = f'{filename}.{ext}'
218218

219+
# print module
220+
code = self._printer.doprint(self.ast)
221+
with open(filename, 'w', encoding="utf-8") as f:
222+
for line in code:
223+
f.write(line)
224+
219225
# print module header
220226
if header_ext is not None:
221227
code = self._printer.doprint(ModuleHeader(self.ast))
222-
with open(header_filename, 'w') as f:
228+
with open(header_filename, 'w', encoding="utf-8") as f:
223229
for line in code:
224230
f.write(line)
225231

226-
# print module
227-
code = self._printer.doprint(self.ast)
228-
with open(filename, 'w') as f:
229-
for line in code:
230-
f.write(line)
231-
232232
# print program
233233
prog_filename = None
234234
if self.is_program and self.language != 'python':

pyccel/codegen/pipeline.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from pyccel.codegen.utilities import recompile_object
2222
from pyccel.codegen.utilities import copy_internal_library
2323
from pyccel.codegen.utilities import internal_libs
24+
from pyccel.codegen.utilities import external_libs
2425
from pyccel.codegen.python_wrapper import create_shared_library
2526
from pyccel.naming import name_clash_checkers
2627
from pyccel.utilities.stage import PyccelStage
@@ -334,6 +335,14 @@ def handle_error(stage):
334335

335336
mod_obj.add_dependencies(stdlib)
336337

338+
339+
# Iterate over the external_libs list and determine if the printer
340+
# requires an external lib to be included.
341+
for key in codegen.get_printer_imports():
342+
lib_name = key.split("/", 1)[0]
343+
if lib_name in external_libs:
344+
lib_dest_path = copy_internal_library(lib_name, pyccel_dirpath)
345+
337346
if convert_only:
338347
# Change working directory back to starting point
339348
os.chdir(base_dirpath)

0 commit comments

Comments
 (0)