Skip to content

fix: escape special characters in Char literals#48

Merged
Unisay merged 1 commit into
mainfrom
fix/char-literal-escaping
Jun 13, 2026
Merged

fix: escape special characters in Char literals#48
Unisay merged 1 commit into
mainfrom
fix/char-literal-escaping

Conversation

@Unisay

@Unisay Unisay commented Jun 13, 2026

Copy link
Copy Markdown
Collaborator

fix: escape special characters in Char literals

IR.LiteralString is escaped via decodeStringEscaping on the way in, but IR.LiteralChar was converted to a Lua string verbatim. A '\n' literal therefore landed as a raw newline inside a double-quoted Lua string, splitting it across two lines, and the chunk failed to load with unfinished string near '"'. Quote and backslash literals were affected the same way. Since this happens at parse time, a single such literal anywhere in a program makes the whole output file unloadable.

Found while reviving the test suite of purescript-lua-strings, whose toCharArray tests contain a '\n'.

Char literals now go through the same decodeStringEscaping as string literals. The new Golden.CharLiterals.Test golden locks this with an eval check over show of the escape-sensitive literals ('\n', '\t', '\r', '\'', '\\').

A Char literal compiled to a raw character inside a double-quoted Lua
string. For control characters this produces an unparseable chunk:
'\n' splits the string literal across lines, and stock Lua refuses
to load the file. Escape Char literals the same way String literals
are escaped (decodeStringEscaping).
@Unisay Unisay force-pushed the fix/char-literal-escaping branch from c2d8f9c to 42cefb6 Compare June 13, 2026 07:18
@Unisay Unisay marked this pull request as ready for review June 13, 2026 07:19

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes Lua code generation for PureScript Char literals so that escape-sensitive characters (e.g. '\n', '\\', '\'') are emitted as valid Lua string literals rather than raw characters that can break Lua parsing. It also adds a new golden test to lock in the behavior via an eval check.

Changes:

  • Update the Lua backend to escape IR.LiteralChar similarly to how string literals are handled.
  • Add a new Golden.CharLiterals.Test PureScript golden module covering escape-sensitive char literals.
  • Add corresponding golden artifacts (.lua, .ir, corefn.json, and eval expected output).

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.

Show a summary per file
File Description
lib/Language/PureScript/Backend/Lua.hs Changes IR.LiteralChar lowering to avoid emitting raw special characters into Lua string literals.
test/ps/golden/Golden/CharLiterals/Test.purs New golden test module exercising escape-sensitive char literals and comparisons.
test/ps/output/Golden.CharLiterals.Test/golden.lua Golden Lua output for the new test.
test/ps/output/Golden.CharLiterals.Test/golden.ir Golden IR output for the new test.
test/ps/output/Golden.CharLiterals.Test/corefn.json Golden CoreFn JSON for the new test.
test/ps/output/Golden.CharLiterals.Test/eval/golden.txt Expected eval output for the new golden test.
test/ps/output/Golden.CharLiterals.Test/eval/.gitignore Ignores eval runtime output (actual.txt).
Comments suppressed due to low confidence (1)

lib/Language/PureScript/Backend/Lua.hs:157

  • decodeStringEscaping emits PureScript-style \x escapes padded to 6 hex digits (see Language.PureScript.PSString.decodeStringEscaping), but Lua string literals require \x followed by exactly 2 hex digits. For char literals outside the explicit cases (\n, \t, \r, quotes, backslash), this will generate Lua source that parses to the wrong runtime value (e.g. \b, \f, \v, \0, or other non-printable/whitespace chars would become \x000008-style sequences). Consider escaping only the Lua-problematic characters here (preserving the prior behavior for everything else), or implement a Lua-specific string escaping routine that produces valid Lua escape sequences throughout.
  IR.LiteralChar _ann c →
    pure (Right (Lua.String (decodeStringEscaping (mkString (Text.singleton c)))))
  IR.LiteralBool _ann b →
    pure . Right $ Lua.Boolean b
  IR.LiteralArray _ann exprs →
    Right . Lua.table <$> forM (zip [1 ..] exprs) \(i, e) →

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@Unisay Unisay merged commit be59567 into main Jun 13, 2026
1 check passed
@Unisay Unisay deleted the fix/char-literal-escaping branch June 13, 2026 07:31
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.

2 participants