-
Notifications
You must be signed in to change notification settings - Fork 59
feat[next]: Add support for tuple comprehensions (not stacked) #2487
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 14 commits
1b4707c
902f8a3
02f881f
0ec4692
ab84ecc
36d6956
152300e
d459b0e
5c4b018
97af81e
8d75708
0dfc80c
067bc29
b771d66
08ed490
9e23d2d
97235d9
dd30833
15b233e
4f0b5d4
b27f80b
b69d700
24f4c90
32e5b2d
a7175d7
4f89818
2779fd0
80f3273
454e15f
55f1799
12dfecb
fc6b1cb
8a1febd
31b969a
c7fc102
7993b9c
b7f8ba9
3d38868
7d5c86c
747f36e
b767700
e91f1f1
9f3474d
7b270a3
d3d4e46
d0272df
56f234e
b7bb0b2
00e077c
6a5a980
e55253b
4fbac27
7a41dda
e73cb27
dc354d9
d864531
08d06a1
158d540
7d8f56c
7808b0f
556178f
01e2754
aed9577
bbf0679
5102336
c6d5a2d
242343f
06d56ee
3f24c06
904623b
a2da186
9205669
349d239
9b610b4
7e7bde5
2c15948
fb724d3
a7ff65a
dc59b75
3b0b4c3
9ab7df4
b96652e
a670352
fced926
502ae5c
ef504e6
e9b8ec2
6d5aab9
4957eb2
d700c31
ccc0722
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,7 +5,6 @@ | |
| # | ||
| # Please, refer to the LICENSE file in the root directory. | ||
| # SPDX-License-Identifier: BSD-3-Clause | ||
|
|
||
| import textwrap | ||
| from typing import Any, Optional, Sequence, TypeAlias, TypeVar, cast | ||
|
|
||
|
|
@@ -24,6 +23,7 @@ | |
| from gt4py.next.ffront.foast_passes import utils as foast_utils | ||
| from gt4py.next.iterator import builtins | ||
| from gt4py.next.type_system import type_info, type_specifications as ts, type_translation | ||
| from gt4py.next.utils import tree_map | ||
|
|
||
|
|
||
| OperatorNodeT = TypeVar("OperatorNodeT", bound=foast.LocatedNode) | ||
|
|
@@ -428,6 +428,10 @@ def visit_Subscript(self, node: foast.Subscript, **kwargs: Any) -> foast.Subscri | |
| f"Tuples need to be indexed with literal integers, got '{node.index}'.", | ||
| ) from ex | ||
| new_type = types[index] | ||
| case ts.VarArgType(element_type=element_type): | ||
| new_type = ( | ||
| element_type # TODO: we only temporarily allow any index for vararg types | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is for direct access to |
||
| ) | ||
|
Comment on lines
+462
to
+464
Comment on lines
+461
to
+464
|
||
| case ts.OffsetType(source=source, target=(target1, target2)): | ||
| if not target2.kind == DimensionKind.LOCAL: | ||
| raise errors.DSLError( | ||
|
|
@@ -674,6 +678,64 @@ def visit_TupleExpr(self, node: foast.TupleExpr, **kwargs: Any) -> foast.TupleEx | |
| new_type = ts.TupleType(types=[element.type for element in new_elts]) | ||
| return foast.TupleExpr(elts=new_elts, type=new_type, location=node.location) | ||
|
|
||
| def visit_TupleComprehension( | ||
| self, node: foast.TupleComprehension, **kwargs: Any | ||
| ) -> foast.TupleComprehension: | ||
| target = self.visit(node.inner.target, **kwargs) | ||
| iterable = self.visit(node.iterable, **kwargs) | ||
| if isinstance(iterable.type, ts.TupleType): | ||
| if len(iterable.type.types) > 0 and not all( | ||
| t == iterable.type.types[0] for t in iterable.type.types | ||
| ): | ||
| raise errors.DSLError( | ||
| iterable.location, | ||
| "Not implemented. All elements of the iterable in a tuple comprehensions must have the same type.", | ||
|
SF-N marked this conversation as resolved.
Outdated
|
||
| ) | ||
| element_type = iterable.type.types[0] | ||
| elif isinstance(iterable.type, ts.VarArgType): | ||
| element_type = iterable.type.element_type | ||
|
SF-N marked this conversation as resolved.
|
||
| else: | ||
| raise errors.DSLError( | ||
| iterable.location, | ||
| f"Iterable in generator expression must be a tuple, got '{iterable.type}'.", | ||
| ) | ||
|
|
||
| inner_kwargs = {"symtable": node.inner.annex.symtable, **kwargs} | ||
|
|
||
| @tree_map(with_path_arg=True) | ||
| def process_target(target_el: foast.Symbol, path: tuple[int, ...]) -> None: | ||
| try: | ||
| type_ = element_type | ||
| for i in path: | ||
| if not isinstance(type_, ts.TupleType) or len(type_.types) <= i: | ||
| raise IndexError() | ||
| type_ = type_.types[i] | ||
| return self.visit(target_el, refine_type=type_, **inner_kwargs) | ||
| except IndexError: | ||
|
SF-N marked this conversation as resolved.
Outdated
|
||
| raise errors.DSLError( | ||
| target_el.location, f"Cannot unpack non-iterable '{type_}' object." | ||
| ) from None | ||
|
|
||
|
|
||
| new_target = process_target(target) | ||
|
|
||
| element_expr = self.visit(node.inner.element_expr, **inner_kwargs) | ||
|
|
||
| return_type: ts.TupleType | ts.VarArgType | ||
| if isinstance(iterable.type, ts.TupleType): | ||
| return_type = ts.TupleType(types=[element_expr.type] * len(iterable.type.types)) | ||
| else: | ||
| assert isinstance(iterable.type, ts.VarArgType) | ||
| return_type = ts.VarArgType(element_type=element_expr.type) | ||
|
|
||
| return foast.TupleComprehension( | ||
| inner=foast.TupleComprehensionMapper( | ||
| target=new_target, element_expr=element_expr, location=node.location | ||
| ), | ||
| iterable=iterable, | ||
| location=node.location, | ||
| type=return_type, | ||
| ) | ||
|
|
||
| def visit_Call(self, node: foast.Call, **kwargs: Any) -> foast.Call: | ||
| new_func = self.visit(node.func, **kwargs) | ||
| new_args = self.visit(node.args, **kwargs) | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.