From 42cefb6f65f7d9ddb50f75e61c9c2bd5cfae1bf4 Mon Sep 17 00:00:00 2001 From: Yura Lazarev Date: Fri, 12 Jun 2026 21:30:06 +0200 Subject: [PATCH] fix: escape special characters in Char literals 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). --- lib/Language/PureScript/Backend/Lua.hs | 3 +- test/ps/golden/Golden/CharLiterals/Test.purs | 20 + .../Golden.CharLiterals.Test/corefn.json | 1 + .../Golden.CharLiterals.Test/eval/.gitignore | 1 + .../Golden.CharLiterals.Test/eval/golden.txt | 8 + .../output/Golden.CharLiterals.Test/golden.ir | 573 ++++++++++++++++++ .../Golden.CharLiterals.Test/golden.lua | 162 +++++ 7 files changed, 767 insertions(+), 1 deletion(-) create mode 100644 test/ps/golden/Golden/CharLiterals/Test.purs create mode 100644 test/ps/output/Golden.CharLiterals.Test/corefn.json create mode 100644 test/ps/output/Golden.CharLiterals.Test/eval/.gitignore create mode 100644 test/ps/output/Golden.CharLiterals.Test/eval/golden.txt create mode 100644 test/ps/output/Golden.CharLiterals.Test/golden.ir create mode 100644 test/ps/output/Golden.CharLiterals.Test/golden.lua diff --git a/lib/Language/PureScript/Backend/Lua.hs b/lib/Language/PureScript/Backend/Lua.hs index eaf7d24..31c230f 100644 --- a/lib/Language/PureScript/Backend/Lua.hs +++ b/lib/Language/PureScript/Backend/Lua.hs @@ -33,6 +33,7 @@ import Language.PureScript.Backend.Lua.Types qualified as Lua import Language.PureScript.Backend.Types (AppOrModule (..)) import Language.PureScript.Names (ModuleName (..), runModuleName) import Language.PureScript.Names qualified as PS +import Language.PureScript.PSString (decodeStringEscaping, mkString) import Path (Abs, Dir, Path) import Prelude hiding (exp, local) @@ -149,7 +150,7 @@ fromIR foreigns topLevelNames modname ir = case ir of IR.LiteralString _ann s → pure . Right $ Lua.String s IR.LiteralChar _ann c → - pure . Right $ Lua.String $ Text.singleton c + pure (Right (Lua.String (decodeStringEscaping (mkString (Text.singleton c))))) IR.LiteralBool _ann b → pure . Right $ Lua.Boolean b IR.LiteralArray _ann exprs → diff --git a/test/ps/golden/Golden/CharLiterals/Test.purs b/test/ps/golden/Golden/CharLiterals/Test.purs new file mode 100644 index 0000000..1b21e51 --- /dev/null +++ b/test/ps/golden/Golden/CharLiterals/Test.purs @@ -0,0 +1,20 @@ +-- Char literals must be escaped in generated Lua: an unescaped '\n' inside +-- a quoted Lua string splits it across lines, producing a chunk no Lua +-- interpreter can parse. +module Golden.CharLiterals.Test where + +import Prelude + +import Effect (Effect) +import Effect.Console (log) + +main :: Effect Unit +main = do + log (show '\n') + log (show '\t') + log (show '\r') + log (show '\'') + log (show '\\') + log (show 'a') + log (show ('\n' == '\n')) + log (show ('\t' < '\n')) diff --git a/test/ps/output/Golden.CharLiterals.Test/corefn.json b/test/ps/output/Golden.CharLiterals.Test/corefn.json new file mode 100644 index 0000000..6fbd271 --- /dev/null +++ b/test/ps/output/Golden.CharLiterals.Test/corefn.json @@ -0,0 +1 @@ +{"builtWith":"0.15.16","comments":[{"LineComment":" Char literals must be escaped in generated Lua: an unescaped '\\n' inside"},{"LineComment":" a quoted Lua string splits it across lines, producing a chunk no Lua"},{"LineComment":" interpreter can parse."}],"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"bindType":"NonRec","expression":{"abstraction":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[13,18],"start":[13,3]}},"type":"Var","value":{"identifier":"discard","moduleName":["Control","Bind"]}},"annotation":{"meta":{"metaType":"IsSyntheticApp"},"sourceSpan":{"end":[13,18],"start":[13,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"discardUnit","moduleName":["Control","Bind"]}},"type":"App"},"annotation":{"meta":{"metaType":"IsSyntheticApp"},"sourceSpan":{"end":[13,18],"start":[13,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"bindEffect","moduleName":["Effect"]}},"type":"App"},"identifier":"discard"},{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[13,12],"start":[13,8]}},"type":"Var","value":{"identifier":"show","moduleName":["Data","Show"]}},"annotation":{"meta":{"metaType":"IsSyntheticApp"},"sourceSpan":{"end":[13,17],"start":[13,8]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"showChar","moduleName":["Data","Show"]}},"type":"App"},"identifier":"show"},{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[19,12],"start":[19,8]}},"type":"Var","value":{"identifier":"show","moduleName":["Data","Show"]}},"annotation":{"meta":{"metaType":"IsSyntheticApp"},"sourceSpan":{"end":[19,27],"start":[19,8]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"showBoolean","moduleName":["Data","Show"]}},"type":"App"},"identifier":"show1"},{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[19,21],"start":[19,19]}},"type":"Var","value":{"identifier":"eq","moduleName":["Data","Eq"]}},"annotation":{"meta":{"metaType":"IsSyntheticApp"},"sourceSpan":{"end":[19,26],"start":[19,14]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"eqChar","moduleName":["Data","Eq"]}},"type":"App"},"identifier":"eq"},{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[20,20],"start":[20,19]}},"type":"Var","value":{"identifier":"lessThan","moduleName":["Data","Ord"]}},"annotation":{"meta":{"metaType":"IsSyntheticApp"},"sourceSpan":{"end":[20,25],"start":[20,14]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"ordChar","moduleName":["Data","Ord"]}},"type":"App"},"identifier":"lessThan"},{"annotation":{"meta":null,"sourceSpan":{"end":[11,20],"start":[11,1]}},"bindType":"NonRec","expression":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"discard","moduleName":["Golden","CharLiterals","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[13,18],"start":[13,3]}},"argument":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[13,6],"start":[13,3]}},"type":"Var","value":{"identifier":"log","moduleName":["Effect","Console"]}},"annotation":{"meta":null,"sourceSpan":{"end":[13,18],"start":[13,3]}},"argument":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"show","moduleName":["Golden","CharLiterals","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[13,17],"start":[13,8]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[13,17],"start":[13,13]}},"type":"Literal","value":{"literalType":"CharLiteral","value":"\n"}},"type":"App"},"type":"App"},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[13,18],"start":[13,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[13,18],"start":[13,3]}},"argument":"$__unused","body":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"discard","moduleName":["Golden","CharLiterals","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[14,18],"start":[14,3]}},"argument":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[14,6],"start":[14,3]}},"type":"Var","value":{"identifier":"log","moduleName":["Effect","Console"]}},"annotation":{"meta":null,"sourceSpan":{"end":[14,18],"start":[14,3]}},"argument":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"show","moduleName":["Golden","CharLiterals","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[14,17],"start":[14,8]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[14,17],"start":[14,13]}},"type":"Literal","value":{"literalType":"CharLiteral","value":"\t"}},"type":"App"},"type":"App"},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[14,18],"start":[14,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[14,18],"start":[14,3]}},"argument":"$__unused","body":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"discard","moduleName":["Golden","CharLiterals","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[15,18],"start":[15,3]}},"argument":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[15,6],"start":[15,3]}},"type":"Var","value":{"identifier":"log","moduleName":["Effect","Console"]}},"annotation":{"meta":null,"sourceSpan":{"end":[15,18],"start":[15,3]}},"argument":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"show","moduleName":["Golden","CharLiterals","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[15,17],"start":[15,8]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[15,17],"start":[15,13]}},"type":"Literal","value":{"literalType":"CharLiteral","value":"\r"}},"type":"App"},"type":"App"},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[15,18],"start":[15,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[15,18],"start":[15,3]}},"argument":"$__unused","body":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"discard","moduleName":["Golden","CharLiterals","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[16,18],"start":[16,3]}},"argument":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[16,6],"start":[16,3]}},"type":"Var","value":{"identifier":"log","moduleName":["Effect","Console"]}},"annotation":{"meta":null,"sourceSpan":{"end":[16,18],"start":[16,3]}},"argument":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"show","moduleName":["Golden","CharLiterals","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[16,17],"start":[16,8]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[16,17],"start":[16,13]}},"type":"Literal","value":{"literalType":"CharLiteral","value":"'"}},"type":"App"},"type":"App"},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[16,18],"start":[16,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[16,18],"start":[16,3]}},"argument":"$__unused","body":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"discard","moduleName":["Golden","CharLiterals","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[17,18],"start":[17,3]}},"argument":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[17,6],"start":[17,3]}},"type":"Var","value":{"identifier":"log","moduleName":["Effect","Console"]}},"annotation":{"meta":null,"sourceSpan":{"end":[17,18],"start":[17,3]}},"argument":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"show","moduleName":["Golden","CharLiterals","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[17,17],"start":[17,8]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[17,17],"start":[17,13]}},"type":"Literal","value":{"literalType":"CharLiteral","value":"\\"}},"type":"App"},"type":"App"},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[17,18],"start":[17,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[17,18],"start":[17,3]}},"argument":"$__unused","body":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"discard","moduleName":["Golden","CharLiterals","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[18,17],"start":[18,3]}},"argument":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[18,6],"start":[18,3]}},"type":"Var","value":{"identifier":"log","moduleName":["Effect","Console"]}},"annotation":{"meta":null,"sourceSpan":{"end":[18,17],"start":[18,3]}},"argument":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"show","moduleName":["Golden","CharLiterals","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[18,16],"start":[18,8]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[18,16],"start":[18,13]}},"type":"Literal","value":{"literalType":"CharLiteral","value":"a"}},"type":"App"},"type":"App"},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[18,17],"start":[18,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[18,17],"start":[18,3]}},"argument":"$__unused","body":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"discard","moduleName":["Golden","CharLiterals","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[19,28],"start":[19,3]}},"argument":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[19,6],"start":[19,3]}},"type":"Var","value":{"identifier":"log","moduleName":["Effect","Console"]}},"annotation":{"meta":null,"sourceSpan":{"end":[19,28],"start":[19,3]}},"argument":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"show1","moduleName":["Golden","CharLiterals","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[19,27],"start":[19,8]}},"argument":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"eq","moduleName":["Golden","CharLiterals","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[19,26],"start":[19,14]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[19,18],"start":[19,14]}},"type":"Literal","value":{"literalType":"CharLiteral","value":"\n"}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[19,26],"start":[19,14]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[19,26],"start":[19,22]}},"type":"Literal","value":{"literalType":"CharLiteral","value":"\n"}},"type":"App"},"type":"App"},"type":"App"},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[19,28],"start":[19,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[19,28],"start":[19,3]}},"argument":"$__unused","body":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[20,6],"start":[20,3]}},"type":"Var","value":{"identifier":"log","moduleName":["Effect","Console"]}},"annotation":{"meta":null,"sourceSpan":{"end":[20,27],"start":[20,3]}},"argument":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"show1","moduleName":["Golden","CharLiterals","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[20,26],"start":[20,8]}},"argument":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"lessThan","moduleName":["Golden","CharLiterals","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[20,25],"start":[20,14]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[20,18],"start":[20,14]}},"type":"Literal","value":{"literalType":"CharLiteral","value":"\t"}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[20,25],"start":[20,14]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[20,25],"start":[20,21]}},"type":"Literal","value":{"literalType":"CharLiteral","value":"\n"}},"type":"App"},"type":"App"},"type":"App"},"type":"Abs"},"type":"App"},"type":"Abs"},"type":"App"},"type":"Abs"},"type":"App"},"type":"Abs"},"type":"App"},"type":"Abs"},"type":"App"},"type":"Abs"},"type":"App"},"type":"Abs"},"type":"App"},"identifier":"main"}],"exports":["main"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[20,27],"start":[4,1]}},"moduleName":["Control","Bind"]},{"annotation":{"meta":null,"sourceSpan":{"end":[20,27],"start":[4,1]}},"moduleName":["Data","Eq"]},{"annotation":{"meta":null,"sourceSpan":{"end":[20,27],"start":[4,1]}},"moduleName":["Data","Ord"]},{"annotation":{"meta":null,"sourceSpan":{"end":[20,27],"start":[4,1]}},"moduleName":["Data","Show"]},{"annotation":{"meta":null,"sourceSpan":{"end":[20,27],"start":[4,1]}},"moduleName":["Effect"]},{"annotation":{"meta":null,"sourceSpan":{"end":[20,27],"start":[4,1]}},"moduleName":["Effect","Console"]},{"annotation":{"meta":null,"sourceSpan":{"end":[6,15],"start":[6,1]}},"moduleName":["Prelude"]},{"annotation":{"meta":null,"sourceSpan":{"end":[20,27],"start":[4,1]}},"moduleName":["Prim"]}],"moduleName":["Golden","CharLiterals","Test"],"modulePath":"golden/Golden/CharLiterals/Test.purs","reExports":{},"sourceSpan":{"end":[20,27],"start":[4,1]}} \ No newline at end of file diff --git a/test/ps/output/Golden.CharLiterals.Test/eval/.gitignore b/test/ps/output/Golden.CharLiterals.Test/eval/.gitignore new file mode 100644 index 0000000..d2dc29b --- /dev/null +++ b/test/ps/output/Golden.CharLiterals.Test/eval/.gitignore @@ -0,0 +1 @@ +actual.txt diff --git a/test/ps/output/Golden.CharLiterals.Test/eval/golden.txt b/test/ps/output/Golden.CharLiterals.Test/eval/golden.txt new file mode 100644 index 0000000..d4c9fd8 --- /dev/null +++ b/test/ps/output/Golden.CharLiterals.Test/eval/golden.txt @@ -0,0 +1,8 @@ +'\n' +'\t' +'\r' +'\'' +'\\' +'a' +true +true diff --git a/test/ps/output/Golden.CharLiterals.Test/golden.ir b/test/ps/output/Golden.CharLiterals.Test/golden.ir new file mode 100644 index 0000000..ac1a435 --- /dev/null +++ b/test/ps/output/Golden.CharLiterals.Test/golden.ir @@ -0,0 +1,573 @@ +UberModule + { uberModuleBindings = + [ Standalone + ( QName + { qnameModuleName = ModuleName "Effect", qnameName = Name "foreign" + }, ForeignImport Nothing + ( ModuleName "Effect" ) ".spago/effect/v4.1.0/src/Effect.purs" + [ ( Nothing, Name "pureE" ), ( Nothing, Name "bindE" ) ] + ), Standalone + ( QName + { qnameModuleName = ModuleName "Effect.Console", qnameName = Name "foreign" + }, ForeignImport Nothing + ( ModuleName "Effect.Console" ) ".spago/console/v6.1.0/src/Effect/Console.purs" + [ ( Nothing, Name "log" ) ] + ), Standalone + ( QName + { qnameModuleName = ModuleName "Data.Eq", qnameName = Name "eqChar" + }, LiteralObject Nothing + [ + ( PropName "eq", ObjectProp ( Just Always ) + ( ForeignImport Nothing + ( ModuleName "Data.Eq" ) ".spago/prelude/v7.2.0/src/Data/Eq.purs" + [ ( Nothing, Name "eqCharImpl" ) ] + ) + ( PropName "eqCharImpl" ) + ) + ] + ), Standalone + ( QName + { qnameModuleName = ModuleName "Data.Show", qnameName = Name "show" }, Abs Nothing + ( ParamNamed Nothing ( Name "dict" ) ) + ( ObjectProp Nothing ( Ref Nothing ( Local ( Name "dict" ) ) 0 ) ( PropName "show" ) ) + ), Standalone + ( QName + { qnameModuleName = ModuleName "Control.Applicative", qnameName = Name "pure" + }, Abs Nothing + ( ParamNamed Nothing ( Name "dict" ) ) + ( ObjectProp Nothing ( Ref Nothing ( Local ( Name "dict" ) ) 0 ) ( PropName "pure" ) ) + ), Standalone + ( QName + { qnameModuleName = ModuleName "Control.Bind", qnameName = Name "bind" }, Abs Nothing + ( ParamNamed Nothing ( Name "dict" ) ) + ( ObjectProp Nothing ( Ref Nothing ( Local ( Name "dict" ) ) 0 ) ( PropName "bind" ) ) + ), RecursiveGroup + ( + ( QName + { qnameModuleName = ModuleName "Effect", qnameName = Name "monadEffect" + }, LiteralObject Nothing + [ + ( PropName "Applicative0", Abs Nothing ( ParamUnused Nothing ) + ( Ref Nothing ( Imported ( ModuleName "Effect" ) ( Name "applicativeEffect" ) ) 0 ) + ), + ( PropName "Bind1", Abs Nothing ( ParamUnused Nothing ) + ( Ref Nothing ( Imported ( ModuleName "Effect" ) ( Name "bindEffect" ) ) 0 ) + ) + ] + ) :| + [ + ( QName + { qnameModuleName = ModuleName "Effect", qnameName = Name "bindEffect" + }, LiteralObject Nothing + [ + ( PropName "bind", ObjectProp ( Just Always ) + ( Ref Nothing ( Imported ( ModuleName "Effect" ) ( Name "foreign" ) ) 0 ) + ( PropName "bindE" ) + ), + ( PropName "Apply0", Abs Nothing ( ParamUnused Nothing ) + ( App Nothing + ( Ref Nothing + ( Imported ( ModuleName "Effect" ) ( Name "Lazy_applyEffect" ) ) 0 + ) + ( LiteralInt Nothing 0 ) + ) + ) + ] + ), + ( QName + { qnameModuleName = ModuleName "Effect", qnameName = Name "applicativeEffect" + }, LiteralObject Nothing + [ + ( PropName "pure", ObjectProp ( Just Always ) + ( Ref Nothing ( Imported ( ModuleName "Effect" ) ( Name "foreign" ) ) 0 ) + ( PropName "pureE" ) + ), + ( PropName "Apply0", Abs Nothing ( ParamUnused Nothing ) + ( App Nothing + ( Ref Nothing + ( Imported ( ModuleName "Effect" ) ( Name "Lazy_applyEffect" ) ) 0 + ) + ( LiteralInt Nothing 0 ) + ) + ) + ] + ), + ( QName + { qnameModuleName = ModuleName "Effect", qnameName = Name "Lazy_functorEffect" + }, App Nothing + ( App Nothing + ( Ref Nothing ( Local ( Name "PSLUA_runtime_lazy" ) ) 0 ) + ( LiteralString Nothing "functorEffect" ) + ) + ( Abs Nothing ( ParamUnused Nothing ) + ( LiteralObject Nothing + [ + ( PropName "map", Abs Nothing + ( ParamNamed Nothing ( Name "f" ) ) + ( Abs Nothing + ( ParamNamed Nothing ( Name "a" ) ) + ( App Nothing + ( App Nothing + ( ObjectProp Nothing + ( App Nothing + ( ObjectProp Nothing + ( Ref Nothing + ( Imported + ( ModuleName "Effect" ) + ( Name "applicativeEffect" ) + ) 0 + ) + ( PropName "Apply0" ) + ) + ( Ref Nothing + ( Imported ( ModuleName "Prim" ) ( Name "undefined" ) ) 0 + ) + ) + ( PropName "apply" ) + ) + ( App Nothing + ( App Nothing + ( Ref Nothing + ( Imported ( ModuleName "Control.Applicative" ) ( Name "pure" ) ) 0 + ) + ( Ref Nothing + ( Imported ( ModuleName "Effect" ) ( Name "applicativeEffect" ) ) 0 + ) + ) + ( Ref Nothing ( Local ( Name "f" ) ) 0 ) + ) + ) + ( Ref Nothing ( Local ( Name "a" ) ) 0 ) + ) + ) + ) + ] + ) + ) + ), + ( QName + { qnameModuleName = ModuleName "Effect", qnameName = Name "Lazy_applyEffect" + }, App Nothing + ( App Nothing + ( Ref Nothing ( Local ( Name "PSLUA_runtime_lazy" ) ) 0 ) + ( LiteralString Nothing "applyEffect" ) + ) + ( Abs Nothing ( ParamUnused Nothing ) + ( LiteralObject Nothing + [ + ( PropName "apply", Let Nothing + ( Standalone + ( Nothing, Name "bind", App Nothing + ( Ref Nothing + ( Imported ( ModuleName "Control.Bind" ) ( Name "bind" ) ) 0 + ) + ( App Nothing + ( ObjectProp Nothing + ( Ref Nothing + ( Imported ( ModuleName "Effect" ) ( Name "monadEffect" ) ) 0 + ) + ( PropName "Bind1" ) + ) + ( Ref Nothing ( Imported ( ModuleName "Prim" ) ( Name "undefined" ) ) 0 ) + ) + ) :| [] + ) + ( Abs Nothing + ( ParamNamed Nothing ( Name "f" ) ) + ( Abs Nothing + ( ParamNamed Nothing ( Name "a" ) ) + ( App Nothing + ( App Nothing + ( Ref Nothing ( Local ( Name "bind" ) ) 0 ) + ( Ref Nothing ( Local ( Name "f" ) ) 0 ) + ) + ( Abs Nothing + ( ParamNamed Nothing ( Name "f'" ) ) + ( App Nothing + ( App Nothing + ( Ref Nothing ( Local ( Name "bind" ) ) 0 ) + ( Ref Nothing ( Local ( Name "a" ) ) 0 ) + ) + ( Abs Nothing + ( ParamNamed Nothing ( Name "a'" ) ) + ( App Nothing + ( App Nothing + ( Ref Nothing + ( Imported + ( ModuleName "Control.Applicative" ) + ( Name "pure" ) + ) 0 + ) + ( App Nothing + ( ObjectProp Nothing + ( Ref Nothing + ( Imported + ( ModuleName "Effect" ) + ( Name "monadEffect" ) + ) 0 + ) + ( PropName "Applicative0" ) + ) + ( Ref Nothing + ( Imported ( ModuleName "Prim" ) ( Name "undefined" ) ) 0 + ) + ) + ) + ( App Nothing + ( Ref Nothing ( Local ( Name "f'" ) ) 0 ) + ( Ref Nothing ( Local ( Name "a'" ) ) 0 ) + ) + ) + ) + ) + ) + ) + ) + ) + ), + ( PropName "Functor0", Abs Nothing ( ParamUnused Nothing ) + ( App Nothing + ( Ref Nothing + ( Imported ( ModuleName "Effect" ) ( Name "Lazy_functorEffect" ) ) 0 + ) + ( LiteralInt Nothing 0 ) + ) + ) + ] + ) + ) + ) + ] + ), Standalone + ( QName + { qnameModuleName = ModuleName "Golden.CharLiterals.Test", qnameName = Name "discard" + }, App Nothing + ( ObjectProp Nothing + ( LiteralObject Nothing + [ + ( PropName "discard", Abs Nothing + ( ParamNamed Nothing ( Name "dictBind" ) ) + ( App Nothing + ( Ref Nothing ( Imported ( ModuleName "Control.Bind" ) ( Name "bind" ) ) 0 ) + ( Ref Nothing ( Local ( Name "dictBind" ) ) 0 ) + ) + ) + ] + ) + ( PropName "discard" ) + ) + ( Ref Nothing ( Imported ( ModuleName "Effect" ) ( Name "bindEffect" ) ) 0 ) + ), Standalone + ( QName + { qnameModuleName = ModuleName "Golden.CharLiterals.Test", qnameName = Name "show" + }, App Nothing + ( Ref Nothing ( Imported ( ModuleName "Data.Show" ) ( Name "show" ) ) 0 ) + ( LiteralObject Nothing + [ + ( PropName "show", ObjectProp ( Just Always ) + ( ForeignImport Nothing + ( ModuleName "Data.Show" ) ".spago/prelude/v7.2.0/src/Data/Show.purs" + [ ( Nothing, Name "showCharImpl" ) ] + ) + ( PropName "showCharImpl" ) + ) + ] + ) + ), Standalone + ( QName + { qnameModuleName = ModuleName "Golden.CharLiterals.Test", qnameName = Name "show1" + }, App Nothing + ( Ref Nothing ( Imported ( ModuleName "Data.Show" ) ( Name "show" ) ) 0 ) + ( LiteralObject Nothing + [ + ( PropName "show", Abs Nothing + ( ParamNamed Nothing ( Name "v" ) ) + ( IfThenElse Nothing + ( Ref Nothing ( Local ( Name "v" ) ) 0 ) + ( LiteralString Nothing "true" ) + ( IfThenElse Nothing + ( Eq Nothing ( LiteralBool Nothing False ) + ( Ref Nothing ( Local ( Name "v" ) ) 0 ) + ) + ( LiteralString Nothing "false" ) + ( Exception Nothing "No patterns matched" ) + ) + ) + ) + ] + ) + ) + ], uberModuleForeigns = [], uberModuleExports = + [ + ( Name "main", App Nothing + ( App Nothing + ( Ref Nothing + ( Imported ( ModuleName "Golden.CharLiterals.Test" ) ( Name "discard" ) ) 0 + ) + ( App Nothing + ( ObjectProp ( Just Always ) + ( Ref Nothing ( Imported ( ModuleName "Effect.Console" ) ( Name "foreign" ) ) 0 ) + ( PropName "log" ) + ) + ( App Nothing + ( Ref Nothing + ( Imported ( ModuleName "Golden.CharLiterals.Test" ) ( Name "show" ) ) 0 + ) + ( LiteralChar Nothing ' ' ) + ) + ) + ) + ( Abs Nothing ( ParamUnused Nothing ) + ( App Nothing + ( App Nothing + ( Ref Nothing + ( Imported ( ModuleName "Golden.CharLiterals.Test" ) ( Name "discard" ) ) 0 + ) + ( App Nothing + ( ObjectProp ( Just Always ) + ( Ref Nothing ( Imported ( ModuleName "Effect.Console" ) ( Name "foreign" ) ) 0 ) + ( PropName "log" ) + ) + ( App Nothing + ( Ref Nothing + ( Imported ( ModuleName "Golden.CharLiterals.Test" ) ( Name "show" ) ) 0 + ) + ( LiteralChar Nothing '\x9' ) + ) + ) + ) + ( Abs Nothing ( ParamUnused Nothing ) + ( App Nothing + ( App Nothing + ( Ref Nothing + ( Imported ( ModuleName "Golden.CharLiterals.Test" ) ( Name "discard" ) ) 0 + ) + ( App Nothing + ( ObjectProp ( Just Always ) + ( Ref Nothing + ( Imported ( ModuleName "Effect.Console" ) ( Name "foreign" ) ) 0 + ) + ( PropName "log" ) + ) + ( App Nothing + ( Ref Nothing + ( Imported ( ModuleName "Golden.CharLiterals.Test" ) ( Name "show" ) ) 0 + ) + ( LiteralChar Nothing '\xd' ) + ) + ) + ) + ( Abs Nothing ( ParamUnused Nothing ) + ( App Nothing + ( App Nothing + ( Ref Nothing + ( Imported ( ModuleName "Golden.CharLiterals.Test" ) ( Name "discard" ) ) 0 + ) + ( App Nothing + ( ObjectProp ( Just Always ) + ( Ref Nothing + ( Imported ( ModuleName "Effect.Console" ) ( Name "foreign" ) ) 0 + ) + ( PropName "log" ) + ) + ( App Nothing + ( Ref Nothing + ( Imported ( ModuleName "Golden.CharLiterals.Test" ) ( Name "show" ) ) 0 + ) + ( LiteralChar Nothing ''' ) + ) + ) + ) + ( Abs Nothing ( ParamUnused Nothing ) + ( App Nothing + ( App Nothing + ( Ref Nothing + ( Imported + ( ModuleName "Golden.CharLiterals.Test" ) + ( Name "discard" ) + ) 0 + ) + ( App Nothing + ( ObjectProp ( Just Always ) + ( Ref Nothing + ( Imported ( ModuleName "Effect.Console" ) ( Name "foreign" ) ) 0 + ) + ( PropName "log" ) + ) + ( App Nothing + ( Ref Nothing + ( Imported + ( ModuleName "Golden.CharLiterals.Test" ) + ( Name "show" ) + ) 0 + ) + ( LiteralChar Nothing '\' ) + ) + ) + ) + ( Abs Nothing ( ParamUnused Nothing ) + ( App Nothing + ( App Nothing + ( Ref Nothing + ( Imported + ( ModuleName "Golden.CharLiterals.Test" ) + ( Name "discard" ) + ) 0 + ) + ( App Nothing + ( ObjectProp ( Just Always ) + ( Ref Nothing + ( Imported + ( ModuleName "Effect.Console" ) + ( Name "foreign" ) + ) 0 + ) + ( PropName "log" ) + ) + ( App Nothing + ( Ref Nothing + ( Imported + ( ModuleName "Golden.CharLiterals.Test" ) + ( Name "show" ) + ) 0 + ) + ( LiteralChar Nothing 'a' ) + ) + ) + ) + ( Abs Nothing ( ParamUnused Nothing ) + ( App Nothing + ( App Nothing + ( Ref Nothing + ( Imported + ( ModuleName "Golden.CharLiterals.Test" ) + ( Name "discard" ) + ) 0 + ) + ( App Nothing + ( ObjectProp ( Just Always ) + ( Ref Nothing + ( Imported + ( ModuleName "Effect.Console" ) + ( Name "foreign" ) + ) 0 + ) + ( PropName "log" ) + ) + ( App Nothing + ( Ref Nothing + ( Imported + ( ModuleName "Golden.CharLiterals.Test" ) + ( Name "show1" ) + ) 0 + ) + ( App Nothing + ( App Nothing + ( ObjectProp Nothing + ( Ref Nothing + ( Imported + ( ModuleName "Data.Eq" ) + ( Name "eqChar" ) + ) 0 + ) + ( PropName "eq" ) + ) + ( LiteralChar Nothing ' ' ) + ) + ( LiteralChar Nothing ' ' ) + ) + ) + ) + ) + ( Abs Nothing ( ParamUnused Nothing ) + ( App Nothing + ( ObjectProp ( Just Always ) + ( Ref Nothing + ( Imported + ( ModuleName "Effect.Console" ) + ( Name "foreign" ) + ) 0 + ) + ( PropName "log" ) + ) + ( App Nothing + ( Ref Nothing + ( Imported + ( ModuleName "Golden.CharLiterals.Test" ) + ( Name "show1" ) + ) 0 + ) + ( IfThenElse Nothing + ( Eq Nothing + ( LiteralString Nothing "Data.Ordering∷Ordering.LT" ) + ( ReflectCtor Nothing + ( App Nothing + ( App Nothing + ( ObjectProp Nothing + ( LiteralObject Nothing + [ + ( PropName "compare", App Nothing + ( App Nothing + ( App Nothing + ( ObjectProp ( Just Always ) + ( ForeignImport Nothing + ( ModuleName "Data.Ord" ) ".spago/prelude/v7.2.0/src/Data/Ord.purs" + [ ( Nothing, Name "ordCharImpl" ) ] + ) + ( PropName "ordCharImpl" ) + ) + ( Ctor Nothing SumType + ( ModuleName "Data.Ordering" ) + ( TyName "Ordering" ) + ( CtorName "LT" ) [] + ) + ) + ( Ctor Nothing SumType + ( ModuleName "Data.Ordering" ) + ( TyName "Ordering" ) + ( CtorName "EQ" ) [] + ) + ) + ( Ctor Nothing SumType + ( ModuleName "Data.Ordering" ) + ( TyName "Ordering" ) + ( CtorName "GT" ) [] + ) + ), + ( PropName "Eq0", Abs Nothing ( ParamUnused Nothing ) + ( Ref Nothing + ( Imported + ( ModuleName "Data.Eq" ) + ( Name "eqChar" ) + ) 0 + ) + ) + ] + ) + ( PropName "compare" ) + ) + ( LiteralChar Nothing '\x9' ) + ) + ( LiteralChar Nothing ' ' ) + ) + ) + ) ( LiteralBool Nothing True ) ( LiteralBool Nothing False ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ] + } \ No newline at end of file diff --git a/test/ps/output/Golden.CharLiterals.Test/golden.lua b/test/ps/output/Golden.CharLiterals.Test/golden.lua new file mode 100644 index 0000000..c5e43fb --- /dev/null +++ b/test/ps/output/Golden.CharLiterals.Test/golden.lua @@ -0,0 +1,162 @@ +local function PSLUA_runtime_lazy(name) + return function(init) + return function() + local state = 0 + local val = nil + if state == 2 then + return val + else + if state == 1 then + return error(name .. " was needed before it finished initializing") + else + state = 1 + val = init() + state = 2 + return val + end + end + end + end +end +local M = {} +M.Effect_foreign = { + pureE = function(a) + return function() + return a + end + end, + bindE = function(a) + return function(f) + return function() + return f(a())() + end + end + end +} +M.Effect_Console_foreign = { + log = function(s) return function() print(s) end end +} +M.Data_Eq_eqChar = { + eq = ((function() + local refEq = function(r1) return function(r2) return r1 == r2 end end + return { eqCharImpl = refEq } + end)()).eqCharImpl +} +M.Data_Show_show = function(dict) return dict.show end +M.Control_Applicative_pure = function(dict) return dict.pure end +M.Control_Bind_bind = function(dict) return dict.bind end +M.Effect_monadEffect = { + Applicative0 = function() return M.Effect_applicativeEffect end, + Bind1 = function() return M.Effect_bindEffect end +} +M.Effect_bindEffect = { + bind = M.Effect_foreign.bindE, + Apply0 = function() return M.Effect_Lazy_applyEffect(0) end +} +M.Effect_applicativeEffect = { + pure = M.Effect_foreign.pureE, + Apply0 = function() return M.Effect_Lazy_applyEffect(0) end +} +M.Effect_Lazy_functorEffect = PSLUA_runtime_lazy("functorEffect")(function() + return { + map = function(f) + return function(a) + return (M.Effect_applicativeEffect.Apply0()).apply(M.Control_Applicative_pure(M.Effect_applicativeEffect)(f))(a) + end + end + } +end) +M.Effect_Lazy_applyEffect = PSLUA_runtime_lazy("applyEffect")(function() + return { + apply = (function() + return function(f) + local bind = M.Control_Bind_bind(M.Effect_monadEffect.Bind1()) + return function(a) + return bind(f)(function(fPrime) + return bind(a)(function(aPrime) + return M.Control_Applicative_pure(M.Effect_monadEffect.Applicative0())(fPrime(aPrime)) + end) + end) + end + end + end)(), + Functor0 = function() return M.Effect_Lazy_functorEffect(0) end + } +end) +M.Golden_CharLiterals_Test_discard = (function(dictBind) + return M.Control_Bind_bind(dictBind) +end)(M.Effect_bindEffect) +M.Golden_CharLiterals_Test_show = M.Data_Show_show({ + show = function(n) + local code = n:byte() + if code < 0x20 or code == 0x7F then + if n == "\x07" then return "'\\a'" end + if n == "\b" then return "'\\b'" end + if n == "\f" then return "'\\f'" end + if n == "\n" then return "'\\n'" end + if n == "\r" then return "'\\r'" end + if n == "\t" then return "'\\t'" end + if n == "\v" then return "'\\v'" end + return "'\\" .. code:toString(10) .. "'" + end + if n == "'" or n == "\\" then return "'\\" .. n .. "'" end + return "'" .. n .. "'" + end +}) +M.Golden_CharLiterals_Test_show1 = M.Data_Show_show({ + show = function(v) + if v then + return "true" + else + if false == v then + return "false" + else + return error("No patterns matched") + end + end + end +}) +return M.Golden_CharLiterals_Test_discard(M.Effect_Console_foreign.log(M.Golden_CharLiterals_Test_show("\n")))(function( ) + return M.Golden_CharLiterals_Test_discard(M.Effect_Console_foreign.log(M.Golden_CharLiterals_Test_show("\t")))(function( ) + return M.Golden_CharLiterals_Test_discard(M.Effect_Console_foreign.log(M.Golden_CharLiterals_Test_show("\r")))(function( ) + return M.Golden_CharLiterals_Test_discard(M.Effect_Console_foreign.log(M.Golden_CharLiterals_Test_show("\'")))(function( ) + return M.Golden_CharLiterals_Test_discard(M.Effect_Console_foreign.log(M.Golden_CharLiterals_Test_show("\\")))(function( ) + return M.Golden_CharLiterals_Test_discard(M.Effect_Console_foreign.log(M.Golden_CharLiterals_Test_show("a")))(function( ) + return M.Golden_CharLiterals_Test_discard(M.Effect_Console_foreign.log(M.Golden_CharLiterals_Test_show1(M.Data_Eq_eqChar.eq("\n")("\n"))))(function( ) + return M.Effect_Console_foreign.log(M.Golden_CharLiterals_Test_show1((function( ) + if "Data.Ordering∷Ordering.LT" == ((function() + local unsafeCoerceImpl = function(lt) + return function(eq) + return function(gt) + return function(x) + return function(y) + if x < y then + return lt + elseif x == y then + return eq + else + return gt + end + end + end + end + end + end + return { ordCharImpl = unsafeCoerceImpl } + end)()).ordCharImpl({ + ["$ctor"] = "Data.Ordering∷Ordering.LT" + })({ ["$ctor"] = "Data.Ordering∷Ordering.EQ" })({ + ["$ctor"] = "Data.Ordering∷Ordering.GT" + })("\t")("\n")["$ctor"] then + return true + else + return false + end + end)())) + end) + end) + end) + end) + end) + end) +end)()