Add hexadecimal integer literals (e.g. 0xFF) - #132
Open
gdisirio wants to merge 1 commit into
Open
Conversation
Whole numbers can now be written in hexadecimal notation, using the 0x (or 0X) prefix followed by hex digits, e.g. 0xFF for 255. This has been requested on the mailing list several times over the years (the previous workaround being to expose Integer.decode as a shared variable). The change is purely additive and backward compatible: in an expression, a sequence like "0xFF" was previously a parse error (a number immediately followed by an identifier), so no currently-valid template can be affected. The new HEX_INTEGER token is only active in the expression lexer states, never in plain template text. Hex literals specify whole numbers only; the sign can be applied as a separate operator (e.g. -0x10). There's no limit on the number of digits: the value is narrowed to an Integer if it fits into a 32-bit signed integer, to a Long if it fits into a 64-bit signed integer, and is kept as a BigInteger otherwise. Added JUnit coverage and a note in the Manual's "Direct specification of values" section (with @SInCE 2.3.35).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Whole numbers can now be written in hexadecimal notation, using an
0x(or0X) prefix followed by hex digits —0xFFis 255,0x100is 256.This has come up on the mailing list several times over the years; the usual workaround has been exposing
Integer.decodeas a shared variable. It's most useful when templates deal with values that are conventionally written in hex — bitmasks, hardware register values, colour constants, binary protocol fields — where decimal spellings obscure the intent.Backward compatibility
Purely additive. In an expression, a sequence like
0xFFwas previously a parse error (a number immediately followed by an identifier), so no currently-valid template can change meaning. The newHEX_INTEGERtoken is only active in the expression lexer states, never in plain template text.Range and representation
Hex literals specify whole numbers only — no fractional part, no exponent, no sign. A sign can still be applied as a separate operator, as in
-0x10.Values are narrowed to the smallest of
Integer/Longthat fits, and beyondLongrange they becomeBigInteger, so there is no arbitrary limit on the number of digits and no overflow error.One consequence worth flagging explicitly: this means hex literals do not go through
ArithmeticEngine.toNumber, so under the defaultBIGDECIMAL_ENGINEthe literal255yields aBigDecimalwhile0xFFyields anInteger. The two compare and arithmetically behave identically, but they are different Java types, which is observable if the value is passed to an overloaded Java method. I went this way because hex notation is inherently integral andInteger/Longis what callers doing mask arithmetic expect — but if you'd rather hex respect the configured arithmetic engine for consistency, that's a small change and I'm happy to make it.Testing & docs
HexLiteralTest: basic values, both prefix cases, use in expressions, assignment, comparison, and the Integer/Long/BigInteger boundaries.@since 2.3.35../gradlew checkand./gradlew manualOfflineboth pass.Relationship to #130
Independent of #130 — the two share no code. This changes only the lexer/parser (
FTL.jj); #130 changes only the string built-ins (BuiltIn.java,BuiltInsForStringsBasic.java). The one file both touch isbook.xml, and the hunks are about 10,000 lines apart (the expressions chapter vs. the built-ins reference). They merge cleanly in either order, so no coordination is needed.