Feature: Tuple unpacking - #1360
Conversation
Codecov Report
@@ Coverage Diff @@
## master #1360 +/- ##
==========================================
+ Coverage 89.44% 89.45% +0.01%
==========================================
Files 65 65
Lines 10648 10774 +126
==========================================
+ Hits 9524 9638 +114
- Misses 1124 1136 +12
|
|
Note: there is a further optional part of the design doc pertaining to having |
| let all_lvals = | ||
| flatten_lvalues lv |> List.map ~f:Ast.untyped_lvalue_of_typed_lvalue in | ||
| match List.find_all_dups ~compare:Ast.compare_untyped_lval all_lvals with |
There was a problem hiding this comment.
compare_untyped_lval is not correct here, e.g.
int i = 1, j = 1;
array[1] tuple(int, int) tup;
(tup[i].1, tup[j].1) = (1, 2);
(tup, tup[1].1) = ({(1,2)}, 3);I'd erase all array-indexing when flattening the lvalues
let rec flatten idx lv = function
match lv.lval with
| LTuplePacking lvs -> List.concat_map ~f:(flatten []) lvs
| LIndexed (l,_) -> flatten idx lv
| LTupleProjection (l, ix) -> flatten (ix :: idx) l
| LVariable id -> [(id.name, idx)]There was a problem hiding this comment.
These were tricky but I think it is working now.
One unfortunate result of stripping away this information is we can't then print it, so we have to resort to just printing tup rather than tup.1 (misleading) or tup[].1 (ideal, but that information is lost) in the errors
There was a problem hiding this comment.
Ok, I found a reasonable way of having the error mention tup[...].1
|
I refactored the code a bit to "make illegal states unrepresentable" (and also makes How do you feel about a more precise uniqueness check that would allow vector[5] x = ...;
(x[1], x[2:]) = (x[5], x[:4]);Implemented on nhuurre@523c931 Also, we need to decide what to do about int x = 1;
vector[2] y = [1,1]';
(x, y[x]) = (2,2); |
|
I definitely like the illegal states refactor, I'll pull that in. The extra precision on the uniqueness check seems nice but also a lot of code for a relative edge case. IMO, since it would be backwards compatible to allow more cases later, I think we should stick to the simpler cases now and see if there is a demand. That's a nasty test case. I think we'd either want to disallow it or give it the semantics that the values on the left hand side are all what they are before any assignments (such that it would be equivalent to x=2; y[1] = 2, not y[2] = 2), but that's the opposite of what currently happens. Disallowing it is probably easier? |
|
I'm also in favor of disallowing it but note that currently this compiles: array[2] int x = {1,2};
x[x[1]] = 2;It's rather silly though, so maybe disallowing that too is fine. |
|
I think that has the "reasonable" semantics, which is less obvious in the tuples case where the assignments are supposed to be simultaneous |
|
@nhuurre I'm not entirely happy with having a I was able to remove it in 145cc34 by re-constructing the tuple packing location as merging all of the individuals, but that misses the opening and closing transformed data {
int x = 3;
int y = 4;
print(x, y);
(/* test */x, y) = (5, 6);Can you think of both a way to fix this error and maybe also remove the |
Not currently happy
|
Current failures are actually due to that loc not being marked as ignore for comparison. Fixing that, the result of formatting is now |
|
I'm not a fan of that The only problem with that auto-format result is misplaced comment 5, right? I think adding |
|
Yes, 5 is the only bad one currently. If we remove the loc others get worse (1 and 4) Fair enough, I think it's fine to leave now that it has the |
|
I changed LTuplePacking to hold a record I think this is good for a first implementation, I'm going to look more into |
Closes #1349.
Two notes on implementation:
std::tiein cases where that would be the fastest option. This can of course be changed later.=proved very difficult. I updated the grammar such that we no longer distinguish (in the BNF grammar of the language) between expressions that can be on the left hand side of an assignment and other expressions. We still make this distinction in the AST by checking it as part of the semantic action for the assignment parse rule.This actually dramatically improved the state of
parser.messages, since we had duplicate errors for states containing alhsand a (non-lhs)expression.I think this is probably fine (we should probably go even further in this direction -- see Simplify parser #614). Something very similar was done in ANSI C, which is why
++foo = 4is a type error in C, not a parse error.Submission Checklist
Release notes
Added the ability to unpack a tuple during an assignment. For example, the following is now valid:
Copyright and Licensing
By submitting this pull request, the copyright holder is agreeing to
license the submitted work under the BSD 3-clause license (https://opensource.org/licenses/BSD-3-Clause)