Skip to content

feat(optimizer): fold ordering on ASCII char literals (#222) - #288

Merged
Unisay merged 1 commit into
mainfrom
issue-222/fold-ascii-char-ordering
Jul 23, 2026
Merged

feat(optimizer): fold ordering on ASCII char literals (#222)#288
Unisay merged 1 commit into
mainfrom
issue-222/fold-ascii-char-ordering

Conversation

@Unisay

@Unisay Unisay commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

Closes #222.

What

compareLiterals (né numericCompare, renamed since it now handles more than numbers) gains one arm: ordering comparisons (<, <=, >, >=) on two Char literals fold at compile time when both codepoints are below U+0080.

(LiteralChar _ x, LiteralChar _ y)
  | isAscii x, isAscii y  Just (compare x y)

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 compare could 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 and String literals 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:

return Effect_Console_log((function()
  local v_S_221 = "\t" < "\n"
  if v_S_221 then
    return "true"
  elseif false == v_S_221 then
    return "false"
  else
    return error("No patterns matched")
  end
end)())()

With the fold in place the existing downstream rewrites cascade (if true then LT else GTLT, "…LT" == "…LT"true, if true then "true""true") and the whole block collapses:

return Effect_Console_log("true")()

The hand-verified eval oracle (eval/golden.txt) is unchanged — the module still prints true — 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. Full cabal test all is green, and the randomized IR Optimizer spec group was stress-run 12 times on fresh seeds with no failures or hangs.

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.
@Unisay Unisay self-assigned this Jul 23, 2026
@Unisay
Unisay merged commit 922c40a into main Jul 23, 2026
2 checks passed
@Unisay
Unisay deleted the issue-222/fold-ascii-char-ordering branch July 23, 2026 08:22
@Unisay
Unisay restored the issue-222/fold-ascii-char-ordering branch July 23, 2026 08:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Constant-fold ordering comparisons on ASCII Char literals

1 participant