feat(optimizer): fold ordering on ASCII char literals (#222) - #288
Merged
Conversation
The constant folder evaluated equality on Char literals but left
ordering comparisons alone: Lua orders strings by bytes while the IR
literal carries a semantic codepoint, so a host-side compare could
disagree with the runtime on non-ASCII operands. For two codepoints
below U+0080 the single-byte Lua representation orders identically to
the codepoint, so compareLiterals (nee numericCompare — renamed now
that it handles chars) gains an arm gated on both operands being ASCII.
Non-ASCII chars and String literals stay unfolded; a dedicated unit
test pins both the ASCII fold and the non-ASCII/mixed bail-out. The
CharLiterals golden collapses its final runtime branch on a constant
"\t" < "\n" to log("true")(), with the eval oracle unchanged.
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.
Closes #222.
What
compareLiterals(nénumericCompare, renamed since it now handles more than numbers) gains one arm: ordering comparisons (<,<=,>,>=) on twoCharliterals fold at compile time when both codepoints are below U+0080.Why the ASCII gate
Note [Folding primops follows Lua 5.1] holds ordering back because Lua orders strings by bytes while the IR literal carries a semantic codepoint, so a host-side
comparecould disagree with the runtime on non-ASCII operands. For two ASCII chars the single-byte representation orders identically to the codepoint, so the fold matches the runtime exactly. Non-ASCII chars andStringliterals stay out of scope; the Note's comparison bullet is updated to record the refinement.Effect on the CharLiterals golden
The final
show ('\t' < '\n')used to compile to a runtime branch on a constant condition:With the fold in place the existing downstream rewrites cascade (
if true then LT else GT→LT,"…LT" == "…LT"→true,if true then "true"→"true") and the whole block collapses:The hand-verified eval oracle (
eval/golden.txt) is unchanged — the module still printstrue— so the collapse is semantics-preserving.Tests
Written test-first (red before the fix): a unit test pins the ASCII fold for all four operators, and a companion test pins the soundness guard — a non-ASCII pair (
'é' < 'ê') and a mixed pair ('a' < 'é') are left unfolded. Fullcabal test allis green, and the randomizedIR Optimizerspec group was stress-run 12 times on fresh seeds with no failures or hangs.