-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Add C#-style type accelerators and suffixes for ushort, uint, ulong, and short literals. #7575
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
Conversation
Catch up to PowerShell/PowerShell/master
Catch up to master
How did that even happen, seriously...
|
I don't intend to fix the code factor issues here. I'll address them during the parser refactor that will come after this. (Much of the code causing the majority of the issues will be replaced anyhow; see #7509). |
| else | ||
| { | ||
| result = d * multiplier; | ||
| result = d; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why we remove the multiplier?
What scenario address the code? It would nice to add a comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I thought I got all those. Correcting...
(I was trying to see if I could do the multiplier before the conversions to avoid throwing too much here, but it doesn't work because Int64.MaxValue is too high to retain precision with Double values in the upper range there.)
| result = ((long)Convert.ChangeType(d, typeof(long), CultureInfo.InvariantCulture)) * multiplier; | ||
| result = ((long)Convert.ChangeType(d, typeof(long), CultureInfo.InvariantCulture) * multiplier); | ||
| } | ||
| else if (suffix == NumberSuffixFlags.Short) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe we could replace one level of if-else-if with switch to get more readable code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm. Agreed!
| { | ||
| if (short.TryParse(strNum, style, NumberFormatInfo.InvariantInfo, out short s)) | ||
| { | ||
| result = s * (short)multiplier; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What result do we expect for multiplier = 1Mb?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At present, that will throw an error (too big for short value type) and is expected.
With some of the upcoming changes (that you can see if you build the version in the original PR) that instead simply registers as an invalid numeric literal, as I am able to verify first that the multiplier does not overflow the intended value type bounds without introducing a morass of if/else.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Closed under next PR.
| } | ||
| else if (suffix.HasFlag(NumberSuffixFlags.Unsigned) && ulong.TryParse(strNum, style, NumberFormatInfo.InvariantInfo, out ulong u)) | ||
| { | ||
| u *= (ulong)multiplier; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder that we define multiplier as long - I expect ulong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am also pondering that myself, but I've not seen a completely necessary need to change it. It does seem to simplify calculations against other signed types, however; unsigned types often need a cast one way or the other when doing multiplication with signed types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Closed.
| @{ Script = "0x100000000"; Expected = [int64]0x100000000 } | ||
| @{ Script = "0x100000000"; Expected = [int64]0x100000000 } | ||
| #Tests for short notation | ||
| @{ Script = "10s"; Expected = "10" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think now we should test not only value but target type too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is probably wise. I'll take some time over lunch to add tests for value types. :)
|
|
||
| $testInvalidNumerals = @( | ||
| @{ Script = "16p" } | ||
| @{ Script = "20ux" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we add 20x?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, if we want to. x is neither a valid type suffix nor a multiplier in PS, though, so testing for it is more or less the same as testing 16p at the moment. We could go through the alphabet if you want. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No :-) We should cover all code paths. Do we cover?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
x should result in an error. I'll pop it in. :)
| @{ Script = "21ss" } | ||
| @{ Script = "100ll" } | ||
| @{ Script = "150su" } | ||
| @{ Script = "10ds" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we add 10ud?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, good catch. Absolutely.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@iSazonov Also noting down now before I forget:
Presently the literal 0x10d is legal in PowerShell, although Decimal.TryParse() does not allow the hexadecimal syntax and that parse fails. Its actual return type is Int32.
I plan on fixing this as I go through the parser rewrite after this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0x10d - have we tests for it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, lol. I am clearly not quite up to speed this morning. Of course 0x10d is legal. D is a hexadecimal character... and that's exactly why decimals will never result from a hex literal ending in d. I'm gonna make a comment in the code that reflects this, because it's not immediately obvious why Decimal doesn't even bother to check for hex literals.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(and yes I believe there are tests for it, but I'll pop one in the type checks just to be sure.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added all these. :)
| result = null; | ||
| return false; | ||
| } | ||
| else if (suffix == NumberSuffixFlags.Short) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe we could replace one level of if-else-if with switch to get more readable code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, agreed. Sorted out. :)
|
PowerShell Committee approved this in #7509. |
Partially replace if stack with switches Add missing multiplier.
Apparently int16 * int16 always results in int32. Wat.
|
OK, pretty sure I got that short parsing sorted. I can understand doing operations in the console types can be freely converted, but if you're gonna specify |
|
Attempting... this always seems far messier than it should be. |
How did that even happen, seriously...
Partially replace if stack with switches Add missing multiplier.
Apparently int16 * int16 always results in int32. Wat.
Teach me to try to restructure the test file too much! ;)
Fix test cases for reals with certain suffixes
No, really, I have no idea how the heck this happened. It's gone now.
Because I cannot find a distinct commit that actually modified this file
…werShell into Tokenizer/TypeSuffixes
|
Okay... @iSazonov apologies about the mess. Not sure what it is with me and rebasing, but I've yet to manage to figure it out and get it done cleanly. The Linux build seems to be failing on some kind of permissions issue with that build environment, not sure what that's about. Everything else looks green, though. :) |
|
You should reset to your last commit and then rebase. |
PR Summary
This has been split off of #7509 at request of @iSazonov as that PR has become overly complex, and this portion of the PR was already approved by Powershell Committee.
Adds the following numeric literal suffixes:
Adds the following type accelerators:
[short][ushort][uint][ulong]And of course, adds tests for all the above.
PR Checklist
.h,.cpp,.cs,.ps1and.psm1files have the correct copyright headerWIP:to the beginning of the title and remove the prefix when the PR is ready.[feature]if the change is significant or affects feature tests