-
Notifications
You must be signed in to change notification settings - Fork 397
Add hex/binary/octal support to String.toInt()
#1808
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
base: main
Are you sure you want to change the base?
Changes from all commits
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 |
|---|---|---|
|
|
@@ -835,7 +835,8 @@ public abstract static class toInt extends ExternalMethod0Node { | |
| @Specialization | ||
| protected long eval(String self) { | ||
| try { | ||
| return Long.parseLong(removeUnderlinesFromNumber(self)); | ||
| var negate = self.charAt(0) == '-'; | ||
| return VmUtils.parseInteger(negate ? self.substring(1) : self, negate, Long::parseLong); | ||
| } catch (NumberFormatException e) { | ||
| throw exceptionBuilder() | ||
| .evalError("cannotParseStringAs", "Int") | ||
|
|
@@ -850,7 +851,8 @@ public abstract static class toIntOrNull extends ExternalMethod0Node { | |
| @Specialization | ||
| protected Object eval(String self) { | ||
| try { | ||
| return Long.parseLong(removeUnderlinesFromNumber(self)); | ||
| var negate = self.charAt(0) == '-'; | ||
| return VmUtils.parseInteger(negate ? self.substring(1) : self, negate, Long::parseLong); | ||
|
Member
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.
One solution is to just reject any sequence after |
||
| } catch (NumberFormatException e) { | ||
| return VmNull.withoutDefault(); | ||
| } | ||
|
|
@@ -862,7 +864,7 @@ public abstract static class toFloat extends ExternalMethod0Node { | |
| @Specialization | ||
| protected double eval(String self) { | ||
| try { | ||
| return Double.parseDouble(removeUnderlinesFromNumber(self)); | ||
| return Double.parseDouble(VmUtils.removeUnderscoresFromNumber(self, false)); | ||
| } catch (NumberFormatException e) { | ||
| throw exceptionBuilder() | ||
| .evalError("cannotParseStringAs", "Float") | ||
|
|
@@ -877,7 +879,7 @@ public abstract static class toFloatOrNull extends ExternalMethod0Node { | |
| @Specialization | ||
| protected Object eval(String self) { | ||
| try { | ||
| return Double.parseDouble(removeUnderlinesFromNumber(self)); | ||
| return Double.parseDouble(VmUtils.removeUnderscoresFromNumber(self, false)); | ||
| } catch (NumberFormatException e) { | ||
| return VmNull.withoutDefault(); | ||
| } | ||
|
|
@@ -1031,23 +1033,4 @@ private static String applyMapper( | |
| var replacement = applyNode.executeString(mapper, regexMatch); | ||
| return Matcher.quoteReplacement(replacement); | ||
| } | ||
|
|
||
| /** | ||
| * Removes `_` from numbers to be parsed to be compatible with how Pkl parses numbers. Will return | ||
| * the string unmodified if it's invalid. | ||
| */ | ||
| private static String removeUnderlinesFromNumber(String number) { | ||
| var builder = new StringBuilder(); | ||
| var numberStart = true; | ||
| for (var i = 0; i < number.length(); i++) { | ||
| var c = number.charAt(i); | ||
| if (c != '_') { | ||
| builder.append(c); | ||
| } else if (numberStart) return number; | ||
|
|
||
| numberStart = c == '.' || c == 'e' || c == 'E'; | ||
| } | ||
|
|
||
| return builder.toString(); | ||
| } | ||
| } | ||
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.
This will throw if given an empty string.
Looks like we're missing this from our tests