|
29 | 29 | PythonTuple, Lambda, PythonMap)
|
30 | 30 |
|
31 | 31 | from pyccel.ast.builtin_methods.list_methods import ListMethod, ListAppend
|
| 32 | +from pyccel.ast.builtin_methods.set_methods import SetMethod, SetAdd |
32 | 33 |
|
33 | 34 | from pyccel.ast.core import Comment, CommentBlock, Pass
|
34 | 35 | from pyccel.ast.core import If, IfSection
|
@@ -3016,7 +3017,8 @@ def _visit_Assign(self, expr):
|
3016 | 3017 | symbol=expr, severity='error')
|
3017 | 3018 |
|
3018 | 3019 | # Checking for the result of _visit_ListExtend
|
3019 |
| - if isinstance(rhs, For) or (isinstance(rhs, CodeBlock) and isinstance(rhs.body[0], ListMethod)): |
| 3020 | + if isinstance(rhs, For) or (isinstance(rhs, CodeBlock) and |
| 3021 | + isinstance(rhs.body[0], (ListMethod, SetMethod))): |
3020 | 3022 | return rhs
|
3021 | 3023 | if isinstance(rhs, ConstructorCall):
|
3022 | 3024 | return rhs
|
@@ -4573,7 +4575,7 @@ def _build_ListExtend(self, expr):
|
4573 | 4575 | """
|
4574 | 4576 | Method to navigate the syntactic DottedName node of an `extend()` call.
|
4575 | 4577 |
|
4576 |
| - The purpose of this `_visit` method is to construct new nodes from a syntactic |
| 4578 | + The purpose of this `_build` method is to construct new nodes from a syntactic |
4577 | 4579 | DottedName node. It checks the type of the iterable passed to `extend()`.
|
4578 | 4580 | If the iterable is an instance of `PythonList` or `PythonTuple`, it constructs
|
4579 | 4581 | a CodeBlock node where its body consists of `ListAppend` objects with the
|
@@ -4799,3 +4801,50 @@ def _build_CmathPhase(self, func_call):
|
4799 | 4801 | else:
|
4800 | 4802 | self.insert_import('math', AsName(MathAtan2, 'atan2'))
|
4801 | 4803 | return MathAtan2(PythonImag(var), PythonReal(var))
|
| 4804 | + |
| 4805 | + def _build_SetUpdate(self, expr): |
| 4806 | + """ |
| 4807 | + Method to navigate the syntactic DottedName node of an `update()` call. |
| 4808 | +
|
| 4809 | + The purpose of this `_build` method is to construct new nodes from a syntactic |
| 4810 | + DottedName node. It checks the type of the iterable passed to `update()`. |
| 4811 | + If the iterable is an instance of `PythonList`, `PythonSet` or `PythonTuple`, it constructs |
| 4812 | + a CodeBlock node where its body consists of `SetAdd` objects with the |
| 4813 | + elements of the iterable. If not, it attempts to construct a syntactic `For` |
| 4814 | + loop to iterate over the iterable object and added its elements to the set |
| 4815 | + object. Finally, it passes to a `_visit()` call for semantic parsing. |
| 4816 | + |
| 4817 | + Parameters |
| 4818 | + ---------- |
| 4819 | + expr : DottedName |
| 4820 | + The syntactic DottedName node that represent the call to `.update()`. |
| 4821 | +
|
| 4822 | + Returns |
| 4823 | + ------- |
| 4824 | + PyccelAstNode |
| 4825 | + CodeBlock or For containing SetAdd objects. |
| 4826 | + """ |
| 4827 | + iterable = expr.name[1].args[0].value |
| 4828 | + if isinstance(iterable, (PythonList, PythonSet, PythonTuple)): |
| 4829 | + list_variable = self._visit(expr.name[0]) |
| 4830 | + added_list = self._visit(iterable) |
| 4831 | + try: |
| 4832 | + store = [SetAdd(list_variable, a) for a in added_list] |
| 4833 | + except TypeError as e: |
| 4834 | + msg = str(e) |
| 4835 | + errors.report(msg, symbol=expr, severity='fatal') |
| 4836 | + return CodeBlock(store) |
| 4837 | + else: |
| 4838 | + pyccel_stage.set_stage('syntactic') |
| 4839 | + for_target = self.scope.get_new_name() |
| 4840 | + arg = FunctionCallArgument(for_target) |
| 4841 | + func_call = FunctionCall('add', [arg]) |
| 4842 | + dotted = DottedName(expr.name[0], func_call) |
| 4843 | + lhs = PyccelSymbol('_', is_temp=True) |
| 4844 | + assign = Assign(lhs, dotted) |
| 4845 | + assign.set_current_ast(expr.python_ast) |
| 4846 | + body = CodeBlock([assign]) |
| 4847 | + for_obj = For(for_target, iterable, body) |
| 4848 | + pyccel_stage.set_stage('semantic') |
| 4849 | + return self._visit(for_obj) |
| 4850 | + |
0 commit comments