├── .editorconfig ├── .envrc ├── .gitattributes ├── .github └── workflows │ └── ci.yaml ├── .gitignore ├── .hlint.yaml ├── .hspec-failures ├── LICENSE ├── README.md ├── Setup.hs ├── cabal.project ├── exe ├── Cli.hs └── Main.hs ├── flake.lock ├── flake.nix ├── fourmolu.yaml ├── hie.yaml ├── lib └── Language │ └── PureScript │ ├── Backend.hs │ ├── Backend │ ├── IR.hs │ ├── IR │ │ ├── DCE.hs │ │ ├── Inliner.hs │ │ ├── Linker.hs │ │ ├── Names.hs │ │ ├── Optimizer.hs │ │ ├── Query.hs │ │ └── Types.hs │ ├── Lua.hs │ ├── Lua │ │ ├── DCE.hs │ │ ├── Fixture.hs │ │ ├── Key.hs │ │ ├── Linker │ │ │ └── Foreign.hs │ │ ├── Name.hs │ │ ├── Optimizer.hs │ │ ├── Printer.hs │ │ ├── Traversal.hs │ │ └── Types.hs │ └── Types.hs │ ├── Comments.hs │ ├── CoreFn.hs │ ├── CoreFn │ ├── Expr.hs │ ├── FromJSON.hs │ ├── Laziness.hs │ ├── Meta.hs │ ├── Module.hs │ ├── Reader.hs │ └── Traversals.hs │ ├── Names.hs │ └── PSString.hs ├── pslua.cabal ├── scripts ├── golden_reset └── prepare_release ├── shell.nix ├── test ├── Hedgehog │ └── Gen │ │ └── Extended.hs ├── Language │ └── PureScript │ │ └── Backend │ │ ├── IR │ │ ├── DCE │ │ │ └── Spec.hs │ │ ├── Gen.hs │ │ ├── Inliner │ │ │ └── Spec.hs │ │ ├── Optimizer │ │ │ └── Spec.hs │ │ ├── Spec.hs │ │ └── Types │ │ │ └── Spec.hs │ │ └── Lua │ │ ├── DCE │ │ └── Spec.hs │ │ ├── Gen.hs │ │ ├── Golden │ │ └── Spec.hs │ │ ├── Linker │ │ └── Foreign │ │ │ └── Spec.hs │ │ ├── Optimizer │ │ └── Spec.hs │ │ └── Printer │ │ └── Spec.hs ├── Main.hs ├── Test │ └── Hspec │ │ ├── Expectations │ │ └── Pretty.hs │ │ ├── Extra.hs │ │ ├── Golden.hs │ │ └── Hedgehog │ │ └── Extended.hs └── ps │ ├── .gitignore │ ├── golden │ └── Golden │ │ ├── Annotations │ │ ├── M1.lua │ │ ├── M1.purs │ │ └── M2.purs │ │ ├── ArrayOfUnits │ │ └── Test.purs │ │ ├── Beta │ │ └── Test.purs │ │ ├── Bug1 │ │ └── Test.purs │ │ ├── CaseStatements │ │ └── Test.purs │ │ ├── Currying │ │ └── Test.purs │ │ ├── DataDeclarations │ │ ├── Test1.purs │ │ └── Test2.purs │ │ ├── Fibonacci │ │ └── Test.purs │ │ ├── Foreign │ │ ├── Lib.lua │ │ ├── Lib.purs │ │ ├── Test.lua │ │ └── Test.purs │ │ ├── HelloPrelude │ │ └── Test.purs │ │ ├── Inline │ │ └── Test.purs │ │ ├── NameShadowing │ │ └── Test.purs │ │ ├── Nested │ │ └── Test.purs │ │ ├── Newtype │ │ └── Test.purs │ │ ├── PatternMatching │ │ ├── Test1.purs │ │ └── Test2.purs │ │ ├── RecDataDefs │ │ └── Test.purs │ │ ├── RecordsAccess │ │ └── Test.purs │ │ ├── RecordsUpdate │ │ └── Test.purs │ │ ├── RecursiveBindings │ │ └── Test.purs │ │ ├── Reexport │ │ ├── Exports.purs │ │ ├── ReExports.purs │ │ └── Test.purs │ │ ├── ReturnTableField │ │ ├── Test.lua │ │ └── Test.purs │ │ ├── Unbinding │ │ └── Test.purs │ │ └── Values │ │ └── Test.purs │ ├── output │ ├── Golden.Annotations.M1 │ │ ├── corefn.json │ │ ├── golden.ir │ │ └── golden.lua │ ├── Golden.Annotations.M2 │ │ ├── corefn.json │ │ ├── golden.ir │ │ └── golden.lua │ ├── Golden.ArrayOfUnits.Test │ │ ├── corefn.json │ │ ├── eval │ │ │ ├── .gitignore │ │ │ └── golden.txt │ │ ├── golden.ir │ │ └── golden.lua │ ├── Golden.Beta.Test │ │ ├── corefn.json │ │ ├── golden.ir │ │ └── golden.lua │ ├── Golden.Bug1.Test │ │ ├── corefn.json │ │ ├── golden.ir │ │ └── golden.lua │ ├── Golden.CaseStatements.Test │ │ ├── corefn.json │ │ ├── golden.ir │ │ └── golden.lua │ ├── Golden.Currying.Test │ │ ├── corefn.json │ │ ├── golden.ir │ │ └── golden.lua │ ├── Golden.DataDeclarations.Test1 │ │ ├── corefn.json │ │ ├── golden.ir │ │ └── golden.lua │ ├── Golden.DataDeclarations.Test2 │ │ ├── corefn.json │ │ ├── golden.ir │ │ └── golden.lua │ ├── Golden.Fibonacci.Test │ │ ├── corefn.json │ │ ├── eval │ │ │ ├── .gitignore │ │ │ └── golden.txt │ │ ├── golden.ir │ │ └── golden.lua │ ├── Golden.Foreign.Lib │ │ ├── corefn.json │ │ ├── golden.ir │ │ └── golden.lua │ ├── Golden.Foreign.Test │ │ ├── corefn.json │ │ ├── golden.ir │ │ └── golden.lua │ ├── Golden.HelloPrelude.Test │ │ ├── corefn.json │ │ ├── golden.ir │ │ └── golden.lua │ ├── Golden.Inline.Test │ │ ├── corefn.json │ │ ├── golden.ir │ │ └── golden.lua │ ├── Golden.NameShadowing.Test │ │ ├── corefn.json │ │ ├── golden.ir │ │ └── golden.lua │ ├── Golden.Nested.Test │ │ ├── corefn.json │ │ ├── golden.ir │ │ └── golden.lua │ ├── Golden.Newtype.Test │ │ ├── corefn.json │ │ ├── golden.ir │ │ └── golden.lua │ ├── Golden.PatternMatching.Test1 │ │ ├── corefn.json │ │ ├── golden.ir │ │ └── golden.lua │ ├── Golden.PatternMatching.Test2 │ │ ├── corefn.json │ │ ├── golden.ir │ │ └── golden.lua │ ├── Golden.RecDataDefs.Test │ │ ├── corefn.json │ │ ├── golden.ir │ │ └── golden.lua │ ├── Golden.RecordsAccess.Test │ │ ├── corefn.json │ │ ├── golden.ir │ │ └── golden.lua │ ├── Golden.RecordsUpdate.Test │ │ ├── corefn.json │ │ ├── golden.ir │ │ └── golden.lua │ ├── Golden.RecursiveBindings.Test │ │ ├── corefn.json │ │ ├── golden.ir │ │ └── golden.lua │ ├── Golden.Reexport.Exports │ │ ├── corefn.json │ │ ├── golden.ir │ │ └── golden.lua │ ├── Golden.Reexport.ReExports │ │ ├── corefn.json │ │ ├── golden.ir │ │ └── golden.lua │ ├── Golden.Reexport.Test │ │ ├── corefn.json │ │ ├── golden.ir │ │ └── golden.lua │ ├── Golden.TestReturnTableField │ │ ├── corefn.json │ │ ├── golden.ir │ │ └── golden.lua │ ├── Golden.Unbinding.Test │ │ ├── corefn.json │ │ ├── golden.ir │ │ └── golden.lua │ └── Golden.Values.Test │ │ ├── corefn.json │ │ ├── golden.ir │ │ └── golden.lua │ ├── packages.dhall │ └── spago.dhall └── treefmt.toml /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | indent_style = space 7 | indent_size = 2 8 | end_of_line = lf 9 | charset = utf-8 10 | trim_trailing_whitespace = true 11 | insert_final_newline = true 12 | -------------------------------------------------------------------------------- /.envrc: -------------------------------------------------------------------------------- 1 | use flake 2 | PATH_add ./scripts 3 | [[ -f .envrc.local ]] && source_env .envrc.local 4 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | flake.lock linguist-generated=true 2 | -------------------------------------------------------------------------------- /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: Purescript Lua CI 2 | on: 3 | push: 4 | branches: [main] 5 | pull_request: 6 | jobs: 7 | tests: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: "📥 Checkout repository" 11 | uses: actions/checkout@v4 12 | - name: "❄ Install Nix" 13 | uses: cachix/install-nix-action@v26 14 | with: 15 | github_access_token: ${{ secrets.GITHUB_TOKEN }} 16 | extra_nix_config: | 17 | access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} 18 | substituters = https://hydra.iohk.io https://cache.nixos.org/ 19 | trusted-public-keys = hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= 20 | - uses: cachix/cachix-action@v14 21 | with: 22 | name: purescript-lua 23 | authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" 24 | - name: "🔨 Build & test" 25 | run: >- 26 | nix develop --accept-flake-config --allow-import-from-derivation --command cabal test all --test-show-details=direct 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | dist-* 3 | cabal.project.local 4 | cabal.project.local~ 5 | result 6 | result-* 7 | .direnv 8 | .psc-ide-port 9 | /output/ 10 | .vscode/settings.json 11 | .envrc.local 12 | -------------------------------------------------------------------------------- /.hlint.yaml: -------------------------------------------------------------------------------- 1 | # HLint configuration file 2 | # https://github.com/ndmitchell/hlint 3 | ########################## 4 | 5 | # This file contains a template configuration file, which is typically 6 | # placed as .hlint.yaml in the root of your project 7 | 8 | # Specify additional command line arguments 9 | # 10 | - arguments: [--color, --cpp-simple, -XQuasiQuotes, -XImportQualifiedPost] 11 | # Control which extensions/flags/modules/functions can be used 12 | # 13 | - extensions: 14 | # - default: false # all extension are banned by default 15 | - name: 16 | - NoStarIsType 17 | - ApplicativeDo 18 | - BangPatterns 19 | - BlockArguments 20 | - ConstraintKinds 21 | - DataKinds 22 | - DeriveDataTypeable 23 | - DeriveFoldable 24 | - DeriveFunctor 25 | - DeriveGeneric 26 | - DeriveLift 27 | - DeriveTraversable 28 | - DerivingStrategies 29 | - DerivingVia 30 | - EmptyCase 31 | - EmptyDataDecls 32 | - EmptyDataDeriving 33 | - ExistentialQuantification 34 | - ExplicitForAll 35 | - FlexibleContexts 36 | - FlexibleInstances 37 | - GADTSyntax 38 | - GeneralisedNewtypeDeriving 39 | - ImportQualifiedPost 40 | - KindSignatures 41 | - LambdaCase 42 | - MultiParamTypeClasses 43 | - MultiWayIf 44 | - NumericUnderscores 45 | - OverloadedStrings 46 | - PolyKinds 47 | - PostfixOperators 48 | - RankNTypes 49 | - RecordWildCards 50 | - ScopedTypeVariables 51 | - StandaloneDeriving 52 | - StandaloneKindSignatures 53 | - TupleSections 54 | - TypeApplications 55 | - TypeFamilies 56 | - TypeOperators 57 | - ViewPatterns, 58 | # - { name: CPP, within: CrossPlatform } # CPP can only be used in a given module 59 | # 60 | # - flags: 61 | # - {name: -w, within: []} # -w is allowed nowhere 62 | # 63 | # - modules: 64 | # - {name: [Data.Set, Data.HashSet], as: Set} # if you import Data.Set qualified, it must be as 'Set' 65 | # - {name: Control.Arrow, within: []} # Certain modules are banned entirely 66 | # 67 | # - functions: 68 | # - {name: unsafePerformIO, within: []} # unsafePerformIO can only appear in no modules 69 | 70 | # Add custom hints for this project 71 | # 72 | # Will suggest replacing "wibbleMany [myvar]" with "wibbleOne myvar" 73 | # - error: {lhs: "wibbleMany [x]", rhs: wibbleOne x} 74 | 75 | # The hints are named by the string they display in warning messages. 76 | # For example, if you see a warning starting like 77 | # 78 | # Main.hs:116:51: Warning: Redundant == 79 | # 80 | # You can refer to that hint with `{name: Redundant ==}` (see below). 81 | 82 | # Turn on hints that are off by default 83 | # 84 | # Ban "module X(module X) where", to require a real export list 85 | # - warn: {name: Use explicit module export list} 86 | # 87 | # Replace a $ b $ c with a . b $ c 88 | # - group: {name: dollar, enabled: true} 89 | # 90 | # Generalise map to fmap, ++ to <> 91 | # - group: {name: generalise, enabled: true} 92 | 93 | # Ignore some builtin hints 94 | # - ignore: {name: Use let} 95 | # - ignore: {name: Use const, within: SpecialModule} # Only within certain modules 96 | 97 | # Define some custom infix operators 98 | # - fixity: infixr 3 ~^#^~ 99 | 100 | # To generate a suitable file for HLint do: 101 | # $ hlint --default > .hlint.yaml 102 | -------------------------------------------------------------------------------- /.hspec-failures: -------------------------------------------------------------------------------- 1 | FailureReport {failureReportSeed = 781992162, failureReportMaxSuccess = 100, failureReportMaxSize = 100, failureReportMaxDiscardRatio = 10, failureReportPaths = []} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Purescript Backend for Lua 2 | 3 | [![Purescript Lua CI](https://github.com/Unisay/purescript-lua/actions/workflows/ci.yaml/badge.svg)](https://github.com/Unisay/purescript-lua/actions/workflows/ci.yaml) 4 | 5 | 🔋 Status: (2024-04-20) the project is in the "_ready to be experimented with_" state (read: it likely contains bugs but is already usable). 6 | 7 | 💡 If you have an idea on how to use Purescript to Lua compilation please contribute it here: 8 | https://github.com/Unisay/purescript-lua/discussions/categories/ideas 9 | 10 | ## Features 11 | 12 | - [x] Lua code bundling: emits either a Lua module (a file that returns a table with functions) or an application (a file that executes itself). 13 | - [x] FFI with Lua. 14 | - [x] Dead Code Elimination (DCE). 15 | - [x] Code inlining. 16 | - [x] [Package Set](https://github.com/Unisay/purescript-lua-package-sets) for PureScript/Lua libs. 17 | - [x] All core libs added to the package set. 18 | 19 | ## Quick Start 20 | 21 | For the moment the best way to start is to use `nix` to intall `pslua`. 22 | 23 | Consider configuring [Cachix](https://docs.cachix.org/installation) as a binary nix cache to avoid rebuilding a ton of dependencies: 24 | 25 | ``` 26 | cachix use purescript-lua 27 | ``` 28 | You can use this [template repository](https://github.com/Unisay/purescript-lua-template) to initialize your project. 29 | 30 | Here is an another [example](https://github.com/Unisay/purescript-lua-example) project: Nginx server running Lua code using [OpenResty](https://openresty.org/). 31 | 32 | If you use [Spago](https://github.com/purescript/spago) to build your PureScript project, then you can configure `pslua` as a custom backend like this: 33 | 34 |
spago.dhall 35 | 36 | Assuming that `pslua` executable is already available on your PATH 37 | 38 | ```dhall 39 | { name = "acme-project" 40 | , dependencies = [ "effect", "prelude" ] 41 | , packages = ./packages.dhall 42 | , sources = [ "src/**/*.purs" ] 43 | , backend = 44 | '' 45 | pslua \ 46 | --foreign-path . \ 47 | --ps-output output \ 48 | --lua-output-file dist/Acme_Main.lua \ 49 | --entry Acme.Main 50 | '' 51 | } 52 | ``` 53 | 54 |
55 | 56 | ### Using nix with flakes 57 | 58 | ``` 59 | nix run 'github:Unisay/purescript-lua' -- --help 60 | ``` 61 | 62 | ## Installation 63 | 64 | If you're on a x86 64bit Linux system then you can download a pre-built executable from the [releases](https://github.com/Unisay/purescript-lua/releases) page: 65 | 66 | ``` 67 | wget -c https://github.com/Unisay/purescript-lua/releases/download/0.1.1-alpha/pslua-linux_x86_64.tar.gz -O - | tar -xz 68 | ``` 69 | 70 | alternatively, 71 | 72 | ### Using nix with flakes 73 | 74 | ``` 75 | nix profile install 'github:Unisay/purescript-lua' 76 | ``` 77 | 78 | will make `pslua` executable available for use. 79 | 80 | ### Windows 81 | 82 | Nix build won't work on Windows so you'd first need to install 83 | `cabal` and `ghc-9.4.8` (One way of installing those is [GHCUp](https://www.haskell.org/ghcup/)). 84 | 85 | Once the pre-requisites are available on your PATH 86 | you run 87 | 88 | ``` 89 | cabal install exe:pslua 90 | 91 | .... elided .... 92 | 93 | Installing commutative-semigroups-0.1.0.1 (lib) 94 | Installing primes-0.2.1.0 (all, legacy fallback) 95 | Installing base16-bytestring-1.0.2.0 (lib) 96 | Installing quiet-0.2 (lib) 97 | Completed newtype-0.2.2.0 (lib) 98 | 99 | .... elided .... 100 | 101 | Starting pslua-0.1.0.0 (exe:pslua) 102 | Building pslua-0.1.0.0 (exe:pslua) 103 | Installing pslua-0.1.0.0 (exe:pslua) 104 | Completed pslua-0.1.0.0 (exe:pslua) 105 | Copying 'pslua.exe' to 'C:\cabal\bin\pslua.exe' 106 | ``` 107 | 108 | This will build and install executable `pslua.exe` 109 | 110 | ``` 111 | C:\cabal\bin\pslua --help 112 | pslua - a PureScript backend for Lua 113 | 114 | Usage: pslua.exe [--foreign-path FOREIGN-PATH] [--ps-output PS-PATH] 115 | [--lua-output-file LUA-OUT-FILE] [-e|--entry ENTRY] 116 | 117 | Compile PureScript's CoreFn to Lua 118 | 119 | Available options: 120 | --foreign-path FOREIGN-PATH 121 | Path to a directory containing foreign files. 122 | Default: foreign 123 | --ps-output PS-PATH Path to purs output directory. 124 | Default: output 125 | --lua-output-file LUA-OUT-FILE 126 | Path to write compiled Lua file to. 127 | Default: main.lua 128 | -e,--entry ENTRY Where to start compilation. 129 | Could be one of the following formats: 130 | - Application format: . 131 | Example: Acme.App.main 132 | - Module format: 133 | Example: Acme.Lib 134 | Default: Main.main 135 | -h,--help Show this help text 136 | ``` 137 | -------------------------------------------------------------------------------- /Setup.hs: -------------------------------------------------------------------------------- 1 | module Main (main) where 2 | 3 | import Distribution.Simple 4 | 5 | main ∷ IO () 6 | main = defaultMain 7 | -------------------------------------------------------------------------------- /cabal.project: -------------------------------------------------------------------------------- 1 | packages: *.cabal 2 | tests: True 3 | -------------------------------------------------------------------------------- /exe/Main.hs: -------------------------------------------------------------------------------- 1 | module Main where 2 | 3 | import Cli (Args (luaOutputFile), ExtraOutput (..)) 4 | import Cli qualified 5 | import Control.Monad.Oops qualified as Oops 6 | import Data.Tagged (Tagged (..)) 7 | import Language.PureScript.Backend (CompilationResult (..)) 8 | import Language.PureScript.Backend qualified as Backend 9 | import Language.PureScript.Backend.IR qualified as IR 10 | import Language.PureScript.Backend.Lua qualified as Lua 11 | import Language.PureScript.Backend.Lua.Printer qualified as Printer 12 | import Language.PureScript.CoreFn.Reader qualified as CoreFn 13 | import Language.PureScript.Names (runIdent, runModuleName) 14 | import Main.Utf8 qualified as Utf8 15 | import Path (Abs, Dir, Path, SomeBase (..), replaceExtension, toFilePath) 16 | import Path.IO qualified as Path 17 | import Prettyprinter (defaultLayoutOptions, layoutPretty) 18 | import Prettyprinter.Render.Text (renderIO) 19 | import Text.Pretty.Simple (pHPrint) 20 | 21 | main ∷ IO () 22 | main = Utf8.withUtf8 do 23 | Cli.Args 24 | { foreignPath 25 | , luaOutputFile 26 | , outputIR 27 | , outputLuaAst 28 | , psOutputPath 29 | , appOrModule 30 | } ← 31 | Cli.parseArguments 32 | 33 | foreignDir ∷ Tagged "foreign" (Path Abs Dir) ← 34 | Tagged 35 | <$> case unTagged foreignPath of 36 | Path.Abs a → pure a 37 | Path.Rel r → Path.makeAbsolute r 38 | 39 | luaOutput ← 40 | case unTagged luaOutputFile of 41 | Path.Abs a → pure a 42 | Path.Rel r → Path.makeAbsolute r 43 | 44 | let extraOutputs = catMaybes [outputLuaAst, outputIR] 45 | 46 | CompilationResult {lua, ir} ← do 47 | putTextLn "PS Lua: compiling ..." 48 | Backend.compileModules psOutputPath foreignDir appOrModule 49 | & handleModuleNotFoundError 50 | & handleModuleDecodingError 51 | & handleCoreFnError 52 | & handleLuaError 53 | & Oops.runOops 54 | 55 | let outputFile = toFilePath luaOutput 56 | withFile outputFile WriteMode \h → 57 | renderIO h . layoutPretty defaultLayoutOptions $ 58 | Printer.printLuaChunk lua 59 | 60 | when (OutputIR `elem` extraOutputs) do 61 | irOutputFile ← toFilePath <$> replaceExtension ".ir" luaOutput 62 | withFile irOutputFile WriteMode (`pHPrint` ir) 63 | putTextLn $ "Wrote IR to " <> toText irOutputFile 64 | 65 | when (OutputLuaAst `elem` extraOutputs) do 66 | luaAstOutputFile ← toFilePath <$> replaceExtension ".lua-ast" luaOutput 67 | withFile luaAstOutputFile WriteMode (`pHPrint` lua) 68 | putTextLn $ "Wrote Lua AST to " <> toText luaAstOutputFile 69 | 70 | putTextLn $ "Wrote linked modules to " <> toText outputFile 71 | 72 | -------------------------------------------------------------------------------- 73 | -- Error handlers -------------------------------------------------------------- 74 | 75 | handleModuleNotFoundError 76 | ∷ ExceptT (Oops.Variant (CoreFn.ModuleNotFound ': e)) IO a 77 | → ExceptT (Oops.Variant e) IO a 78 | handleModuleNotFoundError = Oops.catch \(CoreFn.ModuleNotFound p) → 79 | die . toString . unlines $ 80 | [ "Can't find CoreFn module file: " <> toText (toFilePath p) 81 | , "Please make sure you did run purs with the `-g corefn` arg." 82 | ] 83 | 84 | handleModuleDecodingError 85 | ∷ ExceptT (Oops.Variant (CoreFn.ModuleDecodingErr ': e)) IO a 86 | → ExceptT (Oops.Variant e) IO a 87 | handleModuleDecodingError = Oops.catch \(CoreFn.ModuleDecodingErr p e) → 88 | die . toString . unlines $ 89 | [ "Can't parse CoreFn module file: " <> toText (toFilePath p) 90 | , toText e 91 | ] 92 | 93 | handleCoreFnError 94 | ∷ ExceptT (Oops.Variant (IR.CoreFnError ': e)) IO a 95 | → ExceptT (Oops.Variant e) IO a 96 | handleCoreFnError = 97 | Oops.catch \(e ∷ IR.CoreFnError) → 98 | die $ "CoreFn contains an unexpected value " <> show e 99 | 100 | handleLuaError 101 | ∷ ExceptT (Oops.Variant (Lua.Error ': e)) IO a 102 | → ExceptT (Oops.Variant e) IO a 103 | handleLuaError = 104 | Oops.catch \case 105 | Lua.UnexpectedRefBound modname expr → 106 | die . toString . unwords $ 107 | [ "Unexpected bound reference:" 108 | , show expr 109 | , "in module" 110 | , runModuleName modname 111 | ] 112 | Lua.LinkerErrorForeign e → 113 | die $ "Linker error:\n" <> show e 114 | Lua.AppEntryPointNotFound modname ident → 115 | die . toString $ 116 | "App entry point not found: " 117 | <> runModuleName modname 118 | <> "." 119 | <> runIdent ident 120 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | inputs = { 3 | haskellNix.url = "github:input-output-hk/haskell.nix"; 4 | nixpkgs.follows = "haskellNix/nixpkgs-unstable"; 5 | flake-utils.url = "github:numtide/flake-utils"; 6 | easy-purescript-nix.url = "github:justinwoo/easy-purescript-nix"; 7 | }; 8 | outputs = 9 | { 10 | self, 11 | nixpkgs, 12 | flake-utils, 13 | haskellNix, 14 | easy-purescript-nix, 15 | }: 16 | let 17 | supportedSystems = [ "x86_64-linux" ]; 18 | in 19 | flake-utils.lib.eachSystem supportedSystems ( 20 | system: 21 | let 22 | easy-ps = easy-purescript-nix.packages.${system}; 23 | pkgs = import nixpkgs { 24 | inherit system overlays; 25 | inherit (haskellNix) config; 26 | }; 27 | overlays = [ 28 | haskellNix.overlay 29 | (final: prev: { 30 | psluaProject = final.haskell-nix.project' { 31 | src = ./.; 32 | compiler-nix-name = "ghc98"; 33 | evalSystem = "x86_64-linux"; 34 | modules = 35 | let 36 | prof = false; 37 | in 38 | [ 39 | { 40 | doHaddock = false; 41 | doHoogle = false; 42 | enableProfiling = prof; 43 | enableLibraryProfiling = prof; 44 | } 45 | ]; 46 | 47 | name = "purescript-lua"; 48 | 49 | shell = { 50 | tools = { 51 | cabal = { }; 52 | fourmolu = { }; 53 | hlint = { }; 54 | haskell-language-server = { }; 55 | }; 56 | buildInputs = with pkgs; [ 57 | cachix 58 | easy-ps.purs-0_15_15 59 | easy-ps.spago 60 | lua51Packages.lua 61 | lua51Packages.luacheck 62 | nil 63 | treefmt 64 | upx 65 | yamlfmt 66 | ]; 67 | }; 68 | 69 | crossPlatforms = 70 | p: 71 | pkgs.lib.optionals pkgs.stdenv.hostPlatform.isx86_64 ( 72 | pkgs.lib.optionals pkgs.stdenv.hostPlatform.isLinux [ p.musl64 ] 73 | ); 74 | }; 75 | }) 76 | ]; 77 | flake = pkgs.psluaProject.flake { }; 78 | in 79 | flake 80 | // { 81 | legacyPackages = pkgs; 82 | packages.default = flake.packages."pslua:exe:pslua"; 83 | packages.static = flake.ciJobs.x86_64-unknown-linux-musl.packages."pslua:exe:pslua"; 84 | } 85 | ); 86 | 87 | # --- Flake Local Nix Configuration ---------------------------- 88 | nixConfig = { 89 | extra-substituters = [ 90 | "https://cache.iog.io" 91 | "https://purescript-lua.cachix.org" 92 | ]; 93 | extra-trusted-public-keys = [ 94 | "hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ=" 95 | "purescript-lua.cachix.org-1:yLs4ei2HtnuPtzLekOrW3xdfm95+Etw15gwgyIGTayA=" 96 | ]; 97 | allow-import-from-derivation = "true"; 98 | }; 99 | } 100 | -------------------------------------------------------------------------------- /fourmolu.yaml: -------------------------------------------------------------------------------- 1 | comma-style: leading 2 | column-limit: 80 3 | diff-friendly-import-export: true 4 | function-arrows: leading 5 | haddock-style: multi-line 6 | import-export-style: leading 7 | indent-wheres: false 8 | indentation: 2 9 | newlines-between-decls: 1 10 | record-brace-space: true 11 | respectful: true 12 | single-constraint-parens: never 13 | unicode: always 14 | -------------------------------------------------------------------------------- /hie.yaml: -------------------------------------------------------------------------------- 1 | cradle: 2 | cabal: 3 | - path: "exe" 4 | component: "pslua:exe:pslua" 5 | - path: "lib" 6 | component: "lib:pslua" 7 | - path: "test" 8 | component: "pslua:test:spec" 9 | -------------------------------------------------------------------------------- /lib/Language/PureScript/Backend.hs: -------------------------------------------------------------------------------- 1 | module Language.PureScript.Backend where 2 | 3 | import Control.Monad.Oops (CouldBeAnyOf, Variant) 4 | import Control.Monad.Oops qualified as Oops 5 | import Data.Map qualified as Map 6 | import Data.Tagged (Tagged (..), untag) 7 | import Language.PureScript.Backend.IR qualified as IR 8 | import Language.PureScript.Backend.IR.Linker qualified as Linker 9 | import Language.PureScript.Backend.IR.Optimizer (optimizedUberModule) 10 | import Language.PureScript.Backend.Lua qualified as Lua 11 | import Language.PureScript.Backend.Lua.Optimizer (optimizeChunk) 12 | import Language.PureScript.Backend.Lua.Types qualified as Lua 13 | import Language.PureScript.Backend.Types (AppOrModule (..), entryPointModule) 14 | import Language.PureScript.CoreFn.Reader qualified as CoreFn 15 | import Path (Abs, Dir, Path, SomeBase) 16 | import Prelude hiding (show) 17 | 18 | data CompilationResult = CompilationResult 19 | { ir ∷ Linker.UberModule 20 | , lua ∷ Lua.Chunk 21 | } 22 | 23 | compileModules 24 | ∷ e 25 | `CouldBeAnyOf` '[ CoreFn.ModuleNotFound 26 | , CoreFn.ModuleDecodingErr 27 | , IR.CoreFnError 28 | , Lua.Error 29 | ] 30 | ⇒ Tagged "output" (SomeBase Dir) 31 | → Tagged "foreign" (Path Abs Dir) 32 | → AppOrModule 33 | → ExceptT (Variant e) IO CompilationResult 34 | compileModules outputDir foreignDir appOrModule = do 35 | let entryModuleName = entryPointModule appOrModule 36 | cfnModules ← CoreFn.readModuleRecursively outputDir entryModuleName 37 | let dataDecls = IR.collectDataDeclarations cfnModules 38 | irResults ← forM (Map.toList cfnModules) \(_psModuleName, cfnModule) → 39 | Oops.hoistEither $ IR.mkModule cfnModule dataDecls 40 | let (needsRuntimeLazys, irModules) = unzip irResults 41 | let uberModule = 42 | Linker.makeUberModule (linkerMode appOrModule) irModules 43 | & optimizedUberModule 44 | let needsRuntimeLazy = Tagged (any untag needsRuntimeLazys) 45 | chunk ← Lua.fromUberModule foreignDir needsRuntimeLazy appOrModule uberModule 46 | pure CompilationResult {lua = optimizeChunk chunk, ir = uberModule} 47 | 48 | linkerMode ∷ AppOrModule → Linker.LinkMode 49 | linkerMode = \case 50 | AsModule psModuleName → Linker.LinkAsModule psModuleName 51 | AsApplication psModuleName psIdent → 52 | Linker.LinkAsApplication psModuleName (IR.identToName psIdent) 53 | -------------------------------------------------------------------------------- /lib/Language/PureScript/Backend/IR/Inliner.hs: -------------------------------------------------------------------------------- 1 | module Language.PureScript.Backend.IR.Inliner where 2 | 3 | import Language.PureScript.Backend.IR.Names (Name, nameParser) 4 | import Text.Megaparsec qualified as Megaparsec 5 | import Text.Megaparsec.Char qualified as MC 6 | import Text.Megaparsec.Char.Lexer qualified as ML 7 | 8 | type Pragma = (Name, Annotation) 9 | 10 | data Annotation = Always | Never 11 | deriving stock (Show, Eq, Ord) 12 | 13 | type Parser = Megaparsec.Parsec Void Text 14 | 15 | pragmaParser ∷ Parser Pragma 16 | pragmaParser = do 17 | symbol "@inline" 18 | (,) <$> (nameParser <* sc) <*> annotationParser 19 | 20 | annotationParser ∷ Parser Annotation 21 | annotationParser = (Always <$ symbol "always") <|> (Never <$ symbol "never") 22 | 23 | symbol ∷ Text → Parser () 24 | symbol = void . ML.symbol sc 25 | 26 | sc ∷ Parser () 27 | sc = ML.space (MC.hspace1 @_ @Text) empty empty 28 | -------------------------------------------------------------------------------- /lib/Language/PureScript/Backend/IR/Names.hs: -------------------------------------------------------------------------------- 1 | module Language.PureScript.Backend.IR.Names 2 | ( module Reexport 3 | , Name (..) 4 | , nameParser 5 | , QName (..) 6 | , printQName 7 | , TyName (..) 8 | , CtorName (..) 9 | , FieldName (..) 10 | , PropName (..) 11 | , Qualified (..) 12 | , qualifiedQName 13 | ) where 14 | 15 | import Data.Char (isAlphaNum) 16 | import Language.PureScript.Names as Reexport 17 | ( ModuleName (..) 18 | , moduleNameFromString 19 | , runModuleName 20 | ) 21 | import Quiet (Quiet (..)) 22 | import Text.Megaparsec qualified as Megaparsec 23 | import Prelude hiding (show) 24 | 25 | newtype Name = Name {nameToText ∷ Text} 26 | deriving newtype (Eq, Ord) 27 | deriving stock (Generic) 28 | deriving (Show) via (Quiet Name) 29 | 30 | nameParser ∷ Megaparsec.Parsec Void Text Name 31 | nameParser = Name <$> Megaparsec.takeWhile1P (Just "name char") isAlphaNum 32 | 33 | data QName = QName {qnameModuleName ∷ ModuleName, qnameName ∷ Name} 34 | deriving stock (Eq, Ord, Show) 35 | 36 | printQName ∷ QName → Text 37 | printQName QName {..} = 38 | runModuleName qnameModuleName <> "∷" <> nameToText qnameName 39 | 40 | newtype TyName = TyName {renderTyName ∷ Text} 41 | deriving newtype (Eq, Ord) 42 | deriving stock (Generic) 43 | deriving (Show) via (Quiet TyName) 44 | 45 | newtype CtorName = CtorName {renderCtorName ∷ Text} 46 | deriving newtype (Eq, Ord) 47 | deriving stock (Generic) 48 | deriving (Show) via (Quiet CtorName) 49 | 50 | -- TODO: is it used at all? 51 | newtype FieldName = FieldName {renderFieldName ∷ Text} 52 | deriving newtype (Eq, Ord) 53 | deriving stock (Generic) 54 | deriving (Show) via (Quiet FieldName) 55 | 56 | newtype PropName = PropName {renderPropName ∷ Text} 57 | deriving newtype (Eq, Ord) 58 | deriving stock (Generic) 59 | deriving (Show) via (Quiet PropName) 60 | 61 | data Qualified a = Local a | Imported ModuleName a 62 | deriving stock (Show, Eq, Ord, Functor) 63 | 64 | qualifiedQName ∷ QName → Qualified Name 65 | qualifiedQName QName {qnameModuleName, qnameName} = 66 | Imported qnameModuleName qnameName 67 | -------------------------------------------------------------------------------- /lib/Language/PureScript/Backend/IR/Query.hs: -------------------------------------------------------------------------------- 1 | module Language.PureScript.Backend.IR.Query where 2 | 3 | import Control.Lens.Plated (transformMOf) 4 | import Control.Monad.Trans.Accum (add, execAccum) 5 | import Data.Map qualified as Map 6 | import Data.Set qualified as Set 7 | import Language.PureScript.Backend.IR.Linker (UberModule (..)) 8 | import Language.PureScript.Backend.IR.Names 9 | ( Name (Name) 10 | , Qualified (Imported, Local) 11 | , runModuleName 12 | ) 13 | import Language.PureScript.Backend.IR.Types 14 | ( Exp 15 | , bindingNames 16 | , countFreeRef 17 | , countFreeRefs 18 | , listGrouping 19 | , subexpressions 20 | ) 21 | import Language.PureScript.Backend.IR.Types qualified as IR 22 | import Language.PureScript.Names (runtimeLazyName) 23 | 24 | usesRuntimeLazy ∷ UberModule → Bool 25 | usesRuntimeLazy UberModule {uberModuleBindings, uberModuleExports} = 26 | getAny $ 27 | foldMap 28 | (foldMap (\(_qname, e) → Any (findRuntimeLazyInExpr e)) . listGrouping) 29 | uberModuleBindings 30 | <> foldMap (Any . findRuntimeLazyInExpr . snd) uberModuleExports 31 | 32 | findRuntimeLazyInExpr ∷ Exp → Bool 33 | findRuntimeLazyInExpr expr = 34 | countFreeRef (Local (Name runtimeLazyName)) expr > 0 35 | 36 | usesPrimModule ∷ UberModule → Bool 37 | usesPrimModule UberModule {uberModuleBindings, uberModuleExports} = 38 | getAny $ 39 | foldMap 40 | (foldMap (\(_qname, e) → Any (findPrimModuleInExpr e)) . listGrouping) 41 | uberModuleBindings 42 | <> foldMap (Any . findPrimModuleInExpr . snd) uberModuleExports 43 | 44 | findPrimModuleInExpr ∷ Exp → Bool 45 | findPrimModuleInExpr expr = 46 | Map.keys (countFreeRefs expr) & any \case 47 | Local _name → False 48 | Imported moduleName _name → runModuleName moduleName == "Prim" 49 | 50 | collectBoundNames ∷ Exp → Set Name 51 | collectBoundNames = 52 | (`execAccum` Set.empty) . transformMOf subexpressions \e → 53 | case e of 54 | IR.Abs _ann (IR.ParamNamed _paramAnn name) _body → 55 | e <$ add (Set.singleton name) 56 | IR.Let _ann groupings _body → 57 | e <$ add do 58 | Set.fromList 59 | [iname | grouping ← toList groupings, iname ← bindingNames grouping] 60 | _ → pure e 61 | -------------------------------------------------------------------------------- /lib/Language/PureScript/Backend/Lua/Fixture.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE QuasiQuotes #-} 2 | 3 | module Language.PureScript.Backend.Lua.Fixture where 4 | 5 | import Data.String.Interpolate (__i) 6 | import Language.PureScript.Backend.Lua.Name (Name, name, unsafeName) 7 | import Language.PureScript.Backend.Lua.Name qualified as Name 8 | import Language.PureScript.Backend.Lua.Types hiding (var) 9 | 10 | -------------------------------------------------------------------------------- 11 | -- Hard-coded Lua pieces ------------------------------------------------------- 12 | 13 | uniqueName ∷ MonadState Natural m ⇒ Text → m Name 14 | uniqueName prefix = do 15 | index ← get 16 | modify' (+ 1) 17 | pure $ unsafeName (prefix <> show index) 18 | 19 | psluaName ∷ Name → Name 20 | psluaName = Name.join2 [name|PSLUA|] 21 | 22 | moduleName ∷ Name.Name 23 | moduleName = [name|M|] 24 | 25 | runtimeLazyName ∷ Name 26 | runtimeLazyName = psluaName [name|runtime_lazy|] 27 | 28 | runtimeLazy ∷ Statement 29 | runtimeLazy = 30 | ForeignSourceStat 31 | [__i| 32 | local function #{Name.toText runtimeLazyName}(name) 33 | return function(init) 34 | return function() 35 | local state = 0 36 | local val = nil 37 | if state == 2 then 38 | return val 39 | else 40 | if state == 1 then 41 | return error(name .. " was needed before it finished initializing") 42 | else 43 | state = 1 44 | val = init() 45 | state = 2 46 | return val 47 | end 48 | end 49 | end 50 | end 51 | end 52 | |] 53 | 54 | objectUpdateName ∷ Name 55 | objectUpdateName = psluaName [name|object_update|] 56 | 57 | objectUpdate ∷ Statement 58 | objectUpdate = 59 | ForeignSourceStat 60 | [__i| 61 | local function #{Name.toText objectUpdateName}(o, patches) 62 | local o_copy = {} 63 | for k, v in pairs(o) do 64 | local patch_v = patches[k] 65 | if patch_v ~= nil then 66 | o_copy[k] = patch_v 67 | else 68 | o_copy[k] = v 69 | end 70 | end 71 | return o_copy 72 | end 73 | |] 74 | -------------------------------------------------------------------------------- /lib/Language/PureScript/Backend/Lua/Key.hs: -------------------------------------------------------------------------------- 1 | {- | This module defines the data type `Key` which is used to represent the 2 | keys of a Lua table. 3 | -} 4 | module Language.PureScript.Backend.Lua.Key 5 | ( Key (..) 6 | , parser 7 | , toSafeName 8 | ) where 9 | 10 | import Language.PureScript.Backend.Lua.Name (Name) 11 | import Language.PureScript.Backend.Lua.Name qualified as Name 12 | import Text.Megaparsec qualified as Mega 13 | import Text.Megaparsec.Char qualified as M 14 | 15 | data Key = KeyName Name | KeyReserved Text 16 | deriving stock (Eq, Show) 17 | 18 | toSafeName ∷ Key → Name 19 | toSafeName (KeyName n) = n 20 | toSafeName (KeyReserved t) = Name.makeSafe t 21 | 22 | type Parser = Mega.Parsec Void Text 23 | 24 | parser ∷ Parser Key 25 | parser = (nameParser <|> reservedParser) <* M.space 26 | where 27 | nameParser ∷ Parser Key 28 | nameParser = KeyName <$> Name.parser 29 | 30 | reservedParser ∷ Parser Key 31 | reservedParser = brackets $ quotes do 32 | KeyReserved <$> Mega.choice (M.string <$> toList Name.reserved) 33 | 34 | brackets ∷ Parser a → Parser a 35 | brackets = between '[' ']' 36 | 37 | quotes ∷ Parser a → Parser a 38 | quotes = between '\"' '\"' 39 | 40 | between ∷ Char → Char → Parser c → Parser c 41 | between open close p = char open *> p <* char close 42 | 43 | char ∷ Char → Parser () 44 | char c = M.char c *> M.space 45 | -------------------------------------------------------------------------------- /lib/Language/PureScript/Backend/Lua/Linker/Foreign.hs: -------------------------------------------------------------------------------- 1 | module Language.PureScript.Backend.Lua.Linker.Foreign 2 | ( Source (..) 3 | , Parser 4 | , parseForeignSource 5 | , Error (..) 6 | 7 | -- * Internal 8 | , moduleParser 9 | , valueParser 10 | ) where 11 | 12 | import Control.Monad.Combinators.NonEmpty qualified as NE 13 | import Control.Monad.Trans.Except (except, throwE) 14 | import Data.DList (DList) 15 | import Data.DList qualified as DL 16 | import Data.String qualified as String 17 | import Data.Text qualified as Text 18 | import Language.PureScript.Backend.Lua.Key (Key) 19 | import Language.PureScript.Backend.Lua.Key qualified as Key 20 | import Path (Abs, Dir, File, Path, toFilePath, ()) 21 | import Path qualified 22 | import Path.IO qualified as Path 23 | import Text.Megaparsec (Parsec) 24 | import Text.Megaparsec qualified as MP 25 | import Text.Megaparsec qualified as Megaparsec 26 | import Text.Megaparsec.Char qualified as MP 27 | import Text.Show (Show (..)) 28 | import Prelude hiding (show) 29 | 30 | data Source = Source {header ∷ Maybe Text, exports ∷ NonEmpty (Key, Text)} 31 | deriving stock (Eq, Show) 32 | 33 | {- | Parse a foreign source file which has to be in the following format: 34 | @@ 35 |
36 | return { 37 | identifier = (), 38 | ... 39 | identifier = () 40 | } 41 | @@ 42 | 43 | The
is optional and can contain any Lua statements except 'return'. 44 | It is meant to host Lua code shared by all the export . 45 | 46 | The is a Lua expression. The braces around a are required. 47 | -} 48 | parseForeignSource ∷ Path Abs Dir → FilePath → IO (Either Error Source) 49 | parseForeignSource foreigns path = runExceptT do 50 | filePath ← toFilePath <$> resolveForModule path foreigns 51 | src ← Text.strip . decodeUtf8 <$> liftIO (readFileBS filePath) 52 | let (headerLines, returnStat) = break isReturn (Text.lines src) 53 | case Megaparsec.parse moduleParser filePath (unlines returnStat) of 54 | Left err → throwE $ ForeignErrorParse filePath err 55 | Right parsed → do 56 | let header = guarded (not . Text.null) (Text.strip (unlines headerLines)) 57 | pure $ Source header parsed 58 | where 59 | isReturn ∷ Text → Bool 60 | isReturn = Text.isPrefixOf "return" 61 | 62 | resolveForModule ∷ FilePath → Path Abs Dir → ExceptT Error IO (Path Abs File) 63 | resolveForModule modulePath foreignBaseDir = do 64 | cwd ← Path.getCurrentDir 65 | absModulePath ← 66 | Path.parseAbsFile modulePath 67 | & maybe (Path.resolveFile cwd modulePath) pure 68 | -- Its not always true that module path is relative to the cwd 69 | let relModulePath = Path.makeRelative @_ @Maybe cwd absModulePath 70 | foreignFile ← Path.filename <$> Path.replaceExtension ".lua" absModulePath 71 | let searchLocations = 72 | Path.parent absModulePath :| case relModulePath of 73 | Nothing → [] 74 | Just mp → [foreignBaseDir Path.parent mp] 75 | filesToSearch ← forM searchLocations $ \location → 76 | Path.resolveFile location (toFilePath foreignFile) 77 | found ← forM filesToSearch \file → 78 | bool Nothing (Just file) <$> Path.doesFileExist file 79 | except $ 80 | maybeToRight (ForeignFileNotFound modulePath filesToSearch) (asum found) 81 | 82 | -------------------------------------------------------------------------------- 83 | -- Parser ---------------------------------------------------------------------- 84 | 85 | type Parser = Parsec Void Text 86 | 87 | moduleParser ∷ Parser (NonEmpty (Key, Text)) 88 | moduleParser = do 89 | MP.string "return" *> MP.space1 90 | char '{' 91 | exports ← NE.sepEndBy1 foreignExport (char ',') 92 | char '}' 93 | pure exports 94 | 95 | foreignExport ∷ Parser (Key, Text) 96 | foreignExport = do 97 | exportKey ← Key.parser 98 | char '=' 99 | exportValue ← valueParser 100 | pure (exportKey, toText exportValue) 101 | 102 | valueParser ∷ Parser String 103 | valueParser = char '(' *> go 0 DL.empty <* MP.space 104 | where 105 | go ∷ Int → DList Char → Parser String 106 | go numToClose value = do 107 | cs ← many $ MP.satisfy (\c → c /= '(' && c /= ')') 108 | MP.optional MP.anySingle >>= \case 109 | Just '(' → go (succ numToClose) (DL.snoc (value <> DL.fromList cs) '(') 110 | Just ')' → 111 | if numToClose > 0 112 | then go (pred numToClose) (DL.snoc (value <> DL.fromList cs) ')') 113 | else pure $ DL.toList $ value <> DL.fromList cs 114 | _ → pure $ DL.toList (value <> DL.fromList cs) 115 | 116 | char ∷ Char → Parser () 117 | char c = MP.char c *> MP.space 118 | 119 | -------------------------------------------------------------------------------- 120 | -- Errors ---------------------------------------------------------------------- 121 | 122 | data Error 123 | = ForeignFileNotFound FilePath (NonEmpty (Path Abs File)) 124 | | ForeignErrorParse FilePath (Megaparsec.ParseErrorBundle Text Void) 125 | deriving stock (Eq) 126 | 127 | instance Show Error where 128 | show (ForeignFileNotFound modulePath searched) = 129 | "Foreign file for the module " 130 | <> show modulePath 131 | <> " not found in the following locations:\n" 132 | <> String.unlines (toList searched <&> ("- " <>) . toFilePath) 133 | show (ForeignErrorParse filePath err) = 134 | "Error parsing foreign file " 135 | <> show filePath 136 | <> ":\n" 137 | <> Megaparsec.errorBundlePretty err 138 | -------------------------------------------------------------------------------- /lib/Language/PureScript/Backend/Lua/Name.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE TemplateHaskellQuotes #-} 2 | 3 | module Language.PureScript.Backend.Lua.Name 4 | ( Name 5 | , fromText 6 | , toText 7 | , name 8 | , parser 9 | , unsafeName 10 | , makeSafe 11 | , specialNameType 12 | , specialNameCtor 13 | , join2 14 | , reserved 15 | ) where 16 | 17 | import Data.Char qualified as Char 18 | import Data.Set qualified as Set 19 | import Data.Text qualified as Text 20 | import Language.Haskell.TH.Quote (QuasiQuoter (..)) 21 | import Prettyprinter (Pretty) 22 | import Text.Megaparsec qualified as M 23 | import Text.Megaparsec.Char qualified as M 24 | import Prelude hiding (toText) 25 | 26 | newtype Name = Name {toText ∷ Text} 27 | deriving newtype (Eq, Ord, Show, Pretty) 28 | 29 | name ∷ QuasiQuoter 30 | name = 31 | QuasiQuoter 32 | { quoteExp = \(s ∷ String) → 33 | case fromText (fromString s) of 34 | Nothing → 35 | error "Language.PureScript.Backend.Lua.Name: invalid name" 36 | Just (Name n) → ⟦Name n⟧ 37 | , quotePat = 38 | const $ 39 | error "Language.PureScript.Backend.Lua.Name.quotePat: unsupported" 40 | , quoteType = 41 | const $ 42 | error "Language.PureScript.Backend.Lua.Name.quoteType: unsupported" 43 | , quoteDec = 44 | const $ 45 | error "Language.PureScript.Backend.Lua.Name.quoteDec: unsupported" 46 | } 47 | 48 | fromText ∷ Text → Maybe Name 49 | fromText t = 50 | case Text.strip t of 51 | n 52 | | Text.length n > 0 53 | , checkFirst (Text.head n) 54 | , Text.all checkRest (Text.tail n) 55 | , Set.notMember n reserved → 56 | Just (Name n) 57 | _ → Nothing 58 | where 59 | checkFirst c = Char.isAlpha c || c == '_' 60 | checkRest c = Char.isDigit c || checkFirst c 61 | 62 | parser ∷ M.Parsec Void Text Name 63 | parser = 64 | Name <$> do 65 | c ← M.letterChar <|> M.char '_' 66 | cs ← M.many (M.alphaNumChar <|> M.char '_') 67 | pure $ Text.pack (c : cs) 68 | 69 | makeSafe ∷ HasCallStack ⇒ Text → Name 70 | makeSafe unsafe = unsafeName safest 71 | where 72 | safest = 73 | if safer `Set.member` reserved 74 | then '_' `Text.cons` safer `Text.snoc` '_' 75 | else safer 76 | safer = 77 | Text.replace "$" "_S_" . Text.replace "." "_" $ 78 | Text.replace "'" "Prime" unsafe 79 | 80 | unsafeName ∷ HasCallStack ⇒ Text → Name 81 | unsafeName n = 82 | fromMaybe 83 | ( error . unwords $ 84 | [ "Language.PureScript.Backend.Lua.Name.unsafeName:" 85 | , "invalid name" 86 | , show n 87 | ] 88 | ) 89 | (fromText n) 90 | 91 | specialNameType ∷ Name 92 | specialNameType = Name "$type" 93 | 94 | specialNameCtor ∷ Name 95 | specialNameCtor = Name "$ctor" 96 | 97 | reserved ∷ Set Text 98 | reserved = 99 | Set.fromList 100 | [ "and" 101 | , "break" 102 | , "do" 103 | , "else" 104 | , "elseif" 105 | , "end" 106 | , "false" 107 | , "for" 108 | , "function" 109 | , "goto" 110 | , "if" 111 | , "in" 112 | , "local" 113 | , "nil" 114 | , "not" 115 | , "or" 116 | , "repeat" 117 | , "return" 118 | , "then" 119 | , "true" 120 | , "until" 121 | , "while" 122 | ] 123 | 124 | join2 ∷ Name → Name → Name 125 | join2 (Name a) (Name b) = Name (a <> "_" <> b) 126 | -------------------------------------------------------------------------------- /lib/Language/PureScript/Backend/Lua/Optimizer.hs: -------------------------------------------------------------------------------- 1 | module Language.PureScript.Backend.Lua.Optimizer where 2 | 3 | import Control.Monad.Trans.Accum (Accum, add, execAccum) 4 | import Data.List qualified as List 5 | import Data.Map qualified as Map 6 | import Language.PureScript.Backend.Lua.Name qualified as Lua 7 | import Language.PureScript.Backend.Lua.Traversal 8 | ( everywhereExp 9 | , everywhereInChunkM 10 | , everywhereStat 11 | , everywhereStatM 12 | ) 13 | import Language.PureScript.Backend.Lua.Types 14 | ( Chunk 15 | , Exp 16 | , ExpF (..) 17 | , Statement 18 | , StatementF (Local, Return) 19 | , TableRowF (..) 20 | , VarF (..) 21 | , functionDef 22 | , return 23 | , unAnn 24 | , pattern Ann 25 | ) 26 | import Language.PureScript.Backend.Lua.Types qualified as Lua 27 | import Prelude hiding (return) 28 | 29 | optimizeChunk ∷ Chunk → Chunk 30 | optimizeChunk = fmap optimizeStatement 31 | 32 | substituteVarForValue ∷ Lua.Name → Exp → Chunk → Chunk 33 | substituteVarForValue name inlinee = 34 | runIdentity . everywhereInChunkM (pure . subst) pure 35 | where 36 | subst = \case 37 | Lua.Var (Lua.unAnn → Lua.VarName varName) | varName == name → inlinee 38 | expr → expr 39 | 40 | countRefs ∷ Statement → Map Lua.Name (Sum Natural) 41 | countRefs = everywhereStatM pure countRefsInExpression >>> (`execAccum` mempty) 42 | where 43 | countRefsInExpression ∷ Exp → Accum (Map Lua.Name (Sum Natural)) Exp 44 | countRefsInExpression = \case 45 | expr@(Lua.Var (Lua.unAnn → Lua.VarName name)) → 46 | add (Map.singleton name (Sum 1)) $> expr 47 | expr → pure expr 48 | 49 | optimizeStatement ∷ Statement → Statement 50 | optimizeStatement = everywhereStat identity optimizeExpression 51 | 52 | optimizeExpression ∷ Exp → Exp 53 | optimizeExpression = foldr (>>>) identity rewriteRulesInOrder 54 | 55 | rewriteRulesInOrder ∷ [RewriteRule] 56 | rewriteRulesInOrder = 57 | [ pushDeclarationsDownTheInnerScope 58 | , removeScopeWhenInsideEmptyFunction 59 | , reduceTableDefinitionAccessor 60 | ] 61 | 62 | type RewriteRule = Exp → Exp 63 | 64 | rewriteExpWithRule ∷ RewriteRule → Exp → Exp 65 | rewriteExpWithRule rule = everywhereExp rule identity 66 | 67 | -------------------------------------------------------------------------------- 68 | -- Rewrite rules for expressions ----------------------------------------------- 69 | 70 | pushDeclarationsDownTheInnerScope ∷ RewriteRule 71 | pushDeclarationsDownTheInnerScope = \case 72 | Function outerArgs outerBody 73 | | Just lastStatement ← viaNonEmpty last outerBody 74 | , Ann (Return (Ann (Function innerArgs innerBody))) ← lastStatement 75 | , declarations ← unAnn <$> List.init outerBody 76 | , not (null declarations) 77 | , all isDeclaration declarations → 78 | functionDef 79 | (fmap unAnn outerArgs) 80 | [ return $ 81 | functionDef 82 | (fmap unAnn innerArgs) 83 | (declarations <> fmap unAnn innerBody) 84 | ] 85 | e → e 86 | where 87 | isDeclaration ∷ Statement → Bool 88 | isDeclaration = \case 89 | Local _ _ → True 90 | _ → False 91 | 92 | removeScopeWhenInsideEmptyFunction ∷ RewriteRule 93 | removeScopeWhenInsideEmptyFunction = \case 94 | Function 95 | outerArgs 96 | [Ann (Return (Ann (FunctionCall (Ann (Function [] body)) [])))] → 97 | Function outerArgs body 98 | e → e 99 | 100 | -- | Rewrites '{ foo = 1, bar = 2 }.foo' to '1' 101 | reduceTableDefinitionAccessor ∷ RewriteRule 102 | reduceTableDefinitionAccessor = \case 103 | Var (Ann (VarField (Ann (TableCtor rows)) accessedField)) → 104 | fromMaybe Nil $ 105 | listToMaybe 106 | [ fieldValue 107 | | (_ann, TableRowNV tableField (Ann fieldValue)) ← rows 108 | , tableField == accessedField 109 | ] 110 | e → e 111 | -------------------------------------------------------------------------------- /lib/Language/PureScript/Backend/Types.hs: -------------------------------------------------------------------------------- 1 | module Language.PureScript.Backend.Types where 2 | 3 | import Language.PureScript.Names qualified as PS 4 | 5 | data AppOrModule 6 | = AsApplication PS.ModuleName PS.Ident 7 | | AsModule PS.ModuleName 8 | deriving stock (Show) 9 | 10 | entryPointModule ∷ AppOrModule → PS.ModuleName 11 | entryPointModule = \case 12 | AsApplication modname _ident → modname 13 | AsModule modname → modname 14 | -------------------------------------------------------------------------------- /lib/Language/PureScript/Comments.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE TemplateHaskell #-} 2 | 3 | -- | Defines the types of source code comments 4 | module Language.PureScript.Comments where 5 | 6 | import Data.Aeson.TH 7 | ( Options (..) 8 | , SumEncoding (..) 9 | , defaultOptions 10 | , deriveJSON 11 | ) 12 | 13 | data Comment 14 | = LineComment Text 15 | | BlockComment Text 16 | deriving stock (Show, Eq, Ord, Generic) 17 | 18 | $(deriveJSON (defaultOptions {sumEncoding = ObjectWithSingleField}) ''Comment) 19 | -------------------------------------------------------------------------------- /lib/Language/PureScript/CoreFn.hs: -------------------------------------------------------------------------------- 1 | module Language.PureScript.CoreFn 2 | ( module C 3 | , Ann 4 | ) where 5 | 6 | import Language.PureScript.CoreFn.Expr as C 7 | import Language.PureScript.CoreFn.Meta as C 8 | import Language.PureScript.CoreFn.Module as C 9 | 10 | type Ann = Maybe Meta 11 | -------------------------------------------------------------------------------- /lib/Language/PureScript/CoreFn/Expr.hs: -------------------------------------------------------------------------------- 1 | {- | 2 | The core functional representation 3 | -} 4 | module Language.PureScript.CoreFn.Expr where 5 | 6 | import Control.Arrow ((***)) 7 | import Language.PureScript.Names 8 | import Language.PureScript.PSString (PSString) 9 | 10 | {- | 11 | Data type for expressions and terms 12 | -} 13 | data Expr a 14 | = -- A literal value 15 | Literal a (Literal (Expr a)) 16 | | -- A data constructor (type name, constructor name, field names) 17 | Constructor a (ProperName 'TypeName) (ProperName 'ConstructorName) [Ident] 18 | | -- A record property accessor 19 | Accessor a PSString (Expr a) 20 | | -- Partial record update 21 | ObjectUpdate a (Expr a) [(PSString, Expr a)] 22 | | -- Function introduction 23 | Abs a Ident (Expr a) 24 | | -- Function application 25 | App a (Expr a) (Expr a) 26 | | -- Variable 27 | Var a (Qualified Ident) 28 | | -- A case expression 29 | Case a [Expr a] [CaseAlternative a] 30 | | -- A let binding 31 | Let a [Bind a] (Expr a) 32 | deriving stock (Eq, Ord, Show, Functor) 33 | 34 | data Binder a 35 | = -- | 36 | -- Wildcard binder 37 | NullBinder a 38 | | -- | 39 | -- A binder which matches a literal value 40 | LiteralBinder a (Literal (Binder a)) 41 | | -- | 42 | -- A binder which binds an identifier 43 | VarBinder a Ident 44 | | -- | 45 | -- A binder which matches a data constructor 46 | ConstructorBinder 47 | a 48 | (Qualified (ProperName 'TypeName)) 49 | (Qualified (ProperName 'ConstructorName)) 50 | [Binder a] 51 | | -- | 52 | -- A binder which binds its input to an identifier 53 | NamedBinder a Ident (Binder a) 54 | deriving stock (Eq, Ord, Show, Functor) 55 | 56 | extractBinderAnn ∷ Binder a → a 57 | extractBinderAnn (NullBinder a) = a 58 | extractBinderAnn (LiteralBinder a _) = a 59 | extractBinderAnn (VarBinder a _) = a 60 | extractBinderAnn (ConstructorBinder a _ _ _) = a 61 | extractBinderAnn (NamedBinder a _ _) = a 62 | 63 | {- | 64 | A let or module binding. 65 | -} 66 | data Bind a 67 | = -- | 68 | -- Non-recursive binding for a single value 69 | NonRec a Ident (Expr a) 70 | | -- | 71 | -- Mutually recursive binding group for several values 72 | Rec [((a, Ident), Expr a)] 73 | deriving stock (Eq, Ord, Show, Functor) 74 | 75 | {- | 76 | A guard is just a literalBool-valued expression 77 | that appears alongside a set of binders 78 | -} 79 | type Guard a = Expr a 80 | 81 | {- | 82 | An alternative in a case statement 83 | -} 84 | data CaseAlternative a = CaseAlternative 85 | { caseAlternativeBinders ∷ [Binder a] 86 | -- ^ 87 | -- A collection of binders with which to match the inputs 88 | , caseAlternativeResult ∷ Either [(Guard a, Expr a)] (Expr a) 89 | -- ^ 90 | -- The result expression or a collect of guarded expressions 91 | } 92 | deriving stock (Eq, Ord, Show) 93 | 94 | instance Functor CaseAlternative where 95 | fmap f (CaseAlternative cabs car) = 96 | CaseAlternative 97 | (fmap (fmap f) cabs) 98 | (either (Left . fmap (fmap f *** fmap f)) (Right . fmap f) car) 99 | 100 | {- | 101 | Data type for literal values. Parameterised so it can be used for Exprs and 102 | Binders. 103 | -} 104 | data Literal a 105 | = -- | 106 | -- A numeric literal 107 | NumericLiteral (Either Integer Double) 108 | | -- | 109 | -- A string literal 110 | StringLiteral PSString 111 | | -- | 112 | -- A character literal 113 | CharLiteral Char 114 | | -- | 115 | -- A literalBool literal 116 | BooleanLiteral Bool 117 | | -- | 118 | -- An array literal 119 | ArrayLiteral [a] 120 | | -- | 121 | -- An object literal 122 | ObjectLiteral [(PSString, a)] 123 | deriving stock (Eq, Ord, Show, Functor) 124 | 125 | {- | 126 | Extract the annotation from a term 127 | -} 128 | extractAnn ∷ Expr a → a 129 | extractAnn (Literal a _) = a 130 | extractAnn (Constructor a _ _ _) = a 131 | extractAnn (Accessor a _ _) = a 132 | extractAnn (ObjectUpdate a _ _) = a 133 | extractAnn (Abs a _ _) = a 134 | extractAnn (App a _ _) = a 135 | extractAnn (Var a _) = a 136 | extractAnn (Case a _ _) = a 137 | extractAnn (Let a _ _) = a 138 | 139 | {- | 140 | Modify the annotation on a term 141 | -} 142 | modifyAnn ∷ (a → a) → Expr a → Expr a 143 | modifyAnn f (Literal a b) = Literal (f a) b 144 | modifyAnn f (Constructor a b c d) = Constructor (f a) b c d 145 | modifyAnn f (Accessor a b c) = Accessor (f a) b c 146 | modifyAnn f (ObjectUpdate a b c) = ObjectUpdate (f a) b c 147 | modifyAnn f (Abs a b c) = Abs (f a) b c 148 | modifyAnn f (App a b c) = App (f a) b c 149 | modifyAnn f (Var a b) = Var (f a) b 150 | modifyAnn f (Case a b c) = Case (f a) b c 151 | modifyAnn f (Let a b c) = Let (f a) b c 152 | -------------------------------------------------------------------------------- /lib/Language/PureScript/CoreFn/Meta.hs: -------------------------------------------------------------------------------- 1 | -- | Metadata annotations for core functional representation 2 | module Language.PureScript.CoreFn.Meta where 3 | 4 | import Language.PureScript.Names (Ident) 5 | 6 | -- | Metadata annotations 7 | data Meta 8 | = -- | The contained value is a data constructor 9 | IsConstructor ConstructorType [Ident] 10 | | -- | The contained value is a newtype 11 | IsNewtype 12 | | -- | The contained value is a typeclass dictionary constructor 13 | IsTypeClassConstructor 14 | | -- | The contained reference is for a foreign member 15 | IsForeign 16 | | -- | The contained value is a where clause 17 | IsWhere 18 | | -- | The contained function application was synthesized by the compiler 19 | IsSyntheticApp 20 | deriving stock (Show, Eq, Ord) 21 | 22 | -- | Data constructor metadata 23 | data ConstructorType = ProductType | SumType 24 | deriving stock (Show, Eq, Ord) 25 | -------------------------------------------------------------------------------- /lib/Language/PureScript/CoreFn/Module.hs: -------------------------------------------------------------------------------- 1 | module Language.PureScript.CoreFn.Module where 2 | 3 | import Language.PureScript.Comments (Comment) 4 | import Language.PureScript.CoreFn.Expr (Bind) 5 | import Language.PureScript.Names (Ident, ModuleName) 6 | 7 | {- | 8 | The CoreFn module representation 9 | -} 10 | data Module a = Module 11 | { moduleName ∷ ModuleName 12 | , moduleComments ∷ [Comment] 13 | , modulePath ∷ FilePath 14 | , moduleImports ∷ [(a, ModuleName)] 15 | , moduleExports ∷ [Ident] 16 | , moduleReExports ∷ Map ModuleName [Ident] 17 | , moduleForeign ∷ [Ident] 18 | , moduleBindings ∷ [Bind a] 19 | } 20 | deriving stock (Functor, Show) 21 | -------------------------------------------------------------------------------- /lib/Language/PureScript/CoreFn/Reader.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE TemplateHaskell #-} 2 | 3 | module Language.PureScript.CoreFn.Reader where 4 | 5 | import Control.Monad.Oops (CouldBe, CouldBeAnyOf, Variant, throw) 6 | import Control.Monad.Oops qualified as Oops 7 | import Data.Aeson qualified as Json 8 | import Data.Map.Lazy qualified as Map 9 | import Data.Tagged (Tagged (unTagged)) 10 | import Data.Text qualified as Text 11 | import Language.PureScript.CoreFn qualified as Cfn 12 | import Language.PureScript.CoreFn.FromJSON 13 | ( ModuleWithVersion 14 | , moduleWithoutVersion 15 | ) 16 | import Language.PureScript.Names qualified as PS 17 | import Path 18 | ( Abs 19 | , Dir 20 | , File 21 | , Path 22 | , SomeBase (..) 23 | , mkRelFile 24 | , parseRelDir 25 | , toFilePath 26 | , () 27 | ) 28 | import Path.IO (doesFileExist, makeAbsolute) 29 | 30 | readModuleRecursively 31 | ∷ ∀ e 32 | . e `CouldBeAnyOf` '[ModuleNotFound, ModuleDecodingErr] 33 | ⇒ Tagged "output" (SomeBase Dir) 34 | → PS.ModuleName 35 | → ExceptT (Oops.Variant e) IO (Map PS.ModuleName (Cfn.Module Cfn.Ann)) 36 | readModuleRecursively output moduleName = recurse mempty [moduleName] 37 | where 38 | recurse 39 | ∷ Map PS.ModuleName (Cfn.Module Cfn.Ann) 40 | → [PS.ModuleName] 41 | → ExceptT (Oops.Variant e) IO (Map PS.ModuleName (Cfn.Module Cfn.Ann)) 42 | recurse loaded = \case 43 | [] → pure loaded 44 | modName : otherNames 45 | | "Prim" `Text.isPrefixOf` PS.runModuleName modName → 46 | recurse loaded otherNames 47 | modName : otherNames 48 | | Map.member modName loaded → 49 | recurse loaded otherNames 50 | modName : otherNames → 51 | readModule output modName >>= \m → 52 | recurse 53 | (Map.insert modName m loaded) 54 | (otherNames <> (fmap snd . Cfn.moduleImports) m) 55 | 56 | readModule 57 | ∷ e `CouldBeAnyOf` '[ModuleNotFound, ModuleDecodingErr] 58 | ⇒ Tagged "output" (SomeBase Dir) 59 | → PS.ModuleName 60 | → ExceptT (Variant e) IO (Cfn.Module Cfn.Ann) 61 | readModule output modName = do 62 | path ← modulePath output modName 63 | lift (Json.eitherDecodeFileStrict @ModuleWithVersion (toFilePath path)) 64 | >>= either (throw . ModuleDecodingErr path) (pure . moduleWithoutVersion) 65 | 66 | modulePath 67 | ∷ e `CouldBe` ModuleNotFound 68 | ⇒ Tagged "output" (SomeBase Dir) 69 | → PS.ModuleName 70 | → ExceptT (Variant e) IO (Path Abs File) 71 | modulePath psOutPath modName = do 72 | psOutput ← 73 | case unTagged psOutPath of 74 | Abs a → pure a 75 | Rel r → makeAbsolute r 76 | prd ← parseRelDir (toString (PS.runModuleName modName)) 77 | let path = psOutput prd $(mkRelFile "corefn.json") 78 | unlessM (doesFileExist path) $ throw $ ModuleNotFound path 79 | pure path 80 | 81 | -------------------------------------------------------------------------------- 82 | -- Errors ---------------------------------------------------------------------- 83 | 84 | newtype ModuleNotFound = ModuleNotFound (Path Abs File) 85 | data ModuleDecodingErr = ModuleDecodingErr (Path Abs File) String 86 | -------------------------------------------------------------------------------- /lib/Language/PureScript/CoreFn/Traversals.hs: -------------------------------------------------------------------------------- 1 | {-# OPTIONS_GHC -Wno-missing-local-signatures #-} 2 | 3 | {- | 4 | CoreFn traversal helpers 5 | -} 6 | module Language.PureScript.CoreFn.Traversals where 7 | 8 | import Control.Arrow ((***), (+++)) 9 | import Language.PureScript.CoreFn.Expr 10 | ( Bind (..) 11 | , Binder (ConstructorBinder, LiteralBinder, NamedBinder) 12 | , CaseAlternative (..) 13 | , Expr (Abs, Accessor, App, Case, Let, Literal, ObjectUpdate) 14 | , Literal (ArrayLiteral, ObjectLiteral) 15 | ) 16 | 17 | everywhereOnValues 18 | ∷ (Bind a → Bind a) 19 | → (Expr a → Expr a) 20 | → (Binder a → Binder a) 21 | → (Bind a → Bind a, Expr a → Expr a, Binder a → Binder a) 22 | everywhereOnValues f g h = (f', g', h') 23 | where 24 | f' (NonRec a name e) = f (NonRec a name (g' e)) 25 | f' (Rec es) = f (Rec (map (second g') es)) 26 | 27 | g' (Literal ann e) = g (Literal ann (handleLiteral g' e)) 28 | g' (Accessor ann prop e) = g (Accessor ann prop (g' e)) 29 | g' (ObjectUpdate ann obj vs) = 30 | g (ObjectUpdate ann (g' obj) (map (fmap g') vs)) 31 | g' (Abs ann name e) = g (Abs ann name (g' e)) 32 | g' (App ann v1 v2) = g (App ann (g' v1) (g' v2)) 33 | g' (Case ann vs alts) = 34 | g (Case ann (map g' vs) (map handleCaseAlternative alts)) 35 | g' (Let ann ds e) = g (Let ann (map f' ds) (g' e)) 36 | g' e = g e 37 | 38 | h' (LiteralBinder a b) = h (LiteralBinder a (handleLiteral h' b)) 39 | h' (NamedBinder a name b) = h (NamedBinder a name (h' b)) 40 | h' (ConstructorBinder a q1 q2 bs) = h (ConstructorBinder a q1 q2 (map h' bs)) 41 | h' b = h b 42 | 43 | handleCaseAlternative ca = 44 | ca 45 | { caseAlternativeBinders = map h' (caseAlternativeBinders ca) 46 | , caseAlternativeResult = 47 | (map (g' *** g') +++ g') (caseAlternativeResult ca) 48 | } 49 | 50 | handleLiteral ∷ (a → a) → Literal a → Literal a 51 | handleLiteral i (ArrayLiteral ls) = ArrayLiteral (map i ls) 52 | handleLiteral i (ObjectLiteral ls) = ObjectLiteral (map (fmap i) ls) 53 | handleLiteral _ other = other 54 | 55 | {- | 56 | Apply the provided functions to the top level of AST nodes. 57 | 58 | This function is useful as a building block for recursive functions, but 59 | doesn't actually recurse itself. 60 | -} 61 | traverseCoreFn 62 | ∷ ∀ f a 63 | . Applicative f 64 | ⇒ (Bind a → f (Bind a)) 65 | → (Expr a → f (Expr a)) 66 | → (Binder a → f (Binder a)) 67 | → (CaseAlternative a → f (CaseAlternative a)) 68 | → ( Bind a → f (Bind a) 69 | , Expr a → f (Expr a) 70 | , Binder a 71 | → f (Binder a) 72 | , CaseAlternative a → f (CaseAlternative a) 73 | ) 74 | traverseCoreFn f g h i = (f', g', h', i') 75 | where 76 | f' (NonRec a name e) = NonRec a name <$> g e 77 | f' (Rec es) = Rec <$> traverse (traverse g) es 78 | 79 | g' (Literal ann e) = Literal ann <$> handleLiteral g e 80 | g' (Accessor ann prop e) = Accessor ann prop <$> g e 81 | g' (ObjectUpdate ann obj vs) = 82 | ObjectUpdate ann 83 | <$> g obj 84 | <*> traverse (traverse g) vs 85 | g' (Abs ann name e) = Abs ann name <$> g e 86 | g' (App ann v1 v2) = App ann <$> g v1 <*> g v2 87 | g' (Case ann vs alts) = Case ann <$> traverse g vs <*> traverse i alts 88 | g' (Let ann ds e) = Let ann <$> traverse f ds <*> g' e 89 | g' e = pure e 90 | 91 | h' (LiteralBinder a b) = LiteralBinder a <$> handleLiteral h b 92 | h' (NamedBinder a name b) = NamedBinder a name <$> h b 93 | h' (ConstructorBinder a q1 q2 bs) = 94 | ConstructorBinder a q1 q2 <$> traverse h bs 95 | h' b = pure b 96 | 97 | i' ca = 98 | CaseAlternative 99 | <$> traverse h (caseAlternativeBinders ca) 100 | <*> bitraverse (traverse $ bitraverse g g) g (caseAlternativeResult ca) 101 | 102 | handleLiteral withItem = \case 103 | ArrayLiteral ls → ArrayLiteral <$> traverse withItem ls 104 | ObjectLiteral ls → ObjectLiteral <$> traverse (traverse withItem) ls 105 | other → pure other 106 | -------------------------------------------------------------------------------- /scripts/golden_reset: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "Removing all golden files..." 4 | rm -rf 5 | find ./test/ps/output -name 'golden.*' -delete 6 | cabal test 7 | -------------------------------------------------------------------------------- /scripts/prepare_release: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euxo pipefail 4 | 5 | nix build '.#static' 6 | mkdir -p dist 7 | rm -f -- dist/pslua-linux_x86_64.tar.gz 8 | rm -f -- dist/pslua 9 | upx --best ./result/bin/pslua -o ./dist/pslua 10 | rm -rf ./result 11 | tar -czcf dist/pslua-linux_x86_64.tar.gz -C ./dist pslua 12 | -------------------------------------------------------------------------------- /shell.nix: -------------------------------------------------------------------------------- 1 | (builtins.getFlake 2 | ("git+file://" + toString ./.)).devShells.${builtins.currentSystem}.default 3 | -------------------------------------------------------------------------------- /test/Hedgehog/Gen/Extended.hs: -------------------------------------------------------------------------------- 1 | module Hedgehog.Gen.Extended 2 | ( module Gen 3 | , recursiveFrequency 4 | ) where 5 | 6 | import Hedgehog (MonadGen) 7 | import Hedgehog.Gen as Gen 8 | 9 | recursiveFrequency ∷ MonadGen m ⇒ [(Int, m a)] → [(Int, m a)] → m a 10 | recursiveFrequency nonrecur recur = 11 | Gen.sized $ \n → 12 | if n <= 1 13 | then Gen.frequency nonrecur 14 | else Gen.frequency $ nonrecur <> fmap (fmap Gen.small) recur 15 | -------------------------------------------------------------------------------- /test/Language/PureScript/Backend/IR/Gen.hs: -------------------------------------------------------------------------------- 1 | module Language.PureScript.Backend.IR.Gen where 2 | 3 | import Data.Text qualified as Text 4 | import Hedgehog (MonadGen) 5 | import Hedgehog.Corpus qualified as Corpus 6 | import Hedgehog.Gen.Extended qualified as Gen 7 | import Hedgehog.Range qualified as Range 8 | import Language.PureScript.Backend.IR.Names qualified as IR 9 | import Language.PureScript.Backend.IR.Types (noAnn) 10 | import Language.PureScript.Backend.IR.Types qualified as IR 11 | import Language.PureScript.Names (ModuleName, moduleNameFromString) 12 | import Prelude hiding (exp) 13 | 14 | exp ∷ ∀ m. MonadGen m ⇒ m IR.Exp 15 | exp = 16 | Gen.recursiveFrequency 17 | [(1, nonRecursiveExp)] 18 | [ 19 | ( 7 20 | , Gen.subterm2 exp exp IR.application 21 | ) 22 | , 23 | ( 3 24 | , Gen.subterm3 exp exp exp IR.ifThenElse 25 | ) 26 | , 27 | ( 1 28 | , Gen.subtermM exp \e → 29 | IR.arrayIndex e <$> Gen.integral (Range.linear 0 9) 30 | ) 31 | , 32 | ( 1 33 | , Gen.subtermM exp \e → IR.objectProp e <$> genPropName 34 | ) 35 | , 36 | ( 2 37 | , IR.literalArray <$> Gen.list (Range.linear 1 10) exp 38 | ) 39 | , 40 | ( 2 41 | , IR.literalObject <$> Gen.list (Range.linear 1 10) ((,) <$> genPropName <*> exp) 42 | ) 43 | , 44 | ( 1 45 | , Gen.subtermM exp \e → 46 | IR.objectUpdate e 47 | <$> Gen.nonEmpty (Range.linear 1 10) ((,) <$> genPropName <*> exp) 48 | ) 49 | , 50 | ( 5 51 | , Gen.subtermM exp \e → (`IR.abstraction` e) <$> parameter 52 | ) 53 | , 54 | ( 6 55 | , Gen.subtermM exp \e → 56 | (`IR.lets` e) <$> Gen.nonEmpty (Range.linear 1 5) binding 57 | ) 58 | ] 59 | 60 | binding ∷ MonadGen m ⇒ m IR.Binding 61 | binding = Gen.frequency [(8, standaloneBinding), (2, recursiveBinding)] 62 | 63 | namedExp ∷ MonadGen m ⇒ m (IR.Ann, IR.Name, IR.Exp) 64 | namedExp = (noAnn,,) <$> name <*> exp 65 | 66 | recursiveBinding ∷ MonadGen m ⇒ m IR.Binding 67 | recursiveBinding = 68 | IR.RecursiveGroup <$> Gen.nonEmpty (Range.linear 1 5) namedExp 69 | 70 | standaloneBinding ∷ MonadGen m ⇒ m IR.Binding 71 | standaloneBinding = IR.Standalone <$> namedExp 72 | 73 | nonRecursiveExp ∷ MonadGen m ⇒ m IR.Exp 74 | nonRecursiveExp = 75 | Gen.frequency 76 | [ (5, literalNonRecursiveExp) 77 | , (1, exception) 78 | , (1, ctor) 79 | , (3, IR.ref <$> qualified name <*> pure 0) 80 | ] 81 | 82 | exception ∷ MonadGen m ⇒ m IR.Exp 83 | exception = IR.exception <$> Gen.text (Range.linear 0 10) Gen.unicode 84 | 85 | ctor ∷ MonadGen m ⇒ m IR.Exp 86 | ctor = 87 | IR.ctor 88 | <$> Gen.enumBounded 89 | <*> moduleName 90 | <*> tyName 91 | <*> ctorName 92 | <*> Gen.list (Range.linear 0 10) fieldName 93 | 94 | literalNonRecursiveExp ∷ MonadGen m ⇒ m IR.Exp 95 | literalNonRecursiveExp = 96 | Gen.frequency 97 | [ (5, scalarExp) 98 | , (1, pure $ IR.literalArray []) 99 | , (1, pure $ IR.literalObject []) 100 | ] 101 | 102 | scalarExp ∷ MonadGen m ⇒ m IR.Exp 103 | scalarExp = 104 | Gen.choice 105 | [ IR.literalInt <$> Gen.integral (Range.exponential 0 1000) 106 | , IR.literalString <$> Gen.text (Range.linear 0 10) Gen.unicode 107 | , IR.literalBool <$> Gen.bool 108 | , IR.literalChar <$> Gen.unicode 109 | , IR.literalFloat 110 | <$> Gen.double 111 | (Range.exponentialFloat 0 1000000000000000000) 112 | ] 113 | 114 | parameter ∷ MonadGen m ⇒ m (IR.Parameter IR.Ann) 115 | parameter = 116 | Gen.frequency 117 | [ (1, pure (IR.ParamUnused noAnn)) 118 | , (9, IR.ParamNamed noAnn <$> name) 119 | ] 120 | 121 | qualified ∷ MonadGen m ⇒ m a → m (IR.Qualified a) 122 | qualified q = 123 | Gen.frequency 124 | [ (8, IR.Local <$> q) 125 | , (2, IR.Imported <$> moduleName <*> q) 126 | ] 127 | 128 | refLocal ∷ MonadGen m ⇒ m IR.Exp 129 | refLocal = flip IR.refLocal 0 <$> name 130 | 131 | moduleName ∷ MonadGen m ⇒ m ModuleName 132 | moduleName = moduleNameFromString <$> Gen.element Corpus.colours 133 | 134 | name ∷ MonadGen m ⇒ m IR.Name 135 | name = IR.Name <$> Gen.element ["x", "y", "z", "i", "j", "k", "l"] 136 | 137 | tyName ∷ MonadGen m ⇒ m IR.TyName 138 | tyName = IR.TyName . Text.toTitle <$> Gen.element Corpus.waters 139 | 140 | ctorName ∷ MonadGen m ⇒ m IR.CtorName 141 | ctorName = IR.CtorName . Text.toTitle <$> Gen.element Corpus.colours 142 | 143 | genPropName ∷ MonadGen m ⇒ m IR.PropName 144 | genPropName = IR.PropName <$> Gen.element Corpus.metasyntactic 145 | 146 | fieldName ∷ MonadGen m ⇒ m IR.FieldName 147 | fieldName = IR.FieldName <$> Gen.element Corpus.metasyntactic 148 | -------------------------------------------------------------------------------- /test/Language/PureScript/Backend/IR/Inliner/Spec.hs: -------------------------------------------------------------------------------- 1 | module Language.PureScript.Backend.IR.Inliner.Spec where 2 | 3 | import Hedgehog (MonadTest, failure, footnote, (===)) 4 | import Language.PureScript.Backend.IR.Inliner 5 | ( Annotation (Always, Never) 6 | , Pragma 7 | ) 8 | import Language.PureScript.Backend.IR.Inliner qualified as Inliner 9 | import Language.PureScript.Backend.IR.Names (Name (..)) 10 | import Test.Hspec (Spec, describe) 11 | import Test.Hspec.Hedgehog.Extended (test) 12 | import Text.Megaparsec qualified as Megaparsec 13 | 14 | spec ∷ Spec 15 | spec = describe "IR Inliner" do 16 | describe "parses annotations" do 17 | test "@inline foo always" do 18 | ann ← parseAnn "@inline foo always " 19 | ann === (Name "foo", Always) 20 | test "@inline foo never" do 21 | ann ← parseAnn "@inline foo never " 22 | ann === (Name "foo", Never) 23 | 24 | -------------------------------------------------------------------------------- 25 | -- Helpers --------------------------------------------------------------------- 26 | 27 | parseAnn ∷ MonadTest m ⇒ Text → m Pragma 28 | parseAnn src = do 29 | let parser = Inliner.pragmaParser <* Megaparsec.eof 30 | case Megaparsec.parse parser "" src of 31 | Left eb → do 32 | footnote $ Megaparsec.errorBundlePretty eb 33 | failure 34 | Right ann → pure ann 35 | -------------------------------------------------------------------------------- /test/Language/PureScript/Backend/IR/Types/Spec.hs: -------------------------------------------------------------------------------- 1 | module Language.PureScript.Backend.IR.Types.Spec where 2 | 3 | import Data.Map qualified as Map 4 | import Hedgehog ((===)) 5 | import Language.PureScript.Backend.IR.Names 6 | ( ModuleName (..) 7 | , Name (..) 8 | , Qualified (Imported) 9 | ) 10 | import Language.PureScript.Backend.IR.Types 11 | ( Exp 12 | , Grouping (..) 13 | , abstraction 14 | , application 15 | , countFreeRefs 16 | , lets 17 | , literalInt 18 | , noAnn 19 | , paramNamed 20 | , paramUnused 21 | , refImported 22 | , refLocal 23 | ) 24 | import Test.Hspec (Spec, describe) 25 | import Test.Hspec.Hedgehog.Extended (test) 26 | 27 | spec ∷ Spec 28 | spec = describe "Types" do 29 | test "countFreeRefs" do 30 | countFreeRefs expr 31 | === Map.fromList 32 | [ (Imported (ModuleName "Data.Array") (Name "add"), 1) 33 | , (Imported (ModuleName "Data.Array") (Name "eq1"), 1) 34 | , (Imported (ModuleName "Data.Array") (Name "findLastIndex"), 1) 35 | , (Imported (ModuleName "Data.Array") (Name "fromJust"), 1) 36 | , (Imported (ModuleName "Data.Array") (Name "insertAt"), 1) 37 | , (Imported (ModuleName "Data.Maybe") (Name "maybe"), 1) 38 | , (Imported (ModuleName "Data.Ordering") (Name "GT"), 1) 39 | , (Imported (ModuleName "Partial.Unsafe") (Name "unsafePartial"), 1) 40 | ] 41 | 42 | expr ∷ Exp 43 | expr = 44 | abstraction 45 | (paramNamed (Name "cmp")) 46 | ( abstraction 47 | (paramNamed (Name "x")) 48 | ( abstraction 49 | (paramNamed (Name "ys")) 50 | ( lets 51 | ( Standalone 52 | ( noAnn 53 | , Name "i" 54 | , application 55 | ( application 56 | ( application 57 | (refImported (ModuleName "Data.Maybe") (Name "maybe") 0) 58 | (literalInt 0) 59 | ) 60 | ( abstraction 61 | (paramNamed (Name "v")) 62 | ( application 63 | ( application 64 | (refImported (ModuleName "Data.Array") (Name "add") 0) 65 | (refLocal (Name "v") 0) 66 | ) 67 | (literalInt 1) 68 | ) 69 | ) 70 | ) 71 | ( application 72 | ( application 73 | (refImported (ModuleName "Data.Array") (Name "findLastIndex") 0) 74 | ( abstraction 75 | (paramNamed (Name "y")) 76 | ( application 77 | ( application 78 | (refImported (ModuleName "Data.Array") (Name "eq1") 0) 79 | ( application 80 | ( application 81 | (refLocal (Name "cmp") 0) 82 | (refLocal (Name "x") 0) 83 | ) 84 | (refLocal (Name "y") 0) 85 | ) 86 | ) 87 | (refImported (ModuleName "Data.Ordering") (Name "GT") 0) 88 | ) 89 | ) 90 | ) 91 | (refLocal (Name "ys") 0) 92 | ) 93 | ) 94 | :| [] 95 | ) 96 | ( application 97 | (refImported (ModuleName "Partial.Unsafe") (Name "unsafePartial") 0) 98 | ( abstraction 99 | paramUnused 100 | ( application 101 | (refImported (ModuleName "Data.Array") (Name "fromJust") 0) 102 | ( application 103 | ( application 104 | ( application 105 | (refImported (ModuleName "Data.Array") (Name "insertAt") 0) 106 | (refLocal (Name "i") 0) 107 | ) 108 | (refLocal (Name "x") 0) 109 | ) 110 | (refLocal (Name "ys") 0) 111 | ) 112 | ) 113 | ) 114 | ) 115 | ) 116 | ) 117 | ) 118 | -------------------------------------------------------------------------------- /test/Language/PureScript/Backend/Lua/Gen.hs: -------------------------------------------------------------------------------- 1 | module Language.PureScript.Backend.Lua.Gen where 2 | 3 | import Data.Text qualified as Text 4 | import Hedgehog (Gen, Range) 5 | import Hedgehog.Gen.Extended qualified as Gen 6 | import Hedgehog.Range qualified as Range 7 | import Language.PureScript.Backend.Lua.Name (Name, unsafeName) 8 | import Language.PureScript.Backend.Lua.Printer (printStatement) 9 | import Language.PureScript.Backend.Lua.Types (ParamF (..)) 10 | import Language.PureScript.Backend.Lua.Types qualified as Lua 11 | import Prettyprinter (defaultLayoutOptions, layoutPretty) 12 | import Prettyprinter.Render.Text (renderStrict) 13 | import Prelude hiding (local, return) 14 | 15 | chunk ∷ Gen Lua.Chunk 16 | chunk = Gen.list (Range.linear 1 16) statement 17 | 18 | statement ∷ Gen Lua.Statement 19 | statement = Gen.recursiveFrequency nonRecursiveStatements recursiveStatements 20 | 21 | nonRecursiveStatement ∷ Gen Lua.Statement 22 | nonRecursiveStatement = Gen.frequency nonRecursiveStatements 23 | 24 | nonRecursiveStatements ∷ [(Int, Gen Lua.Statement)] 25 | nonRecursiveStatements = 26 | [ (2, Lua.return <$> expression) 27 | , (2, assign) 28 | , (3, local) 29 | , (1, foreignSourceCode) 30 | ] 31 | 32 | assign ∷ Gen Lua.Statement 33 | assign = Lua.assign <$> nonRecursiveVar <*> expression 34 | 35 | local ∷ Gen Lua.Statement 36 | local = Lua.local <$> name <*> Gen.maybe expression 37 | 38 | ifThenElse ∷ Gen Lua.Statement 39 | ifThenElse = do 40 | cond ← expression 41 | then' ← Gen.list (Range.linear 1 5) statement 42 | else' ← Gen.list (Range.linear 1 5) statement 43 | pure $ Lua.ifThenElse cond then' else' 44 | 45 | recursiveStatements ∷ [(Int, Gen Lua.Statement)] 46 | recursiveStatements = [(2, ifThenElse)] 47 | 48 | foreignSourceCode ∷ Gen Lua.Statement 49 | foreignSourceCode = 50 | Lua.ForeignSourceStat 51 | . renderStrict 52 | . layoutPretty defaultLayoutOptions 53 | . printStatement 54 | . Lua.return 55 | <$> table 56 | 57 | tableRow ∷ Gen Lua.TableRow 58 | tableRow = 59 | Gen.frequency 60 | [ (1, Lua.tableRowKV <$> expression <*> expression) 61 | , (2, Lua.tableRowNV <$> name <*> expression) 62 | ] 63 | 64 | name ∷ Gen Name 65 | name = do 66 | firstChar ← Gen.frequency [(8, Gen.alpha), (2, Gen.constant '_')] 67 | let nextChar = Gen.frequency [(8, Gen.alphaNum), (2, Gen.constant '_')] 68 | followingChars ← Gen.list (Range.linearFrom 3 1 16) nextChar 69 | pure . unsafeName $ Text.cons firstChar (Text.pack followingChars) 70 | 71 | expression ∷ Gen Lua.Exp 72 | expression = Gen.recursiveFrequency nonRecursiveExpressions recursiveExpressions 73 | 74 | nonRecursiveExpression ∷ Gen Lua.Exp 75 | nonRecursiveExpression = Gen.frequency nonRecursiveExpressions 76 | 77 | nonRecursiveExpressions ∷ [(Int, Gen Lua.Exp)] 78 | nonRecursiveExpressions = 79 | [ (2, nil) 80 | , (1, literalBool) 81 | , (2, literalInt) 82 | , (1, literalFloat) 83 | , (2, literalString) 84 | , (3, Lua.var <$> nonRecursiveVar) 85 | ] 86 | 87 | nil ∷ Gen Lua.Exp 88 | nil = Gen.constant Lua.Nil 89 | 90 | literalBool ∷ Gen Lua.Exp 91 | literalBool = Lua.Boolean <$> Gen.bool 92 | 93 | literalInt ∷ Gen Lua.Exp 94 | literalInt = Lua.Integer <$> Gen.integral integerRange 95 | where 96 | integerRange ∷ Range Integer 97 | integerRange = fromIntegral <$> (Range.exponentialBounded ∷ Range Int64) 98 | 99 | literalFloat ∷ Gen Lua.Exp 100 | literalFloat = 101 | Lua.Float 102 | <$> Gen.double (Range.exponentialFloatFrom 0 (-1234567890.0) 1234567890) 103 | 104 | literalString ∷ Gen Lua.Exp 105 | literalString = Lua.String <$> Gen.text (Range.linear 1 16) Gen.unicode 106 | 107 | nonRecursiveVar ∷ Gen Lua.Var 108 | nonRecursiveVar = Gen.frequency [(1, Lua.VarName <$> name)] 109 | 110 | recursiveExpressions ∷ [(Int, Gen Lua.Exp)] 111 | recursiveExpressions = 112 | [ (3, function) 113 | , (1, unOp) 114 | , (2, binOp) 115 | , (1, table) 116 | , (5, recursiveVar) 117 | , (3, functionCall) 118 | ] 119 | 120 | function ∷ Gen Lua.Exp 121 | function = 122 | Lua.functionDef 123 | <$> Gen.list 124 | (Range.linear 0 5) 125 | (maybe ParamUnused ParamNamed <$> Gen.maybe name) 126 | <*> chunk 127 | 128 | unOp ∷ Gen Lua.Exp 129 | unOp = Lua.unOp <$> Gen.enumBounded <*> expression 130 | 131 | binOp ∷ Gen Lua.Exp 132 | binOp = Lua.binOp <$> Gen.enumBounded <*> expression <*> expression 133 | 134 | table ∷ Gen Lua.Exp 135 | table = Lua.table <$> Gen.list (Range.linear 0 5) tableRow 136 | 137 | recursiveVar ∷ Gen Lua.Exp 138 | recursiveVar = do 139 | Gen.choice 140 | [ Lua.varIndex <$> expression <*> expression 141 | , Lua.varField <$> expression <*> name 142 | ] 143 | 144 | functionCall ∷ Gen Lua.Exp 145 | functionCall = 146 | Lua.functionCall <$> expression <*> Gen.list (Range.linear 0 5) expression 147 | -------------------------------------------------------------------------------- /test/Language/PureScript/Backend/Lua/Linker/Foreign/Spec.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE QuasiQuotes #-} 2 | {-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} 3 | 4 | {-# HLINT ignore "Use fewer imports" #-} 5 | 6 | module Language.PureScript.Backend.Lua.Linker.Foreign.Spec where 7 | 8 | import Data.List.NonEmpty qualified as NE 9 | import Data.String.Interpolate (__i) 10 | import Language.PureScript.Backend.Lua.Key (Key (..)) 11 | import Language.PureScript.Backend.Lua.Linker.Foreign 12 | import Language.PureScript.Backend.Lua.Name (unsafeName) 13 | import Path (relfile, toFilePath, ()) 14 | import Path.IO (withSystemTempDir) 15 | import Test.HUnit (Assertion) 16 | import Test.Hspec (Spec, describe, it) 17 | import Test.Hspec.Expectations.Pretty (shouldBe) 18 | import Text.Megaparsec qualified as M 19 | 20 | spec ∷ Spec 21 | spec = do 22 | describe "Foreign parser" do 23 | it "exports" do 24 | shouldParse moduleParser (toText rawExports) parsedExports 25 | 26 | it "value" do 27 | shouldParse valueParser "(((x)(y)))" "((x)(y))" 28 | 29 | describe "Foreign module parser" do 30 | it "parses file" do 31 | foreignSource ← withSystemTempDir "foreigns" \foreigns → do 32 | let path = toFilePath $ foreigns [relfile|Foo.lua|] 33 | writeFile path $ rawHeader <> "\n" <> rawExports 34 | parseForeignSource foreigns path 35 | case foreignSource of 36 | Left err → fail $ show err 37 | Right source → 38 | source 39 | `shouldBe` Source 40 | { header = Just (toText rawHeader) 41 | , exports = parsedExports 42 | } 43 | 44 | shouldParse ∷ (Eq a, Show a) ⇒ Parser a → Text → a → Assertion 45 | shouldParse p s e = 46 | case M.parse p "Test" s of 47 | Left eb → fail $ M.errorBundlePretty eb 48 | Right a → a `shouldBe` e 49 | 50 | rawHeader ∷ String 51 | rawHeader = 52 | [__i| 53 | function foo() 54 | return 42 55 | end 56 | local boo = "boo" 57 | local zoo = "boo" .. "zoo" 58 | |] 59 | 60 | rawExports ∷ String 61 | rawExports = 62 | [__i| 63 | return { 64 | foo = (42), 65 | bar = ("ok"), 66 | baz = (function(unused) 67 | return zoo 68 | end), 69 | [ "if"]= (function() return "if" end), 70 | } 71 | |] 72 | 73 | parsedExports ∷ NE.NonEmpty (Key, Text) 74 | parsedExports = 75 | (unsafeKey "foo", "42") 76 | :| [ (unsafeKey "bar", "\"ok\"") 77 | , (unsafeKey "baz", "function(unused)\n return zoo\n end") 78 | , (KeyReserved "if", "function() return \"if\" end") 79 | ] 80 | 81 | unsafeKey ∷ Text → Key 82 | unsafeKey = KeyName . unsafeName 83 | -------------------------------------------------------------------------------- /test/Language/PureScript/Backend/Lua/Optimizer/Spec.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE QuasiQuotes #-} 2 | 3 | module Language.PureScript.Backend.Lua.Optimizer.Spec where 4 | 5 | import Language.PureScript.Backend.Lua.Name (name) 6 | import Language.PureScript.Backend.Lua.Optimizer 7 | ( pushDeclarationsDownTheInnerScope 8 | , removeScopeWhenInsideEmptyFunction 9 | , rewriteExpWithRule 10 | ) 11 | import Language.PureScript.Backend.Lua.Types (ParamF (..)) 12 | import Language.PureScript.Backend.Lua.Types qualified as Lua 13 | import Test.Hspec (Spec, describe, it) 14 | import Test.Hspec.Expectations.Pretty (assertEqual) 15 | import Text.Pretty.Simple (pShow) 16 | 17 | spec ∷ Spec 18 | spec = describe "Lua AST Optimizer" do 19 | describe "optimizes expressions" do 20 | it "removes scope when inside an empty function" do 21 | let original ∷ Lua.Exp = 22 | Lua.functionDef 23 | [ParamNamed [name|a|]] 24 | [ Lua.return 25 | ( Lua.functionDef 26 | [ParamNamed [name|b|]] 27 | [Lua.return (Lua.scope [Lua.return (Lua.varName [name|c|])])] 28 | ) 29 | ] 30 | expected ∷ Lua.Exp = 31 | Lua.functionDef 32 | [ParamNamed [name|a|]] 33 | [ Lua.return 34 | ( Lua.functionDef 35 | [ParamNamed [name|b|]] 36 | [Lua.return (Lua.varName [name|c|])] 37 | ) 38 | ] 39 | assertEqual (toString $ pShow original) expected $ 40 | rewriteExpWithRule removeScopeWhenInsideEmptyFunction original 41 | 42 | it "pushes declarations down into an inner scope" do 43 | let original ∷ Lua.Exp = 44 | Lua.functionDef 45 | [ParamNamed [name|a|], ParamNamed [name|b|]] 46 | [ Lua.local1 [name|i|] (Lua.Integer 42) 47 | , Lua.local1 [name|j|] (Lua.Integer 43) 48 | , Lua.return 49 | ( Lua.functionDef 50 | [ParamNamed [name|d|]] 51 | [Lua.return (Lua.varName [name|c|])] 52 | ) 53 | ] 54 | expected ∷ Lua.Exp = 55 | Lua.functionDef 56 | [ParamNamed [name|a|], ParamNamed [name|b|]] 57 | [ Lua.return 58 | ( Lua.functionDef 59 | [ParamNamed [name|d|]] 60 | [ Lua.local1 [name|i|] (Lua.Integer 42) 61 | , Lua.local1 [name|j|] (Lua.Integer 43) 62 | , Lua.return (Lua.varName [name|c|]) 63 | ] 64 | ) 65 | ] 66 | assertEqual (toString $ pShow @Lua.Exp original) expected $ 67 | rewriteExpWithRule pushDeclarationsDownTheInnerScope original 68 | -------------------------------------------------------------------------------- /test/Main.hs: -------------------------------------------------------------------------------- 1 | module Main where 2 | 3 | import Language.PureScript.Backend.IR.DCE.Spec qualified as IrDce 4 | import Language.PureScript.Backend.IR.Inliner.Spec qualified as Inliner 5 | import Language.PureScript.Backend.IR.Optimizer.Spec qualified as IROptimizer 6 | import Language.PureScript.Backend.IR.Spec qualified as IR 7 | import Language.PureScript.Backend.IR.Types.Spec qualified as Types 8 | import Language.PureScript.Backend.Lua.DCE.Spec qualified as LuaDce 9 | import Language.PureScript.Backend.Lua.Golden.Spec qualified as Golden 10 | import Language.PureScript.Backend.Lua.Linker.Foreign.Spec qualified as LuaLinkerForeign 11 | import Language.PureScript.Backend.Lua.Optimizer.Spec qualified as LuaOptimizer 12 | import Language.PureScript.Backend.Lua.Printer.Spec qualified as Printer 13 | import Test.Hspec (hspec) 14 | 15 | main ∷ IO () 16 | main = hspec do 17 | IR.spec 18 | Inliner.spec 19 | Golden.spec 20 | IrDce.spec 21 | LuaDce.spec 22 | Types.spec 23 | IROptimizer.spec 24 | LuaOptimizer.spec 25 | Printer.spec 26 | LuaLinkerForeign.spec 27 | -------------------------------------------------------------------------------- /test/Test/Hspec/Expectations/Pretty.hs: -------------------------------------------------------------------------------- 1 | module Test.Hspec.Expectations.Pretty where 2 | 3 | import Control.Exception (throwIO) 4 | import Data.CallStack (SrcLoc, callStack) 5 | import Test.HUnit.Lang 6 | ( Assertion 7 | , FailureReason (ExpectedButGot) 8 | , HUnitFailure (HUnitFailure) 9 | ) 10 | import Text.Pretty.Simple (pShow) 11 | 12 | shouldBe ∷ (HasCallStack, Eq a, Show a) ⇒ a → a → Assertion 13 | shouldBe expected actual = assertEqual "" actual expected 14 | 15 | {- | Asserts that the specified actual value is equal to the expected value. 16 | The output message will contain the prefix, the expected value, and the 17 | actual value. 18 | 19 | If the prefix is the empty string (i.e., @\"\"@), then the prefix is omitted 20 | and only the expected and actual values are output. 21 | -} 22 | assertEqual 23 | ∷ (HasCallStack, Eq a, Show a) 24 | ⇒ String 25 | -- ^ The message prefix 26 | → a 27 | -- ^ The expected value 28 | → a 29 | -- ^ The actual value 30 | → Assertion 31 | assertEqual preface expected actual = 32 | unless (actual == expected) do 33 | prefaceMsg 34 | `deepseq` expectedMsg 35 | `deepseq` actualMsg 36 | `deepseq` throwIO 37 | ( HUnitFailure location $ 38 | ExpectedButGot prefaceMsg expectedMsg actualMsg 39 | ) 40 | where 41 | prefaceMsg 42 | | null preface = Nothing 43 | | otherwise = Just preface 44 | expectedMsg = toString $ pShow expected 45 | actualMsg = toString $ pShow actual 46 | 47 | location ∷ HasCallStack ⇒ Maybe SrcLoc 48 | location = case reverse Data.CallStack.callStack of 49 | (_, loc) : _ → Just loc 50 | [] → Nothing 51 | -------------------------------------------------------------------------------- /test/Test/Hspec/Extra.hs: -------------------------------------------------------------------------------- 1 | module Test.Hspec.Extra where 2 | 3 | import Control.Exception (catch, throwIO) 4 | import Test.HUnit.Lang 5 | ( FailureReason (Reason) 6 | , HUnitFailure (HUnitFailure) 7 | , formatFailureReason 8 | ) 9 | import Test.Hspec (Expectation) 10 | 11 | {- | 12 | Decorate an @'Expectation'@ with a message. The @'String'@ is prepended to 13 | failure messages. 14 | 15 | @ 16 | myValue `shouldBe` myExpectation `annotatingWith` "Oh GAWD no!" 17 | @ 18 | -} 19 | annotatingWith ∷ Expectation → String → Expectation 20 | annotatingWith action message = 21 | action `catch` \(HUnitFailure l r) → 22 | throwIO . HUnitFailure l . Reason $ 23 | message <> "\n\n" <> formatFailureReason r 24 | 25 | infix 0 `annotatingWith` 26 | -------------------------------------------------------------------------------- /test/Test/Hspec/Golden.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE FlexibleInstances #-} 2 | {-# LANGUAGE RecordWildCards #-} 3 | {-# LANGUAGE TypeFamilies #-} 4 | 5 | module Test.Hspec.Golden 6 | ( Golden (..) 7 | , defaultGolden 8 | ) 9 | where 10 | 11 | import Path (Abs, File, Path, parent, toFilePath) 12 | import Path.IO (createDirIfMissing, doesFileExist) 13 | import Test.Hspec.Core.Spec 14 | ( Example (..) 15 | , FailureReason (..) 16 | , Result (..) 17 | , ResultStatus (..) 18 | ) 19 | 20 | {- | Golden tests parameters 21 | 22 | @ 23 | import Data.Text (Text) 24 | import qualified Data.Text.IO as T 25 | 26 | goldenText :: Path Abs File -> Text -> Golden Text 27 | goldenText name actualOutput = 28 | Golden { 29 | output = actualOutput, 30 | encodePretty = prettyText, 31 | writeToFile = T.writeFile, 32 | readFromFile = T.readFile, 33 | goldenFile = ".specific-golden-dir" name "golden", 34 | actualFile = Just (".specific-golden-dir" name "actual"), 35 | failFirstTime = False 36 | } 37 | 38 | describe "myTextFunc" $ 39 | it "generates the right output with the right params" $ 40 | goldenText "myTextFunc" (myTextFunc params) 41 | @ 42 | -} 43 | data Golden str = Golden 44 | { produceOutput ∷ IO str 45 | -- ^ Output 46 | , encodePretty ∷ str → String 47 | -- ^ Makes the comparison pretty when the test fails 48 | , writeToFile ∷ Path Abs File → str → IO () 49 | -- ^ How to write into the golden file the file 50 | , readFromFile ∷ Path Abs File → IO str 51 | -- ^ How to read the file, 52 | , goldenFile ∷ Path Abs File 53 | -- ^ Where to read/write the golden file for this test. 54 | , actualFile ∷ Maybe (Path Abs File) 55 | -- ^ Where to save the actual file for this test. 56 | -- If it is @Nothing@ then no file is written. 57 | , failFirstTime ∷ Bool 58 | -- ^ Whether to record a failure the first time this test is run 59 | } 60 | 61 | instance Eq str ⇒ Example (Golden str) where 62 | type Arg (Golden str) = () 63 | evaluateExample e = evaluateExample (\() → e) 64 | 65 | instance Eq str ⇒ Example (arg → Golden str) where 66 | type Arg (arg → Golden str) = arg 67 | evaluateExample golden _ action _ = do 68 | ref ← newIORef (Result "" Success) 69 | action $ \arg → do 70 | r ← runGolden (golden arg) 71 | writeIORef ref (fromGoldenResult r) 72 | readIORef ref 73 | 74 | -- | Transform a GoldenResult into a Result from Hspec 75 | fromGoldenResult ∷ GoldenResult → Result 76 | fromGoldenResult = \case 77 | SameOutput → 78 | Result "Golden and Actual output hasn't changed" Success 79 | FirstExecutionSucceed → 80 | Result "First time execution. Golden file created." Success 81 | FirstExecutionFail → 82 | Result 83 | "First time execution. Golden file created." 84 | (Failure Nothing (Reason "failFirstTime is set to True")) 85 | MissmatchOutput expected actual → 86 | Result 87 | "Files golden and actual not match" 88 | (Failure Nothing (ExpectedButGot Nothing expected actual)) 89 | 90 | defaultGolden 91 | ∷ Path Abs File 92 | → Maybe (Path Abs File) 93 | → IO Text 94 | → Golden Text 95 | defaultGolden goldenFile actualFile produceOutput = 96 | Golden 97 | { produceOutput 98 | , encodePretty = show 99 | , writeToFile = \f → writeFileBS (toFilePath f) . encodeUtf8 100 | , readFromFile = fmap decodeUtf8 . readFileBS . toFilePath 101 | , goldenFile 102 | , actualFile 103 | , failFirstTime = False 104 | } 105 | 106 | -- | Possible results from a golden test execution 107 | data GoldenResult 108 | = MissmatchOutput String String 109 | | SameOutput 110 | | FirstExecutionSucceed 111 | | FirstExecutionFail 112 | 113 | -- | Runs a Golden test. 114 | runGolden ∷ Eq str ⇒ Golden str → IO GoldenResult 115 | runGolden Golden {..} = do 116 | let goldenTestDir = parent goldenFile 117 | createDirIfMissing True goldenTestDir 118 | goldenFileExist ← doesFileExist goldenFile 119 | output ← produceOutput 120 | 121 | case actualFile of 122 | Nothing → pass 123 | Just actual → do 124 | let actualDir = parent actual 125 | createDirIfMissing True actualDir 126 | writeToFile actual output 127 | 128 | if not goldenFileExist 129 | then do 130 | writeToFile goldenFile output 131 | pure $ 132 | if failFirstTime 133 | then FirstExecutionFail 134 | else FirstExecutionSucceed 135 | else do 136 | contentGolden ← readFromFile goldenFile 137 | pure 138 | if contentGolden == output 139 | then SameOutput 140 | else 141 | MissmatchOutput 142 | (encodePretty contentGolden) 143 | (encodePretty output) 144 | -------------------------------------------------------------------------------- /test/Test/Hspec/Hedgehog/Extended.hs: -------------------------------------------------------------------------------- 1 | module Test.Hspec.Hedgehog.Extended 2 | ( module H 3 | , test 4 | , xtest 5 | ) where 6 | 7 | import Hedgehog (PropertyT) 8 | import Test.Hspec (SpecWith, it, xit) 9 | import Test.Hspec.Hedgehog (hedgehog, modifyMaxShrinks, modifyMaxSuccess) 10 | import Test.Hspec.Hedgehog qualified as H 11 | 12 | test ∷ String → PropertyT IO () → SpecWith () 13 | test title = 14 | modifyMaxShrinks (const 0) 15 | . modifyMaxSuccess (const 1) 16 | . it title 17 | . hedgehog 18 | 19 | xtest ∷ String → PropertyT IO () → SpecWith () 20 | xtest title = xit title . hedgehog 21 | -------------------------------------------------------------------------------- /test/ps/.gitignore: -------------------------------------------------------------------------------- 1 | /bower_components/ 2 | /node_modules/ 3 | /.pulp-cache/ 4 | /output/*/*.cbor 5 | /output/*/*.json 6 | !/output/Golden*/corefn.json 7 | /output/*/*.js 8 | /output/*/actual.* 9 | /output/*.json 10 | /output-es/ 11 | /generated-docs/ 12 | /.psc-package/ 13 | /.psc* 14 | /.purs* 15 | /.psa* 16 | /.spago 17 | -------------------------------------------------------------------------------- /test/ps/golden/Golden/Annotations/M1.lua: -------------------------------------------------------------------------------- 1 | local step = 2 2 | return { 3 | dontInlineClosure = (function(i) 4 | return i + step 5 | end), 6 | inlineMeLambda = (function(i) 7 | return i + i 8 | end) 9 | } 10 | -------------------------------------------------------------------------------- /test/ps/golden/Golden/Annotations/M1.purs: -------------------------------------------------------------------------------- 1 | -- @inline inlineMe always 2 | -- @inline inlineMeLambda always 3 | module Golden.Annotations.M1 where 4 | 5 | inlineMe :: Int -> Int 6 | inlineMe 1 = 2 7 | inlineMe x = x 8 | 9 | foreign import dontInlineClosure :: Int -> Int 10 | foreign import inlineMeLambda :: Int -> Int 11 | -------------------------------------------------------------------------------- /test/ps/golden/Golden/Annotations/M2.purs: -------------------------------------------------------------------------------- 1 | module Golden.Annotations.M2 where 2 | 3 | import Golden.Annotations.M1 (dontInlineClosure, inlineMe, inlineMeLambda) 4 | 5 | inlineIntoMe :: Int -> Int 6 | inlineIntoMe i = inlineMe (inlineMe (inlineMe i)) 7 | 8 | inlineIntoMe2 :: Int 9 | inlineIntoMe2 = dontInlineClosure(inlineMeLambda (inlineIntoMe3 17)) 10 | where 11 | inlineIntoMe3 :: Int -> Int 12 | inlineIntoMe3 = inlineMeLambda 13 | -------------------------------------------------------------------------------- /test/ps/golden/Golden/ArrayOfUnits/Test.purs: -------------------------------------------------------------------------------- 1 | module Golden.ArrayOfUnits.Test where 2 | 3 | import Prelude (Unit, discard, unit) 4 | 5 | import Effect (Effect) 6 | import Effect.Console (logShow) 7 | import Data.Traversable (traverse_) 8 | import Data.Foldable (length) 9 | 10 | main :: Effect Unit 11 | main = do 12 | let arr :: Array Unit 13 | arr = [unit, unit, unit] 14 | traverse_ logShow arr 15 | let len :: Int 16 | len = length arr 17 | logShow len 18 | -------------------------------------------------------------------------------- /test/ps/golden/Golden/Beta/Test.purs: -------------------------------------------------------------------------------- 1 | module Golden.Beta.Test (g) where 2 | 3 | f :: Int -> Int 4 | f 42 = 42 5 | f _ = 1 6 | 7 | g :: Int -> Int 8 | g x = f x 9 | -------------------------------------------------------------------------------- /test/ps/golden/Golden/Bug1/Test.purs: -------------------------------------------------------------------------------- 1 | module Golden.Bug1.Test where 2 | 3 | test :: Int 4 | test = 5 | let go r = { elem: r.elem } 6 | in _.elem (go { elem: 1 }) 7 | -------------------------------------------------------------------------------- /test/ps/golden/Golden/CaseStatements/Test.purs: -------------------------------------------------------------------------------- 1 | module Golden.CaseStatements.Test where 2 | 3 | import Golden.Values.Test (f) 4 | 5 | a ∷ Int 6 | a = 1 7 | 8 | b ∷ Char 9 | b = 'b' 10 | 11 | c ∷ Int 12 | c = 13 | case a, b of 14 | 1, 'b' | f 2, f 1 -> 42 15 | 2, _ | f 0 -> 10 16 | y@(z@3), _ | f z -> y 17 | y@(z@4), _ | f y -> z 18 | _, _ -> 0 19 | 20 | {- 21 | 22 | let v = \v1 -> 0 23 | in 24 | case a, b of 25 | 1, 'b' -> 26 | case f 2 of 27 | true -> 28 | case f 1 of 29 | true -> 42 30 | _ -> v true 31 | _ -> v true 32 | _, _ -> v true 33 | 34 | -} 35 | 36 | data M a = J a | N 37 | 38 | d :: M Int -> M String -> Char -> Int 39 | d m n x = 40 | case x of 41 | 'x' | J y <- m, N <- n -> y 42 | 'y' -> 0 43 | _ -> 1 44 | 45 | {- 46 | 47 | \m -> \n -> \x -> 48 | let v = \v1 -> 49 | case x of 50 | 'y' -> 0 51 | _ -> 1 52 | 'x' -> 53 | 54 | 55 | -} 56 | 57 | multipleGuards ∷ Int 58 | multipleGuards 59 | | false = 0 60 | | true = 1 61 | 62 | {- 63 | 64 | Case 65 | [ ] 66 | [ CaseAlternative 67 | { caseAlternativeBinders = [] 68 | , caseAlternativeResult = 69 | Left 70 | [ ( Literal (BooleanLiteral False) 71 | , Literal (NumericLiteral (Left 0)) 72 | ) 73 | , ( Literal (BooleanLiteral True) 74 | , Literal (NumericLiteral (Left 1)) 75 | ) 76 | ] 77 | } 78 | ] 79 | 80 | -} 81 | -------------------------------------------------------------------------------- /test/ps/golden/Golden/Currying/Test.purs: -------------------------------------------------------------------------------- 1 | module Golden.Currying.Test where 2 | 3 | apply :: forall a b. (a -> b) -> a -> b 4 | apply f x = f x 5 | 6 | f :: Int -> Boolean -> Char -> Number -> String 7 | f i b c d = "ok" 8 | -------------------------------------------------------------------------------- /test/ps/golden/Golden/DataDeclarations/Test1.purs: -------------------------------------------------------------------------------- 1 | module Golden.DataDeclarations.Test1 where 2 | 3 | data Void 4 | data Unit = U 5 | data TProduct = P3 Int Boolean String 6 | data TProductWithFields = PF { ii :: Int, bb :: Boolean, ss :: String } 7 | data TSum = S0 | S1 Char | S2 Int Boolean 8 | data Rec = Nop | More Rec 9 | data TySameName = CtorSameName 10 | -------------------------------------------------------------------------------- /test/ps/golden/Golden/DataDeclarations/Test2.purs: -------------------------------------------------------------------------------- 1 | module Golden.DataDeclarations.Test2 where 2 | 3 | import Golden.DataDeclarations.Test1 as TDD1 4 | 5 | data TySameName = CtorSameName 6 | 7 | test :: TDD1.TySameName -> TySameName -> Boolean 8 | test TDD1.CtorSameName CtorSameName = true 9 | 10 | -------------------------------------------------------------------------------- /test/ps/golden/Golden/Fibonacci/Test.purs: -------------------------------------------------------------------------------- 1 | module Golden.Fibonacci.Test where 2 | 3 | import Prelude 4 | import Effect (Effect) 5 | import Effect.Console (logShow) 6 | 7 | fib :: Int -> Int 8 | fib 0 = 0 9 | fib 1 = 1 10 | fib n = fib (n - 1) + fib (n - 2) 11 | 12 | main :: Effect Unit 13 | main = logShow $ fib 32 -- 2178309 14 | -------------------------------------------------------------------------------- /test/ps/golden/Golden/Foreign/Lib.lua: -------------------------------------------------------------------------------- 1 | return {dead = (-100), alive = (100)} 2 | -------------------------------------------------------------------------------- /test/ps/golden/Golden/Foreign/Lib.purs: -------------------------------------------------------------------------------- 1 | module Golden.Foreign.Lib where 2 | 3 | foreign import dead :: Int 4 | foreign import alive :: Int 5 | -------------------------------------------------------------------------------- /test/ps/golden/Golden/Foreign/Test.lua: -------------------------------------------------------------------------------- 1 | local fooBar = 42 2 | return { 3 | foo = (fooBar + 1), 4 | boo = (fooBar + 2), 5 | baz = (true), 6 | dead = ("beef") 7 | } 8 | -------------------------------------------------------------------------------- /test/ps/golden/Golden/Foreign/Test.purs: -------------------------------------------------------------------------------- 1 | module Golden.Foreign.Test (foo, baz) where 2 | 3 | import Golden.Foreign.Lib 4 | 5 | foreign import foo :: Int 6 | foreign import boo :: Int 7 | 8 | baz :: Array Int 9 | baz = [ boo, alive ] 10 | -------------------------------------------------------------------------------- /test/ps/golden/Golden/HelloPrelude/Test.purs: -------------------------------------------------------------------------------- 1 | module Golden.HelloPrelude.Test where 2 | 3 | import Prelude 4 | import Effect (Effect) 5 | 6 | main :: Effect Unit 7 | main = pass 8 | -------------------------------------------------------------------------------- /test/ps/golden/Golden/Inline/Test.purs: -------------------------------------------------------------------------------- 1 | module Golden.Inline.Test 2 | ( main 3 | , Mu 4 | , runMu 5 | , iMu 6 | ) where 7 | 8 | main :: Int 9 | main = 10 | let x :: forall a. a -> Int 11 | x _ = 1 12 | in let y :: forall b. b -> Int 13 | y _ = 2 14 | in x y 15 | 16 | newtype Mu a = MkMu (Mu a -> a) 17 | 18 | runMu :: forall a. Mu a -> a 19 | runMu mu@(MkMu f) = f mu 20 | 21 | iMu :: Mu Int 22 | iMu = MkMu runMu 23 | -------------------------------------------------------------------------------- /test/ps/golden/Golden/NameShadowing/Test.purs: -------------------------------------------------------------------------------- 1 | module Golden.NameShadowing.Test (b, c) where 2 | 3 | a :: Int -> Int 4 | a x = f x 1 5 | 6 | b :: Int -> Int -> Int 7 | b x x1 = f (f x x1) (a 42) 8 | 9 | c ∷ Int -> Int -> Int 10 | c = \x -> (\y -> \x -> f x y) x 11 | 12 | f :: Int -> Int -> Int 13 | f 1 _ = 1 14 | f _ 1 = 2 15 | f _ _ = 3 16 | -------------------------------------------------------------------------------- /test/ps/golden/Golden/Nested/Test.purs: -------------------------------------------------------------------------------- 1 | module Golden.Nested.Test where 2 | 3 | isZero :: Int -> Boolean 4 | isZero 0 = true 5 | isZero _ = false 6 | 7 | main :: String 8 | main = 9 | if isZero 1 10 | then (if isZero 1 then "ok" else "fine") 11 | else (if isZero 0 then "ha" else "cool") 12 | -------------------------------------------------------------------------------- /test/ps/golden/Golden/Newtype/Test.purs: -------------------------------------------------------------------------------- 1 | module Golden.Newtype.Test where 2 | 3 | newtype NT = NT { foo :: Int } 4 | 5 | f :: NT -> Int 6 | f (NT n) = n.foo 7 | 8 | g :: { foo :: Int } -> NT 9 | g = NT 10 | -------------------------------------------------------------------------------- /test/ps/golden/Golden/PatternMatching/Test1.purs: -------------------------------------------------------------------------------- 1 | module Golden.PatternMatching.Test1 where 2 | 3 | data N = Zero | Succ N 4 | data E = Num N | Not E 5 | 6 | pat :: E -> Int 7 | pat e = case e of 8 | Not (Num (Succ _)) -> 1 9 | Not (Num Zero) -> 2 10 | Not (Not (Num (Succ _))) -> 3 11 | Num (Succ _) -> 4 12 | Num _ -> 5 13 | _ -> 6 14 | 15 | data Tuple = T Int Int 16 | 17 | fst :: Tuple -> Int 18 | fst (T x _) = x 19 | 20 | snd :: Tuple -> Int 21 | snd (T _ y) = y 22 | -------------------------------------------------------------------------------- /test/ps/golden/Golden/PatternMatching/Test2.purs: -------------------------------------------------------------------------------- 1 | module Golden.PatternMatching.Test2 where 2 | 3 | import Golden.PatternMatching.Test1 as P 4 | 5 | data N = Zero | Succ N | Add N N | Mul N N 6 | 7 | pat :: N -> Int 8 | pat e = case e of 9 | (Add (Add _ _) Zero) -> 1 10 | (Add (Mul _ _) Zero) -> 2 11 | (Add _ (Mul _ _)) -> 3 12 | (Add _ (Add _ _)) -> 4 13 | (Add _ Zero) -> 5 14 | _ -> 6 15 | 16 | bat :: P.N -> Int 17 | bat n = case n of 18 | P.Zero -> 1 19 | P.Succ b -> bat b 20 | -------------------------------------------------------------------------------- /test/ps/golden/Golden/RecDataDefs/Test.purs: -------------------------------------------------------------------------------- 1 | module Golden.RecDataDefs.Test where 2 | 3 | data A = A | AB B 4 | data B = B | BA A 5 | 6 | a :: A 7 | a = A 8 | 9 | b :: B 10 | b = B 11 | 12 | ab :: A 13 | ab = AB b 14 | 15 | ba :: B 16 | ba = BA ab 17 | -------------------------------------------------------------------------------- /test/ps/golden/Golden/RecordsAccess/Test.purs: -------------------------------------------------------------------------------- 1 | module Golden.RecordsAccess.Test where 2 | 3 | type R = { x :: Int, y :: Boolean } 4 | 5 | r :: R 6 | r = { x: 1, y: true } 7 | 8 | test1 :: Int 9 | test1 = r.x 10 | 11 | test2 :: R -> Int 12 | test2 = _.x 13 | 14 | test3 :: R -> Int 15 | test3 { x } = x 16 | 17 | test4 :: R -> Int 18 | test4 v = case v of 19 | { x } -> x 20 | -------------------------------------------------------------------------------- /test/ps/golden/Golden/RecordsUpdate/Test.purs: -------------------------------------------------------------------------------- 1 | module Golden.RecordsUpdate.Test where 2 | 3 | type R = { x :: Int, y :: Boolean, z :: Z } 4 | type Z = { z :: String , p :: Char } 5 | 6 | r :: R 7 | r = { x: 1, y: true, z: { z: "foo", p: 'a' } } 8 | 9 | test1 :: R 10 | test1 = r { x = 2 } 11 | 12 | test2 :: R -> R 13 | test2 = _ { y = false } 14 | 15 | test3 :: R -> R 16 | test3 = _ { z { p = 'b' } } 17 | 18 | type Poly r = { x :: Int, y :: Char | r } 19 | 20 | test4 :: forall r. Poly r -> Poly r 21 | test4 = _ { x = 1 } 22 | -------------------------------------------------------------------------------- /test/ps/golden/Golden/RecursiveBindings/Test.purs: -------------------------------------------------------------------------------- 1 | module Golden.RecursiveBindings.Test where 2 | 3 | letRec :: Boolean 4 | letRec = 5 | let 6 | no :: Boolean -> Boolean 7 | no = case _ of 8 | true -> yes false 9 | false -> yes true 10 | 11 | yes :: Boolean -> Boolean 12 | yes = case _ of 13 | true -> no false 14 | false -> no true 15 | in 16 | no false 17 | 18 | whereRec :: Boolean 19 | whereRec = no false 20 | where 21 | no :: Boolean -> Boolean 22 | no = case _ of 23 | true -> yes false 24 | false -> yes true 25 | 26 | yes :: Boolean -> Boolean 27 | yes = case _ of 28 | true -> no false 29 | false -> no true 30 | 31 | letRecMixed :: Int 32 | letRecMixed = 33 | let 34 | z = 1 35 | f _ k = a k 36 | -- ^ non-recursive binding `f` depends on `a` from a mutually recursive group 37 | x = y `f` y -- x depends on `y` definded below. 38 | y = z `f` z -- y depends on `z` definded above. 39 | 40 | -- `a` and `b` form a mutually recursive group: 41 | a _ = b z -- depends on a binding `z` outside of the group 42 | b _ = a z -- depends on a binding `z` outside of the group 43 | 44 | {- 45 | The bindings above are sorted by purs in the following order: 46 | 47 | NonRec: z 48 | Rec: b, a 49 | NonRec: f 50 | NonRec: y 51 | NonRec: x 52 | -} 53 | in 54 | x `f` (y `f` 0) 55 | -------------------------------------------------------------------------------- /test/ps/golden/Golden/Reexport/Exports.purs: -------------------------------------------------------------------------------- 1 | module Golden.Reexport.Exports (binding1) where 2 | 3 | binding1 :: Int 4 | binding1 = 1 5 | -------------------------------------------------------------------------------- /test/ps/golden/Golden/Reexport/ReExports.purs: -------------------------------------------------------------------------------- 1 | module Golden.Reexport.ReExports 2 | ( module Reexported 3 | , binding2 4 | ) where 5 | 6 | import Golden.Reexport.Exports (binding1) as Reexported 7 | 8 | binding2 :: Int 9 | binding2 = 2 10 | -------------------------------------------------------------------------------- /test/ps/golden/Golden/Reexport/Test.purs: -------------------------------------------------------------------------------- 1 | module Golden.Reexport.Test where 2 | 3 | import Golden.Reexport.ReExports 4 | 5 | binding3 :: Array Int 6 | binding3 = [ binding1 , binding2 ] 7 | -------------------------------------------------------------------------------- /test/ps/golden/Golden/ReturnTableField/Test.lua: -------------------------------------------------------------------------------- 1 | return { 2 | u = (nil), 3 | x = ("unused") 4 | } 5 | -------------------------------------------------------------------------------- /test/ps/golden/Golden/ReturnTableField/Test.purs: -------------------------------------------------------------------------------- 1 | module Golden.TestReturnTableField where 2 | 3 | data U 4 | foreign import u :: U 5 | -------------------------------------------------------------------------------- /test/ps/golden/Golden/Unbinding/Test.purs: -------------------------------------------------------------------------------- 1 | module Golden.Unbinding.Test where 2 | 3 | a = 1 4 | b = 2 5 | f _ _ = 3 6 | c = f a (f b a) 7 | -------------------------------------------------------------------------------- /test/ps/golden/Golden/Values/Test.purs: -------------------------------------------------------------------------------- 1 | module Golden.Values.Test where 2 | 3 | i :: Int 4 | i = 1 5 | 6 | b :: Boolean 7 | b = true 8 | 9 | c :: Char 10 | c = 'c' 11 | 12 | a :: Array Int 13 | a = [ 1, 2, 3 ] 14 | 15 | o :: { i :: Int, b :: Boolean, c :: Char } 16 | o = { i, b, c } 17 | 18 | f :: Int -> Boolean 19 | f _ = true 20 | 21 | -------------------------------------------------------------------------------- /test/ps/output/Golden.Annotations.M1/corefn.json: -------------------------------------------------------------------------------- 1 | {"builtWith":"0.15.15","comments":[{"LineComment":" @inline inlineMe always"},{"LineComment":" @inline inlineMeLambda always"}],"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[5,23],"start":[5,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[5,23],"start":[5,1]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[5,23],"start":[5,1]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[6,11],"start":[6,10]}},"binderType":"LiteralBinder","literal":{"literalType":"IntLiteral","value":1}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[6,15],"start":[6,14]}},"type":"Literal","value":{"literalType":"IntLiteral","value":2}},"isGuarded":false},{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[7,11],"start":[7,10]}},"binderType":"VarBinder","identifier":"x"}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[7,15],"start":[7,14]}},"type":"Var","value":{"identifier":"x","sourcePos":[7,10]}},"isGuarded":false}],"caseExpressions":[{"annotation":{"meta":null,"sourceSpan":{"end":[6,15],"start":[6,1]}},"type":"Var","value":{"identifier":"v","sourcePos":[0,0]}}],"type":"Case"},"type":"Abs"},"identifier":"inlineMe"}],"exports":["inlineMe","dontInlineClosure","inlineMeLambda"],"foreign":["dontInlineClosure","inlineMeLambda"],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[10,44],"start":[3,1]}},"moduleName":["Prim"]}],"moduleName":["Golden","Annotations","M1"],"modulePath":"golden/Golden/Annotations/M1.purs","reExports":{},"sourceSpan":{"end":[10,44],"start":[3,1]}} -------------------------------------------------------------------------------- /test/ps/output/Golden.Annotations.M1/golden.ir: -------------------------------------------------------------------------------- 1 | UberModule 2 | { uberModuleBindings = 3 | [ Standalone 4 | ( QName 5 | { qnameModuleName = ModuleName "Golden.Annotations.M1", qnameName = Name "foreign" 6 | }, ForeignImport Nothing 7 | ( ModuleName "Golden.Annotations.M1" ) "golden/Golden/Annotations/M1.purs" 8 | [ ( Nothing, Name "dontInlineClosure" ), ( Just Always, Name "inlineMeLambda" ) ] 9 | ) 10 | ], uberModuleForeigns = [], uberModuleExports = 11 | [ 12 | ( Name "inlineMe", Abs ( Just Always ) 13 | ( ParamNamed Nothing ( Name "v" ) ) 14 | ( IfThenElse Nothing 15 | ( Eq Nothing ( LiteralInt Nothing 1 ) ( Ref Nothing ( Local ( Name "v" ) ) 0 ) ) 16 | ( LiteralInt Nothing 2 ) 17 | ( Ref Nothing ( Local ( Name "v" ) ) 0 ) 18 | ) 19 | ), 20 | ( Name "dontInlineClosure", ObjectProp ( Just Always ) 21 | ( Ref Nothing ( Imported ( ModuleName "Golden.Annotations.M1" ) ( Name "foreign" ) ) 0 ) 22 | ( PropName "dontInlineClosure" ) 23 | ), 24 | ( Name "inlineMeLambda", ObjectProp ( Just Always ) 25 | ( Ref Nothing ( Imported ( ModuleName "Golden.Annotations.M1" ) ( Name "foreign" ) ) 0 ) 26 | ( PropName "inlineMeLambda" ) 27 | ) 28 | ] 29 | } -------------------------------------------------------------------------------- /test/ps/output/Golden.Annotations.M1/golden.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | M.Golden_Annotations_M1_foreign = (function() 3 | local step = 2 4 | return { 5 | dontInlineClosure = function(i) 6 | return i + step 7 | end, 8 | inlineMeLambda = function(i) 9 | return i + i 10 | end 11 | } 12 | end)() 13 | return { 14 | inlineMe = function(v) if 1 == v then return 2 else return v end end, 15 | dontInlineClosure = M.Golden_Annotations_M1_foreign.dontInlineClosure, 16 | inlineMeLambda = M.Golden_Annotations_M1_foreign.inlineMeLambda 17 | } 18 | -------------------------------------------------------------------------------- /test/ps/output/Golden.Annotations.M2/corefn.json: -------------------------------------------------------------------------------- 1 | {"builtWith":"0.15.15","comments":[],"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[8,21],"start":[8,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":{"metaType":"IsWhere"},"sourceSpan":{"end":[9,69],"start":[9,17]}},"binds":[{"annotation":{"meta":null,"sourceSpan":{"end":[11,32],"start":[11,5]}},"bindType":"NonRec","expression":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[12,35],"start":[12,21]}},"type":"Var","value":{"identifier":"inlineMeLambda","moduleName":["Golden","Annotations","M1"]}},"identifier":"inlineIntoMe3"}],"expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[9,34],"start":[9,17]}},"type":"Var","value":{"identifier":"dontInlineClosure","moduleName":["Golden","Annotations","M1"]}},"annotation":{"meta":null,"sourceSpan":{"end":[9,69],"start":[9,17]}},"argument":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[9,49],"start":[9,35]}},"type":"Var","value":{"identifier":"inlineMeLambda","moduleName":["Golden","Annotations","M1"]}},"annotation":{"meta":null,"sourceSpan":{"end":[9,68],"start":[9,35]}},"argument":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[9,64],"start":[9,51]}},"type":"Var","value":{"identifier":"inlineIntoMe3","sourcePos":[11,5]}},"annotation":{"meta":null,"sourceSpan":{"end":[9,67],"start":[9,51]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[9,67],"start":[9,65]}},"type":"Literal","value":{"literalType":"IntLiteral","value":17}},"type":"App"},"type":"App"},"type":"App"},"type":"Let"},"identifier":"inlineIntoMe2"},{"annotation":{"meta":null,"sourceSpan":{"end":[5,27],"start":[5,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[5,27],"start":[5,1]}},"argument":"i","body":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[6,26],"start":[6,18]}},"type":"Var","value":{"identifier":"inlineMe","moduleName":["Golden","Annotations","M1"]}},"annotation":{"meta":null,"sourceSpan":{"end":[6,50],"start":[6,18]}},"argument":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[6,36],"start":[6,28]}},"type":"Var","value":{"identifier":"inlineMe","moduleName":["Golden","Annotations","M1"]}},"annotation":{"meta":null,"sourceSpan":{"end":[6,49],"start":[6,28]}},"argument":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[6,46],"start":[6,38]}},"type":"Var","value":{"identifier":"inlineMe","moduleName":["Golden","Annotations","M1"]}},"annotation":{"meta":null,"sourceSpan":{"end":[6,48],"start":[6,38]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[6,48],"start":[6,47]}},"type":"Var","value":{"identifier":"i","sourcePos":[6,1]}},"type":"App"},"type":"App"},"type":"App"},"type":"Abs"},"identifier":"inlineIntoMe"}],"exports":["inlineIntoMe","inlineIntoMe2"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[12,35],"start":[1,1]}},"moduleName":["Golden","Annotations","M1"]},{"annotation":{"meta":null,"sourceSpan":{"end":[12,35],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Golden","Annotations","M2"],"modulePath":"golden/Golden/Annotations/M2.purs","reExports":{},"sourceSpan":{"end":[12,35],"start":[1,1]}} -------------------------------------------------------------------------------- /test/ps/output/Golden.Annotations.M2/golden.ir: -------------------------------------------------------------------------------- 1 | UberModule 2 | { uberModuleBindings = 3 | [ Standalone 4 | ( QName 5 | { qnameModuleName = ModuleName "Golden.Annotations.M1", qnameName = Name "foreign" 6 | }, ForeignImport Nothing 7 | ( ModuleName "Golden.Annotations.M1" ) "golden/Golden/Annotations/M1.purs" 8 | [ ( Nothing, Name "dontInlineClosure" ), ( Just Always, Name "inlineMeLambda" ) ] 9 | ) 10 | ], uberModuleForeigns = [], uberModuleExports = 11 | [ 12 | ( Name "inlineIntoMe", Abs Nothing 13 | ( ParamNamed Nothing ( Name "i" ) ) 14 | ( IfThenElse Nothing 15 | ( Eq Nothing 16 | ( LiteralInt Nothing 1 ) 17 | ( IfThenElse Nothing 18 | ( Eq Nothing 19 | ( LiteralInt Nothing 1 ) 20 | ( IfThenElse Nothing 21 | ( Eq Nothing ( LiteralInt Nothing 1 ) ( Ref Nothing ( Local ( Name "i" ) ) 0 ) ) 22 | ( LiteralInt Nothing 2 ) 23 | ( Ref Nothing ( Local ( Name "i" ) ) 0 ) 24 | ) 25 | ) 26 | ( LiteralInt Nothing 2 ) 27 | ( IfThenElse Nothing 28 | ( Eq Nothing ( LiteralInt Nothing 1 ) ( Ref Nothing ( Local ( Name "i" ) ) 0 ) ) 29 | ( LiteralInt Nothing 2 ) 30 | ( Ref Nothing ( Local ( Name "i" ) ) 0 ) 31 | ) 32 | ) 33 | ) 34 | ( LiteralInt Nothing 2 ) 35 | ( IfThenElse Nothing 36 | ( Eq Nothing 37 | ( LiteralInt Nothing 1 ) 38 | ( IfThenElse Nothing 39 | ( Eq Nothing ( LiteralInt Nothing 1 ) ( Ref Nothing ( Local ( Name "i" ) ) 0 ) ) 40 | ( LiteralInt Nothing 2 ) 41 | ( Ref Nothing ( Local ( Name "i" ) ) 0 ) 42 | ) 43 | ) 44 | ( LiteralInt Nothing 2 ) 45 | ( IfThenElse Nothing 46 | ( Eq Nothing ( LiteralInt Nothing 1 ) ( Ref Nothing ( Local ( Name "i" ) ) 0 ) ) 47 | ( LiteralInt Nothing 2 ) 48 | ( Ref Nothing ( Local ( Name "i" ) ) 0 ) 49 | ) 50 | ) 51 | ) 52 | ), 53 | ( Name "inlineIntoMe2", App Nothing 54 | ( ObjectProp ( Just Always ) 55 | ( Ref Nothing ( Imported ( ModuleName "Golden.Annotations.M1" ) ( Name "foreign" ) ) 0 ) 56 | ( PropName "dontInlineClosure" ) 57 | ) 58 | ( App Nothing 59 | ( ObjectProp ( Just Always ) 60 | ( Ref Nothing 61 | ( Imported ( ModuleName "Golden.Annotations.M1" ) ( Name "foreign" ) ) 0 62 | ) 63 | ( PropName "inlineMeLambda" ) 64 | ) 65 | ( App Nothing 66 | ( ObjectProp ( Just Always ) 67 | ( Ref Nothing 68 | ( Imported ( ModuleName "Golden.Annotations.M1" ) ( Name "foreign" ) ) 0 69 | ) 70 | ( PropName "inlineMeLambda" ) 71 | ) 72 | ( LiteralInt Nothing 17 ) 73 | ) 74 | ) 75 | ) 76 | ] 77 | } -------------------------------------------------------------------------------- /test/ps/output/Golden.Annotations.M2/golden.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | M.Golden_Annotations_M1_foreign = (function() 3 | local step = 2 4 | return { 5 | dontInlineClosure = function(i) 6 | return i + step 7 | end, 8 | inlineMeLambda = function(i) 9 | return i + i 10 | end 11 | } 12 | end)() 13 | return { 14 | inlineIntoMe = function(i) 15 | if 1 == (function() 16 | if 1 == (function() if 1 == i then return 2 else return i end end)() then 17 | return 2 18 | else 19 | if 1 == i then return 2 else return i end 20 | end 21 | end)() then 22 | return 2 23 | else 24 | if 1 == (function() if 1 == i then return 2 else return i end end)() then 25 | return 2 26 | else 27 | if 1 == i then return 2 else return i end 28 | end 29 | end 30 | end, 31 | inlineIntoMe2 = M.Golden_Annotations_M1_foreign.dontInlineClosure(M.Golden_Annotations_M1_foreign.inlineMeLambda(M.Golden_Annotations_M1_foreign.inlineMeLambda(17))) 32 | } 33 | -------------------------------------------------------------------------------- /test/ps/output/Golden.ArrayOfUnits.Test/eval/.gitignore: -------------------------------------------------------------------------------- 1 | actual.txt 2 | -------------------------------------------------------------------------------- /test/ps/output/Golden.ArrayOfUnits.Test/eval/golden.txt: -------------------------------------------------------------------------------- 1 | unit 2 | unit 3 | unit 4 | 3 5 | -------------------------------------------------------------------------------- /test/ps/output/Golden.ArrayOfUnits.Test/golden.lua: -------------------------------------------------------------------------------- 1 | local function PSLUA_runtime_lazy(name) 2 | return function(init) 3 | return function() 4 | local state = 0 5 | local val = nil 6 | if state == 2 then 7 | return val 8 | else 9 | if state == 1 then 10 | return error(name .. " was needed before it finished initializing") 11 | else 12 | state = 1 13 | val = init() 14 | state = 2 15 | return val 16 | end 17 | end 18 | end 19 | end 20 | end 21 | local M = {} 22 | M.Data_Unit_foreign = { unit = {} } 23 | M.Data_Semiring_foreign = { 24 | intAdd = function(x) return function(y) return x + y end end, 25 | intMul = function(x) return function(y) return x * y end end 26 | } 27 | M.Data_Foldable_foreign = { 28 | foldrArray = function(f) 29 | return function(init) 30 | return function(xs) 31 | local acc = init 32 | local len = #xs 33 | for i = len, 1, -1 do acc = f(xs[i])(acc) end 34 | return acc 35 | end 36 | end 37 | end, 38 | foldlArray = function(f) 39 | return function(init) 40 | return function(xs) 41 | local acc = init 42 | local len = #xs 43 | for i = 1, len do acc = f(acc)(xs[i]) end 44 | return acc 45 | end 46 | end 47 | end 48 | } 49 | M.Effect_foreign = { 50 | pureE = function(a) 51 | return function() 52 | return a 53 | end 54 | end, 55 | bindE = function(a) 56 | return function(f) 57 | return function() 58 | return f(a())() 59 | end 60 | end 61 | end 62 | } 63 | M.Control_Semigroupoid_semigroupoidFn = { 64 | compose = function(f) 65 | return function(g) return function(x) return f(g(x)) end end 66 | end 67 | } 68 | M.Data_Semiring_semiringInt = { 69 | add = M.Data_Semiring_foreign.intAdd, 70 | zero = 0, 71 | mul = M.Data_Semiring_foreign.intMul, 72 | one = 1 73 | } 74 | M.Control_Apply_apply = function(dict) return dict.apply end 75 | M.Control_Applicative_pure = function(dict) return dict.pure end 76 | M.Control_Bind_bind = function(dict) return dict.bind end 77 | M.Data_Foldable_foldr = function(dict) return dict.foldr end 78 | M.Data_Foldable_foldableArray = { 79 | foldr = M.Data_Foldable_foreign.foldrArray, 80 | foldl = M.Data_Foldable_foreign.foldlArray, 81 | foldMap = function(dictMonoid) 82 | return function(f) 83 | return M.Data_Foldable_foldr(M.Data_Foldable_foldableArray)(function(x) 84 | return (dictMonoid.Semigroup0()).append(f(x)) 85 | end)(dictMonoid.mempty) 86 | end 87 | end 88 | } 89 | M.Effect_monadEffect = { 90 | Applicative0 = function() return M.Effect_applicativeEffect end, 91 | Bind1 = function() return M.Effect_bindEffect end 92 | } 93 | M.Effect_bindEffect = { 94 | bind = M.Effect_foreign.bindE, 95 | Apply0 = function() return M.Effect_Lazy_applyEffect(0) end 96 | } 97 | M.Effect_applicativeEffect = { 98 | pure = M.Effect_foreign.pureE, 99 | Apply0 = function() return M.Effect_Lazy_applyEffect(0) end 100 | } 101 | M.Effect_Lazy_functorEffect = PSLUA_runtime_lazy("functorEffect")(function() 102 | return { 103 | map = function(f) 104 | return M.Control_Apply_apply(M.Effect_applicativeEffect.Apply0())(M.Control_Applicative_pure(M.Effect_applicativeEffect)(f)) 105 | end 106 | } 107 | end) 108 | M.Effect_Lazy_applyEffect = PSLUA_runtime_lazy("applyEffect")(function() 109 | return { 110 | apply = (function() 111 | return function(f) 112 | local bind = M.Control_Bind_bind(M.Effect_monadEffect.Bind1()) 113 | return function(a) 114 | return bind(f)(function(fPrime) 115 | return bind(a)(function(aPrime) 116 | return M.Control_Applicative_pure(M.Effect_monadEffect.Applicative0())(fPrime(aPrime)) 117 | end) 118 | end) 119 | end 120 | end 121 | end)(), 122 | Functor0 = function() return M.Effect_Lazy_functorEffect(0) end 123 | } 124 | end) 125 | M.Effect_Console_logShow = function(dictShow) 126 | return function(a) 127 | return (function(s) return function() print(s) end end)(dictShow.show(a)) 128 | end 129 | end 130 | return (function() 131 | local arr = { 132 | [1] = M.Data_Unit_foreign.unit, 133 | [2] = M.Data_Unit_foreign.unit, 134 | [3] = M.Data_Unit_foreign.unit 135 | } 136 | return M.Control_Bind_bind(M.Effect_bindEffect)(M.Data_Foldable_foldr(M.Data_Foldable_foldableArray)(M.Control_Semigroupoid_semigroupoidFn.compose(function( a ) 137 | return M.Control_Apply_apply(M.Effect_applicativeEffect.Apply0())(((M.Effect_applicativeEffect.Apply0()).Functor0()).map(function( ) 138 | return function(x) return x end 139 | end)(a)) 140 | end)(M.Effect_Console_logShow({ 141 | show = function() return "unit" end 142 | })))(M.Control_Applicative_pure(M.Effect_applicativeEffect)(M.Data_Unit_foreign.unit))(arr))(function( ) 143 | return M.Effect_Console_logShow({ 144 | show = function(n) return tostring(n) end 145 | })(M.Data_Foldable_foldableArray.foldl(function(c) 146 | return function() 147 | return M.Data_Semiring_semiringInt.add(M.Data_Semiring_semiringInt.one)(c) 148 | end 149 | end)(M.Data_Semiring_semiringInt.zero)(arr)) 150 | end) 151 | end)()() 152 | -------------------------------------------------------------------------------- /test/ps/output/Golden.Beta.Test/corefn.json: -------------------------------------------------------------------------------- 1 | {"builtWith":"0.15.15","comments":[],"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,16],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[3,16],"start":[3,1]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[3,16],"start":[3,1]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[4,5],"start":[4,3]}},"binderType":"LiteralBinder","literal":{"literalType":"IntLiteral","value":42}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[4,10],"start":[4,8]}},"type":"Literal","value":{"literalType":"IntLiteral","value":42}},"isGuarded":false},{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[5,4],"start":[5,3]}},"binderType":"NullBinder"}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[5,8],"start":[5,7]}},"type":"Literal","value":{"literalType":"IntLiteral","value":1}},"isGuarded":false}],"caseExpressions":[{"annotation":{"meta":null,"sourceSpan":{"end":[4,10],"start":[4,1]}},"type":"Var","value":{"identifier":"v","sourcePos":[0,0]}}],"type":"Case"},"type":"Abs"},"identifier":"f"},{"annotation":{"meta":null,"sourceSpan":{"end":[7,16],"start":[7,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[7,16],"start":[7,1]}},"argument":"x","body":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[8,8],"start":[8,7]}},"type":"Var","value":{"identifier":"f","moduleName":["Golden","Beta","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[8,10],"start":[8,7]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[8,10],"start":[8,9]}},"type":"Var","value":{"identifier":"x","sourcePos":[8,1]}},"type":"App"},"type":"Abs"},"identifier":"g"}],"exports":["g"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[8,10],"start":[1,1]}},"moduleName":["Golden","Beta","Test"]},{"annotation":{"meta":null,"sourceSpan":{"end":[8,10],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Golden","Beta","Test"],"modulePath":"golden/Golden/Beta/Test.purs","reExports":{},"sourceSpan":{"end":[8,10],"start":[1,1]}} -------------------------------------------------------------------------------- /test/ps/output/Golden.Beta.Test/golden.ir: -------------------------------------------------------------------------------- 1 | UberModule 2 | { uberModuleBindings = [], uberModuleForeigns = [], uberModuleExports = 3 | [ 4 | ( Name "g", Abs Nothing 5 | ( ParamNamed Nothing ( Name "v" ) ) 6 | ( IfThenElse Nothing 7 | ( Eq Nothing ( LiteralInt Nothing 42 ) ( Ref Nothing ( Local ( Name "v" ) ) 0 ) ) 8 | ( LiteralInt Nothing 42 ) 9 | ( LiteralInt Nothing 1 ) 10 | ) 11 | ) 12 | ] 13 | } -------------------------------------------------------------------------------- /test/ps/output/Golden.Beta.Test/golden.lua: -------------------------------------------------------------------------------- 1 | return { g = function(v) if 42 == v then return 42 else return 1 end end } 2 | -------------------------------------------------------------------------------- /test/ps/output/Golden.Bug1.Test/corefn.json: -------------------------------------------------------------------------------- 1 | {"builtWith":"0.15.15","comments":[],"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,12],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[6,29],"start":[5,3]}},"binds":[{"annotation":{"meta":null,"sourceSpan":{"end":[5,30],"start":[5,7]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[5,30],"start":[5,7]}},"argument":"r","body":{"annotation":{"meta":null,"sourceSpan":{"end":[5,30],"start":[5,14]}},"type":"Literal","value":{"literalType":"ObjectLiteral","value":[["elem",{"annotation":{"meta":null,"sourceSpan":{"end":[5,28],"start":[5,22]}},"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[5,23],"start":[5,22]}},"type":"Var","value":{"identifier":"r","sourcePos":[5,7]}},"fieldName":"elem","type":"Accessor"}]]}},"type":"Abs"},"identifier":"go"}],"expression":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[6,12],"start":[6,6]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[6,12],"start":[6,6]}},"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"v","sourcePos":[0,0]}},"fieldName":"elem","type":"Accessor"},"type":"Abs"},"annotation":{"meta":null,"sourceSpan":{"end":[6,29],"start":[6,6]}},"argument":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[6,16],"start":[6,14]}},"type":"Var","value":{"identifier":"go","sourcePos":[5,7]}},"annotation":{"meta":null,"sourceSpan":{"end":[6,28],"start":[6,14]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[6,28],"start":[6,17]}},"type":"Literal","value":{"literalType":"ObjectLiteral","value":[["elem",{"annotation":{"meta":null,"sourceSpan":{"end":[6,26],"start":[6,25]}},"type":"Literal","value":{"literalType":"IntLiteral","value":1}}]]}},"type":"App"},"type":"App"},"type":"Let"},"identifier":"test"}],"exports":["test"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[6,29],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Golden","Bug1","Test"],"modulePath":"golden/Golden/Bug1/Test.purs","reExports":{},"sourceSpan":{"end":[6,29],"start":[1,1]}} -------------------------------------------------------------------------------- /test/ps/output/Golden.Bug1.Test/golden.ir: -------------------------------------------------------------------------------- 1 | UberModule 2 | { uberModuleBindings = [], uberModuleForeigns = [], uberModuleExports = 3 | [ 4 | ( Name "test", ObjectProp Nothing 5 | ( LiteralObject Nothing 6 | [ 7 | ( PropName "elem", ObjectProp Nothing 8 | ( LiteralObject Nothing [ ( PropName "elem", LiteralInt Nothing 1 ) ] ) 9 | ( PropName "elem" ) 10 | ) 11 | ] 12 | ) 13 | ( PropName "elem" ) 14 | ) 15 | ] 16 | } -------------------------------------------------------------------------------- /test/ps/output/Golden.Bug1.Test/golden.lua: -------------------------------------------------------------------------------- 1 | return { test = 1 } 2 | -------------------------------------------------------------------------------- /test/ps/output/Golden.CaseStatements.Test/golden.ir: -------------------------------------------------------------------------------- 1 | UberModule 2 | { uberModuleBindings = 3 | [ Standalone 4 | ( QName 5 | { qnameModuleName = ModuleName "Golden.Values.Test", qnameName = Name "f" 6 | }, Abs Nothing ( ParamUnused Nothing ) ( LiteralBool Nothing True ) 7 | ) 8 | ], uberModuleForeigns = [], uberModuleExports = 9 | [ 10 | ( Name "a", LiteralInt Nothing 1 ), 11 | ( Name "b", LiteralChar Nothing 'b' ), 12 | ( Name "c", Let Nothing 13 | ( Standalone 14 | ( Nothing, Name "v", Abs Nothing ( ParamUnused Nothing ) ( LiteralInt Nothing 0 ) ) :| [] 15 | ) 16 | ( IfThenElse Nothing 17 | ( App Nothing 18 | ( Ref Nothing ( Imported ( ModuleName "Golden.Values.Test" ) ( Name "f" ) ) 0 ) 19 | ( LiteralInt Nothing 2 ) 20 | ) 21 | ( IfThenElse Nothing 22 | ( App Nothing 23 | ( Ref Nothing ( Imported ( ModuleName "Golden.Values.Test" ) ( Name "f" ) ) 0 ) 24 | ( LiteralInt Nothing 1 ) 25 | ) 26 | ( LiteralInt Nothing 42 ) 27 | ( App Nothing ( Ref Nothing ( Local ( Name "v" ) ) 0 ) ( LiteralBool Nothing True ) ) 28 | ) 29 | ( App Nothing ( Ref Nothing ( Local ( Name "v" ) ) 0 ) ( LiteralBool Nothing True ) ) 30 | ) 31 | ), 32 | ( Name "J", Ctor Nothing SumType 33 | ( ModuleName "Golden.CaseStatements.Test" ) 34 | ( TyName "M" ) 35 | ( CtorName "J" ) 36 | [ FieldName "value0" ] 37 | ), 38 | ( Name "N", Ctor Nothing SumType 39 | ( ModuleName "Golden.CaseStatements.Test" ) 40 | ( TyName "M" ) 41 | ( CtorName "N" ) [] 42 | ), 43 | ( Name "d", Abs Nothing 44 | ( ParamNamed Nothing ( Name "m" ) ) 45 | ( Abs Nothing 46 | ( ParamNamed Nothing ( Name "n" ) ) 47 | ( Abs Nothing 48 | ( ParamNamed Nothing ( Name "x" ) ) 49 | ( Let Nothing 50 | ( Standalone 51 | ( Nothing, Name "v", Abs Nothing ( ParamUnused Nothing ) 52 | ( IfThenElse Nothing 53 | ( Eq Nothing 54 | ( LiteralChar Nothing 'y' ) 55 | ( Ref Nothing ( Local ( Name "x" ) ) 0 ) 56 | ) 57 | ( LiteralInt Nothing 0 ) 58 | ( LiteralInt Nothing 1 ) 59 | ) 60 | ) :| [] 61 | ) 62 | ( IfThenElse Nothing 63 | ( Eq Nothing ( LiteralChar Nothing 'x' ) ( Ref Nothing ( Local ( Name "x" ) ) 0 ) ) 64 | ( IfThenElse Nothing 65 | ( Eq Nothing 66 | ( LiteralString Nothing "Golden.CaseStatements.Test∷M.J" ) 67 | ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "m" ) ) 0 ) ) 68 | ) 69 | ( IfThenElse Nothing 70 | ( Eq Nothing 71 | ( LiteralString Nothing "Golden.CaseStatements.Test∷M.N" ) 72 | ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "n" ) ) 0 ) ) 73 | ) 74 | ( ObjectProp Nothing 75 | ( Ref Nothing ( Local ( Name "m" ) ) 0 ) 76 | ( PropName "value0" ) 77 | ) 78 | ( App Nothing 79 | ( Ref Nothing ( Local ( Name "v" ) ) 0 ) ( LiteralBool Nothing True ) 80 | ) 81 | ) 82 | ( App Nothing 83 | ( Ref Nothing ( Local ( Name "v" ) ) 0 ) ( LiteralBool Nothing True ) 84 | ) 85 | ) 86 | ( App Nothing 87 | ( Ref Nothing ( Local ( Name "v" ) ) 0 ) ( LiteralBool Nothing True ) 88 | ) 89 | ) 90 | ) 91 | ) 92 | ) 93 | ), 94 | ( Name "multipleGuards", LiteralInt Nothing 1 ) 95 | ] 96 | } -------------------------------------------------------------------------------- /test/ps/output/Golden.CaseStatements.Test/golden.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | M.Golden_Values_Test_f = function() return true end 3 | return { 4 | a = 1, 5 | b = "b", 6 | c = (function() 7 | local v = function() return 0 end 8 | if M.Golden_Values_Test_f(2) then 9 | if M.Golden_Values_Test_f(1) then return 42 else return v(true) end 10 | else 11 | return v(true) 12 | end 13 | end)(), 14 | J = function(value0) 15 | return { ["$ctor"] = "Golden.CaseStatements.Test∷M.J", value0 = value0 } 16 | end, 17 | N = { ["$ctor"] = "Golden.CaseStatements.Test∷M.N" }, 18 | d = function(m) 19 | return function(n) 20 | return function(x) 21 | local v = function() if "y" == x then return 0 else return 1 end end 22 | if "x" == x then 23 | if "Golden.CaseStatements.Test∷M.J" == m["$ctor"] then 24 | if "Golden.CaseStatements.Test∷M.N" == n["$ctor"] then 25 | return m.value0 26 | else 27 | return v(true) 28 | end 29 | else 30 | return v(true) 31 | end 32 | else 33 | return v(true) 34 | end 35 | end 36 | end 37 | end, 38 | multipleGuards = 1 39 | } 40 | -------------------------------------------------------------------------------- /test/ps/output/Golden.Currying.Test/corefn.json: -------------------------------------------------------------------------------- 1 | {"builtWith":"0.15.15","comments":[],"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[6,48],"start":[6,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[6,48],"start":[6,1]}},"argument":"i","body":{"annotation":{"meta":null,"sourceSpan":{"end":[6,48],"start":[6,1]}},"argument":"b","body":{"annotation":{"meta":null,"sourceSpan":{"end":[6,48],"start":[6,1]}},"argument":"c","body":{"annotation":{"meta":null,"sourceSpan":{"end":[6,48],"start":[6,1]}},"argument":"d","body":{"annotation":{"meta":null,"sourceSpan":{"end":[7,17],"start":[7,13]}},"type":"Literal","value":{"literalType":"StringLiteral","value":"ok"}},"type":"Abs"},"type":"Abs"},"type":"Abs"},"type":"Abs"},"identifier":"f"},{"annotation":{"meta":null,"sourceSpan":{"end":[3,40],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[3,40],"start":[3,1]}},"argument":"f1","body":{"annotation":{"meta":null,"sourceSpan":{"end":[3,40],"start":[3,1]}},"argument":"x","body":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[4,14],"start":[4,13]}},"type":"Var","value":{"identifier":"f1","sourcePos":[4,1]}},"annotation":{"meta":null,"sourceSpan":{"end":[4,16],"start":[4,13]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[4,16],"start":[4,15]}},"type":"Var","value":{"identifier":"x","sourcePos":[4,1]}},"type":"App"},"type":"Abs"},"type":"Abs"},"identifier":"apply"}],"exports":["apply","f"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[7,17],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Golden","Currying","Test"],"modulePath":"golden/Golden/Currying/Test.purs","reExports":{},"sourceSpan":{"end":[7,17],"start":[1,1]}} -------------------------------------------------------------------------------- /test/ps/output/Golden.Currying.Test/golden.ir: -------------------------------------------------------------------------------- 1 | UberModule 2 | { uberModuleBindings = [], uberModuleForeigns = [], uberModuleExports = 3 | [ 4 | ( Name "apply", Abs Nothing 5 | ( ParamNamed Nothing ( Name "f1" ) ) 6 | ( Ref Nothing ( Local ( Name "f1" ) ) 0 ) 7 | ), 8 | ( Name "f", Abs Nothing ( ParamUnused Nothing ) 9 | ( Abs Nothing ( ParamUnused Nothing ) 10 | ( Abs Nothing ( ParamUnused Nothing ) 11 | ( Abs Nothing ( ParamUnused Nothing ) ( LiteralString Nothing "ok" ) ) 12 | ) 13 | ) 14 | ) 15 | ] 16 | } -------------------------------------------------------------------------------- /test/ps/output/Golden.Currying.Test/golden.lua: -------------------------------------------------------------------------------- 1 | return { 2 | apply = function(f1) return f1 end, 3 | f = function() 4 | return function() 5 | return function() return function() return "ok" end end 6 | end 7 | end 8 | } 9 | -------------------------------------------------------------------------------- /test/ps/output/Golden.DataDeclarations.Test1/corefn.json: -------------------------------------------------------------------------------- 1 | {"builtWith":"0.15.15","comments":[],"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[4,14],"start":[4,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[4,14],"start":[4,1]}},"constructorName":"U","fieldNames":[],"type":"Constructor","typeName":"Unit"},"identifier":"U"},{"annotation":{"meta":null,"sourceSpan":{"end":[9,31],"start":[9,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[9,31],"start":[9,1]}},"constructorName":"CtorSameName","fieldNames":[],"type":"Constructor","typeName":"TySameName"},"identifier":"CtorSameName"},{"annotation":{"meta":null,"sourceSpan":{"end":[7,42],"start":[7,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[7,42],"start":[7,1]}},"constructorName":"S0","fieldNames":[],"type":"Constructor","typeName":"TSum"},"identifier":"S0"},{"annotation":{"meta":null,"sourceSpan":{"end":[7,42],"start":[7,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[7,42],"start":[7,1]}},"constructorName":"S1","fieldNames":["value0"],"type":"Constructor","typeName":"TSum"},"identifier":"S1"},{"annotation":{"meta":null,"sourceSpan":{"end":[7,42],"start":[7,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[7,42],"start":[7,1]}},"constructorName":"S2","fieldNames":["value0","value1"],"type":"Constructor","typeName":"TSum"},"identifier":"S2"},{"annotation":{"meta":null,"sourceSpan":{"end":[6,72],"start":[6,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[6,72],"start":[6,1]}},"constructorName":"PF","fieldNames":["value0"],"type":"Constructor","typeName":"TProductWithFields"},"identifier":"PF"},{"annotation":{"meta":null,"sourceSpan":{"end":[5,38],"start":[5,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[5,38],"start":[5,1]}},"constructorName":"P3","fieldNames":["value0","value1","value2"],"type":"Constructor","typeName":"TProduct"},"identifier":"P3"},{"annotation":{"meta":null,"sourceSpan":{"end":[8,26],"start":[8,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[8,26],"start":[8,1]}},"constructorName":"Nop","fieldNames":[],"type":"Constructor","typeName":"Rec"},"identifier":"Nop"},{"annotation":{"meta":null,"sourceSpan":{"end":[8,26],"start":[8,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[8,26],"start":[8,1]}},"constructorName":"More","fieldNames":["value0"],"type":"Constructor","typeName":"Rec"},"identifier":"More"}],"exports":["U","P3","PF","S0","S1","S2","Nop","More","CtorSameName"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[9,31],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Golden","DataDeclarations","Test1"],"modulePath":"golden/Golden/DataDeclarations/Test1.purs","reExports":{},"sourceSpan":{"end":[9,31],"start":[1,1]}} -------------------------------------------------------------------------------- /test/ps/output/Golden.DataDeclarations.Test1/golden.ir: -------------------------------------------------------------------------------- 1 | UberModule 2 | { uberModuleBindings = [], uberModuleForeigns = [], uberModuleExports = 3 | [ 4 | ( Name "U", Ctor Nothing ProductType 5 | ( ModuleName "Golden.DataDeclarations.Test1" ) 6 | ( TyName "Unit" ) 7 | ( CtorName "U" ) [] 8 | ), 9 | ( Name "P3", Ctor Nothing ProductType 10 | ( ModuleName "Golden.DataDeclarations.Test1" ) 11 | ( TyName "TProduct" ) 12 | ( CtorName "P3" ) 13 | [ FieldName "value0", FieldName "value1", FieldName "value2" ] 14 | ), 15 | ( Name "PF", Ctor Nothing ProductType 16 | ( ModuleName "Golden.DataDeclarations.Test1" ) 17 | ( TyName "TProductWithFields" ) 18 | ( CtorName "PF" ) 19 | [ FieldName "value0" ] 20 | ), 21 | ( Name "S0", Ctor Nothing SumType 22 | ( ModuleName "Golden.DataDeclarations.Test1" ) 23 | ( TyName "TSum" ) 24 | ( CtorName "S0" ) [] 25 | ), 26 | ( Name "S1", Ctor Nothing SumType 27 | ( ModuleName "Golden.DataDeclarations.Test1" ) 28 | ( TyName "TSum" ) 29 | ( CtorName "S1" ) 30 | [ FieldName "value0" ] 31 | ), 32 | ( Name "S2", Ctor Nothing SumType 33 | ( ModuleName "Golden.DataDeclarations.Test1" ) 34 | ( TyName "TSum" ) 35 | ( CtorName "S2" ) 36 | [ FieldName "value0", FieldName "value1" ] 37 | ), 38 | ( Name "Nop", Ctor Nothing SumType 39 | ( ModuleName "Golden.DataDeclarations.Test1" ) 40 | ( TyName "Rec" ) 41 | ( CtorName "Nop" ) [] 42 | ), 43 | ( Name "More", Ctor Nothing SumType 44 | ( ModuleName "Golden.DataDeclarations.Test1" ) 45 | ( TyName "Rec" ) 46 | ( CtorName "More" ) 47 | [ FieldName "value0" ] 48 | ), 49 | ( Name "CtorSameName", Ctor Nothing ProductType 50 | ( ModuleName "Golden.DataDeclarations.Test1" ) 51 | ( TyName "TySameName" ) 52 | ( CtorName "CtorSameName" ) [] 53 | ) 54 | ] 55 | } -------------------------------------------------------------------------------- /test/ps/output/Golden.DataDeclarations.Test1/golden.lua: -------------------------------------------------------------------------------- 1 | return { 2 | U = { ["$ctor"] = "Golden.DataDeclarations.Test1∷Unit.U" }, 3 | P3 = function(value0) 4 | return function(value1) 5 | return function(value2) 6 | return { 7 | ["$ctor"] = "Golden.DataDeclarations.Test1∷TProduct.P3", 8 | value0 = value0, 9 | value1 = value1, 10 | value2 = value2 11 | } 12 | end 13 | end 14 | end, 15 | PF = function(value0) 16 | return { 17 | ["$ctor"] = "Golden.DataDeclarations.Test1∷TProductWithFields.PF", 18 | value0 = value0 19 | } 20 | end, 21 | S0 = { ["$ctor"] = "Golden.DataDeclarations.Test1∷TSum.S0" }, 22 | S1 = function(value0) 23 | return { 24 | ["$ctor"] = "Golden.DataDeclarations.Test1∷TSum.S1", 25 | value0 = value0 26 | } 27 | end, 28 | S2 = function(value0) 29 | return function(value1) 30 | return { 31 | ["$ctor"] = "Golden.DataDeclarations.Test1∷TSum.S2", 32 | value0 = value0, 33 | value1 = value1 34 | } 35 | end 36 | end, 37 | Nop = { ["$ctor"] = "Golden.DataDeclarations.Test1∷Rec.Nop" }, 38 | More = function(value0) 39 | return { 40 | ["$ctor"] = "Golden.DataDeclarations.Test1∷Rec.More", 41 | value0 = value0 42 | } 43 | end, 44 | CtorSameName = { 45 | ["$ctor"] = "Golden.DataDeclarations.Test1∷TySameName.CtorSameName" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /test/ps/output/Golden.DataDeclarations.Test2/corefn.json: -------------------------------------------------------------------------------- 1 | {"builtWith":"0.15.15","comments":[],"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[5,31],"start":[5,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[5,31],"start":[5,1]}},"constructorName":"CtorSameName","fieldNames":[],"type":"Constructor","typeName":"TySameName"},"identifier":"CtorSameName"},{"annotation":{"meta":null,"sourceSpan":{"end":[7,49],"start":[7,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[7,49],"start":[7,1]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[7,49],"start":[7,1]}},"argument":"v1","body":{"annotation":{"meta":null,"sourceSpan":{"end":[7,49],"start":[7,1]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":{"constructorType":"ProductType","identifiers":[],"metaType":"IsConstructor"},"sourceSpan":{"end":[8,23],"start":[8,6]}},"binderType":"ConstructorBinder","binders":[],"constructorName":{"identifier":"CtorSameName","moduleName":["Golden","DataDeclarations","Test1"]},"typeName":{"identifier":"TySameName","moduleName":["Golden","DataDeclarations","Test1"]}},{"annotation":{"meta":{"constructorType":"ProductType","identifiers":[],"metaType":"IsConstructor"},"sourceSpan":{"end":[8,36],"start":[8,24]}},"binderType":"ConstructorBinder","binders":[],"constructorName":{"identifier":"CtorSameName","moduleName":["Golden","DataDeclarations","Test2"]},"typeName":{"identifier":"TySameName","moduleName":["Golden","DataDeclarations","Test2"]}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[8,43],"start":[8,39]}},"type":"Literal","value":{"literalType":"BooleanLiteral","value":true}},"isGuarded":false}],"caseExpressions":[{"annotation":{"meta":null,"sourceSpan":{"end":[8,43],"start":[8,1]}},"type":"Var","value":{"identifier":"v","sourcePos":[0,0]}},{"annotation":{"meta":null,"sourceSpan":{"end":[8,43],"start":[8,1]}},"type":"Var","value":{"identifier":"v1","sourcePos":[0,0]}}],"type":"Case"},"type":"Abs"},"type":"Abs"},"identifier":"test"}],"exports":["CtorSameName","test"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[8,43],"start":[1,1]}},"moduleName":["Golden","DataDeclarations","Test1"]},{"annotation":{"meta":null,"sourceSpan":{"end":[8,43],"start":[1,1]}},"moduleName":["Golden","DataDeclarations","Test2"]},{"annotation":{"meta":null,"sourceSpan":{"end":[8,43],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Golden","DataDeclarations","Test2"],"modulePath":"golden/Golden/DataDeclarations/Test2.purs","reExports":{},"sourceSpan":{"end":[8,43],"start":[1,1]}} -------------------------------------------------------------------------------- /test/ps/output/Golden.DataDeclarations.Test2/golden.ir: -------------------------------------------------------------------------------- 1 | UberModule 2 | { uberModuleBindings = [], uberModuleForeigns = [], uberModuleExports = 3 | [ 4 | ( Name "CtorSameName", Ctor Nothing ProductType 5 | ( ModuleName "Golden.DataDeclarations.Test2" ) 6 | ( TyName "TySameName" ) 7 | ( CtorName "CtorSameName" ) [] 8 | ), 9 | ( Name "test", Abs Nothing ( ParamUnused Nothing ) 10 | ( Abs Nothing ( ParamUnused Nothing ) ( LiteralBool Nothing True ) ) 11 | ) 12 | ] 13 | } -------------------------------------------------------------------------------- /test/ps/output/Golden.DataDeclarations.Test2/golden.lua: -------------------------------------------------------------------------------- 1 | return { 2 | CtorSameName = { 3 | ["$ctor"] = "Golden.DataDeclarations.Test2∷TySameName.CtorSameName" 4 | }, 5 | test = function() return function() return true end end 6 | } 7 | -------------------------------------------------------------------------------- /test/ps/output/Golden.Fibonacci.Test/eval/.gitignore: -------------------------------------------------------------------------------- 1 | actual.txt 2 | -------------------------------------------------------------------------------- /test/ps/output/Golden.Fibonacci.Test/eval/golden.txt: -------------------------------------------------------------------------------- 1 | 2178309 2 | -------------------------------------------------------------------------------- /test/ps/output/Golden.Fibonacci.Test/golden.ir: -------------------------------------------------------------------------------- 1 | UberModule 2 | { uberModuleBindings = 3 | [ Standalone 4 | ( QName 5 | { qnameModuleName = ModuleName "Data.Semiring", qnameName = Name "foreign" 6 | }, ForeignImport Nothing 7 | ( ModuleName "Data.Semiring" ) ".spago/prelude/v7.2.0/src/Data/Semiring.purs" 8 | [ ( Nothing, Name "intAdd" ), ( Nothing, Name "intMul" ) ] 9 | ), Standalone 10 | ( QName 11 | { qnameModuleName = ModuleName "Data.Semiring", qnameName = Name "semiringInt" 12 | }, LiteralObject Nothing 13 | [ 14 | ( PropName "add", ObjectProp ( Just Always ) 15 | ( Ref Nothing ( Imported ( ModuleName "Data.Semiring" ) ( Name "foreign" ) ) 0 ) 16 | ( PropName "intAdd" ) 17 | ), 18 | ( PropName "zero", LiteralInt Nothing 0 ), 19 | ( PropName "mul", ObjectProp ( Just Always ) 20 | ( Ref Nothing ( Imported ( ModuleName "Data.Semiring" ) ( Name "foreign" ) ) 0 ) 21 | ( PropName "intMul" ) 22 | ), 23 | ( PropName "one", LiteralInt Nothing 1 ) 24 | ] 25 | ), Standalone 26 | ( QName 27 | { qnameModuleName = ModuleName "Golden.Fibonacci.Test", qnameName = Name "sub" 28 | }, ObjectProp Nothing 29 | ( LiteralObject Nothing 30 | [ 31 | ( PropName "sub", ObjectProp ( Just Always ) 32 | ( ForeignImport Nothing 33 | ( ModuleName "Data.Ring" ) ".spago/prelude/v7.2.0/src/Data/Ring.purs" 34 | [ ( Nothing, Name "intSub" ) ] 35 | ) 36 | ( PropName "intSub" ) 37 | ), 38 | ( PropName "Semiring0", Abs Nothing ( ParamUnused Nothing ) 39 | ( Ref Nothing ( Imported ( ModuleName "Data.Semiring" ) ( Name "semiringInt" ) ) 0 ) 40 | ) 41 | ] 42 | ) 43 | ( PropName "sub" ) 44 | ), RecursiveGroup 45 | ( 46 | ( QName 47 | { qnameModuleName = ModuleName "Golden.Fibonacci.Test", qnameName = Name "fib" 48 | }, Abs Nothing 49 | ( ParamNamed Nothing ( Name "v" ) ) 50 | ( IfThenElse Nothing 51 | ( Eq Nothing ( LiteralInt Nothing 0 ) ( Ref Nothing ( Local ( Name "v" ) ) 0 ) ) 52 | ( LiteralInt Nothing 0 ) 53 | ( IfThenElse Nothing 54 | ( Eq Nothing ( LiteralInt Nothing 1 ) ( Ref Nothing ( Local ( Name "v" ) ) 0 ) ) 55 | ( LiteralInt Nothing 1 ) 56 | ( App Nothing 57 | ( App Nothing 58 | ( ObjectProp Nothing 59 | ( Ref Nothing 60 | ( Imported ( ModuleName "Data.Semiring" ) ( Name "semiringInt" ) ) 0 61 | ) 62 | ( PropName "add" ) 63 | ) 64 | ( App Nothing 65 | ( Ref Nothing 66 | ( Imported ( ModuleName "Golden.Fibonacci.Test" ) ( Name "fib" ) ) 0 67 | ) 68 | ( App Nothing 69 | ( App Nothing 70 | ( Ref Nothing 71 | ( Imported ( ModuleName "Golden.Fibonacci.Test" ) ( Name "sub" ) ) 0 72 | ) 73 | ( Ref Nothing ( Local ( Name "v" ) ) 0 ) 74 | ) 75 | ( LiteralInt Nothing 1 ) 76 | ) 77 | ) 78 | ) 79 | ( App Nothing 80 | ( Ref Nothing 81 | ( Imported ( ModuleName "Golden.Fibonacci.Test" ) ( Name "fib" ) ) 0 82 | ) 83 | ( App Nothing 84 | ( App Nothing 85 | ( Ref Nothing 86 | ( Imported ( ModuleName "Golden.Fibonacci.Test" ) ( Name "sub" ) ) 0 87 | ) 88 | ( Ref Nothing ( Local ( Name "v" ) ) 0 ) 89 | ) 90 | ( LiteralInt Nothing 2 ) 91 | ) 92 | ) 93 | ) 94 | ) 95 | ) 96 | ) :| [] 97 | ) 98 | ], uberModuleForeigns = [], uberModuleExports = 99 | [ 100 | ( Name "fib", Ref Nothing 101 | ( Imported ( ModuleName "Golden.Fibonacci.Test" ) ( Name "fib" ) ) 0 102 | ), 103 | ( Name "main", App Nothing 104 | ( ObjectProp ( Just Always ) 105 | ( ForeignImport Nothing 106 | ( ModuleName "Effect.Console" ) ".spago/console/v6.1.0/src/Effect/Console.purs" 107 | [ ( Nothing, Name "log" ) ] 108 | ) 109 | ( PropName "log" ) 110 | ) 111 | ( App Nothing 112 | ( ObjectProp Nothing 113 | ( LiteralObject Nothing 114 | [ 115 | ( PropName "show", ObjectProp ( Just Always ) 116 | ( ForeignImport Nothing 117 | ( ModuleName "Data.Show" ) ".spago/prelude/v7.2.0/src/Data/Show.purs" 118 | [ ( Nothing, Name "showIntImpl" ) ] 119 | ) 120 | ( PropName "showIntImpl" ) 121 | ) 122 | ] 123 | ) 124 | ( PropName "show" ) 125 | ) 126 | ( App Nothing 127 | ( Ref Nothing ( Imported ( ModuleName "Golden.Fibonacci.Test" ) ( Name "fib" ) ) 0 ) 128 | ( LiteralInt Nothing 32 ) 129 | ) 130 | ) 131 | ) 132 | ] 133 | } -------------------------------------------------------------------------------- /test/ps/output/Golden.Fibonacci.Test/golden.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | M.Data_Semiring_foreign = { 3 | intAdd = function(x) return function(y) return x + y end end, 4 | intMul = function(x) return function(y) return x * y end end 5 | } 6 | M.Data_Semiring_semiringInt = { 7 | add = M.Data_Semiring_foreign.intAdd, 8 | zero = 0, 9 | mul = M.Data_Semiring_foreign.intMul, 10 | one = 1 11 | } 12 | M.Golden_Fibonacci_Test_sub = function(x) return function(y) return x - y end end 13 | M.Golden_Fibonacci_Test_fib = function(v) 14 | if 0 == v then 15 | return 0 16 | else 17 | if 1 == v then 18 | return 1 19 | else 20 | return M.Data_Semiring_semiringInt.add(M.Golden_Fibonacci_Test_fib(M.Golden_Fibonacci_Test_sub(v)(1)))(M.Golden_Fibonacci_Test_fib(M.Golden_Fibonacci_Test_sub(v)(2))) 21 | end 22 | end 23 | end 24 | return (function(s) return function() print(s) end end)((function(n) return tostring(n) end)(M.Golden_Fibonacci_Test_fib(32)))() 25 | -------------------------------------------------------------------------------- /test/ps/output/Golden.Foreign.Lib/corefn.json: -------------------------------------------------------------------------------- 1 | {"builtWith":"0.15.15","comments":[],"decls":[],"exports":["dead","alive"],"foreign":["dead","alive"],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[4,28],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Golden","Foreign","Lib"],"modulePath":"golden/Golden/Foreign/Lib.purs","reExports":{},"sourceSpan":{"end":[4,28],"start":[1,1]}} -------------------------------------------------------------------------------- /test/ps/output/Golden.Foreign.Lib/golden.ir: -------------------------------------------------------------------------------- 1 | UberModule 2 | { uberModuleBindings = 3 | [ Standalone 4 | ( QName 5 | { qnameModuleName = ModuleName "Golden.Foreign.Lib", qnameName = Name "foreign" 6 | }, ForeignImport Nothing 7 | ( ModuleName "Golden.Foreign.Lib" ) "golden/Golden/Foreign/Lib.purs" 8 | [ ( Nothing, Name "dead" ), ( Nothing, Name "alive" ) ] 9 | ) 10 | ], uberModuleForeigns = [], uberModuleExports = 11 | [ 12 | ( Name "dead", ObjectProp ( Just Always ) 13 | ( Ref Nothing ( Imported ( ModuleName "Golden.Foreign.Lib" ) ( Name "foreign" ) ) 0 ) 14 | ( PropName "dead" ) 15 | ), 16 | ( Name "alive", ObjectProp ( Just Always ) 17 | ( Ref Nothing ( Imported ( ModuleName "Golden.Foreign.Lib" ) ( Name "foreign" ) ) 0 ) 18 | ( PropName "alive" ) 19 | ) 20 | ] 21 | } -------------------------------------------------------------------------------- /test/ps/output/Golden.Foreign.Lib/golden.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | M.Golden_Foreign_Lib_foreign = { dead = -100, alive = 100 } 3 | return { 4 | dead = M.Golden_Foreign_Lib_foreign.dead, 5 | alive = M.Golden_Foreign_Lib_foreign.alive 6 | } 7 | -------------------------------------------------------------------------------- /test/ps/output/Golden.Foreign.Test/corefn.json: -------------------------------------------------------------------------------- 1 | {"builtWith":"0.15.15","comments":[],"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[8,17],"start":[8,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[9,21],"start":[9,7]}},"type":"Literal","value":{"literalType":"ArrayLiteral","value":[{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[9,12],"start":[9,9]}},"type":"Var","value":{"identifier":"boo","moduleName":["Golden","Foreign","Test"]}},{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[9,19],"start":[9,14]}},"type":"Var","value":{"identifier":"alive","moduleName":["Golden","Foreign","Lib"]}}]}},"identifier":"baz"}],"exports":["foo","baz"],"foreign":["foo","boo"],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[9,21],"start":[1,1]}},"moduleName":["Golden","Foreign","Lib"]},{"annotation":{"meta":null,"sourceSpan":{"end":[9,21],"start":[1,1]}},"moduleName":["Golden","Foreign","Test"]},{"annotation":{"meta":null,"sourceSpan":{"end":[9,21],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Golden","Foreign","Test"],"modulePath":"golden/Golden/Foreign/Test.purs","reExports":{},"sourceSpan":{"end":[9,21],"start":[1,1]}} -------------------------------------------------------------------------------- /test/ps/output/Golden.Foreign.Test/golden.ir: -------------------------------------------------------------------------------- 1 | UberModule 2 | { uberModuleBindings = 3 | [ Standalone 4 | ( QName 5 | { qnameModuleName = ModuleName "Golden.Foreign.Test", qnameName = Name "foreign" 6 | }, ForeignImport Nothing 7 | ( ModuleName "Golden.Foreign.Test" ) "golden/Golden/Foreign/Test.purs" 8 | [ ( Nothing, Name "foo" ), ( Nothing, Name "boo" ) ] 9 | ) 10 | ], uberModuleForeigns = [], uberModuleExports = 11 | [ 12 | ( Name "foo", ObjectProp ( Just Always ) 13 | ( Ref Nothing ( Imported ( ModuleName "Golden.Foreign.Test" ) ( Name "foreign" ) ) 0 ) 14 | ( PropName "foo" ) 15 | ), 16 | ( Name "baz", LiteralArray Nothing 17 | [ ObjectProp ( Just Always ) 18 | ( Ref Nothing ( Imported ( ModuleName "Golden.Foreign.Test" ) ( Name "foreign" ) ) 0 ) 19 | ( PropName "boo" ), ObjectProp ( Just Always ) 20 | ( ForeignImport Nothing 21 | ( ModuleName "Golden.Foreign.Lib" ) "golden/Golden/Foreign/Lib.purs" 22 | [ ( Nothing, Name "alive" ) ] 23 | ) 24 | ( PropName "alive" ) 25 | ] 26 | ) 27 | ] 28 | } -------------------------------------------------------------------------------- /test/ps/output/Golden.Foreign.Test/golden.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | M.Golden_Foreign_Test_foreign = (function() 3 | local fooBar = 42 4 | return { foo = fooBar + 1, boo = fooBar + 2 } 5 | end)() 6 | return { 7 | foo = M.Golden_Foreign_Test_foreign.foo, 8 | baz = { [1] = M.Golden_Foreign_Test_foreign.boo, [2] = 100 } 9 | } 10 | -------------------------------------------------------------------------------- /test/ps/output/Golden.HelloPrelude.Test/corefn.json: -------------------------------------------------------------------------------- 1 | {"builtWith":"0.15.15","comments":[],"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[6,20],"start":[6,1]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[7,12],"start":[7,8]}},"type":"Var","value":{"identifier":"pass","moduleName":["Prelude"]}},"annotation":{"meta":{"metaType":"IsSyntheticApp"},"sourceSpan":{"end":[7,12],"start":[7,8]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"applicativeEffect","moduleName":["Effect"]}},"type":"App"},"identifier":"main"}],"exports":["main"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[7,12],"start":[1,1]}},"moduleName":["Effect"]},{"annotation":{"meta":null,"sourceSpan":{"end":[7,12],"start":[1,1]}},"moduleName":["Prelude"]},{"annotation":{"meta":null,"sourceSpan":{"end":[7,12],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Golden","HelloPrelude","Test"],"modulePath":"golden/Golden/HelloPrelude/Test.purs","reExports":{},"sourceSpan":{"end":[7,12],"start":[1,1]}} -------------------------------------------------------------------------------- /test/ps/output/Golden.HelloPrelude.Test/golden.lua: -------------------------------------------------------------------------------- 1 | local function PSLUA_runtime_lazy(name) 2 | return function(init) 3 | return function() 4 | local state = 0 5 | local val = nil 6 | if state == 2 then 7 | return val 8 | else 9 | if state == 1 then 10 | return error(name .. " was needed before it finished initializing") 11 | else 12 | state = 1 13 | val = init() 14 | state = 2 15 | return val 16 | end 17 | end 18 | end 19 | end 20 | end 21 | local M = {} 22 | M.Effect_foreign = { 23 | pureE = function(a) 24 | return function() 25 | return a 26 | end 27 | end, 28 | bindE = function(a) 29 | return function(f) 30 | return function() 31 | return f(a())() 32 | end 33 | end 34 | end 35 | } 36 | M.Control_Applicative_pure = function(dict) return dict.pure end 37 | M.Effect_monadEffect = { 38 | Applicative0 = function() return M.Effect_applicativeEffect end, 39 | Bind1 = function() return M.Effect_bindEffect end 40 | } 41 | M.Effect_bindEffect = { 42 | bind = M.Effect_foreign.bindE, 43 | Apply0 = function() return M.Effect_Lazy_applyEffect(0) end 44 | } 45 | M.Effect_applicativeEffect = { 46 | pure = M.Effect_foreign.pureE, 47 | Apply0 = function() return M.Effect_Lazy_applyEffect(0) end 48 | } 49 | M.Effect_Lazy_functorEffect = PSLUA_runtime_lazy("functorEffect")(function() 50 | return { 51 | map = function(f) 52 | return (M.Effect_applicativeEffect.Apply0()).apply(M.Control_Applicative_pure(M.Effect_applicativeEffect)(f)) 53 | end 54 | } 55 | end) 56 | M.Effect_Lazy_applyEffect = PSLUA_runtime_lazy("applyEffect")(function() 57 | return { 58 | apply = (function() 59 | return function(f) 60 | local bind = (M.Effect_monadEffect.Bind1()).bind 61 | return function(a) 62 | return bind(f)(function(fPrime) 63 | return bind(a)(function(aPrime) 64 | return M.Control_Applicative_pure(M.Effect_monadEffect.Applicative0())(fPrime(aPrime)) 65 | end) 66 | end) 67 | end 68 | end 69 | end)(), 70 | Functor0 = function() return M.Effect_Lazy_functorEffect(0) end 71 | } 72 | end) 73 | return { main = M.Control_Applicative_pure(M.Effect_applicativeEffect)({}) } 74 | -------------------------------------------------------------------------------- /test/ps/output/Golden.Inline.Test/corefn.json: -------------------------------------------------------------------------------- 1 | {"builtWith":"0.15.15","comments":[],"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[16,32],"start":[16,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[16,32],"start":[16,1]}},"argument":"x","body":{"annotation":{"meta":null,"sourceSpan":{"end":[16,32],"start":[16,1]}},"type":"Var","value":{"identifier":"x","sourcePos":[0,0]}},"type":"Abs"},"identifier":"MkMu"},{"annotation":{"meta":null,"sourceSpan":{"end":[18,29],"start":[18,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[18,29],"start":[18,1]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[18,29],"start":[18,1]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[19,18],"start":[19,7]}},"binder":{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[19,17],"start":[19,11]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[19,17],"start":[19,16]}},"binderType":"VarBinder","identifier":"f"}],"constructorName":{"identifier":"MkMu","moduleName":["Golden","Inline","Test"]},"typeName":{"identifier":"Mu","moduleName":["Golden","Inline","Test"]}},"binderType":"NamedBinder","identifier":"mu"}],"expression":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[19,22],"start":[19,21]}},"type":"Var","value":{"identifier":"f","sourcePos":[19,16]}},"annotation":{"meta":null,"sourceSpan":{"end":[19,25],"start":[19,21]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[19,25],"start":[19,23]}},"type":"Var","value":{"identifier":"mu","sourcePos":[19,7]}},"type":"App"},"isGuarded":false}],"caseExpressions":[{"annotation":{"meta":null,"sourceSpan":{"end":[19,25],"start":[19,1]}},"type":"Var","value":{"identifier":"v","sourcePos":[0,0]}}],"type":"Case"},"type":"Abs"},"identifier":"runMu"},{"annotation":{"meta":null,"sourceSpan":{"end":[8,12],"start":[8,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[14,13],"start":[10,3]}},"binds":[{"annotation":{"meta":null,"sourceSpan":{"end":[10,30],"start":[10,7]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[10,30],"start":[10,7]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[11,14],"start":[11,13]}},"type":"Literal","value":{"literalType":"IntLiteral","value":1}},"type":"Abs"},"identifier":"x"}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[14,13],"start":[12,6]}},"binds":[{"annotation":{"meta":null,"sourceSpan":{"end":[12,34],"start":[12,11]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[12,34],"start":[12,11]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[13,18],"start":[13,17]}},"type":"Literal","value":{"literalType":"IntLiteral","value":2}},"type":"Abs"},"identifier":"y"}],"expression":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[14,11],"start":[14,10]}},"type":"Var","value":{"identifier":"x","sourcePos":[10,7]}},"annotation":{"meta":null,"sourceSpan":{"end":[14,13],"start":[14,10]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[14,13],"start":[14,12]}},"type":"Var","value":{"identifier":"y","sourcePos":[12,11]}},"type":"App"},"type":"Let"},"type":"Let"},"identifier":"main"},{"annotation":{"meta":null,"sourceSpan":{"end":[21,14],"start":[21,1]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[22,11],"start":[22,7]}},"type":"Var","value":{"identifier":"MkMu","moduleName":["Golden","Inline","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[22,17],"start":[22,7]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[22,17],"start":[22,12]}},"type":"Var","value":{"identifier":"runMu","moduleName":["Golden","Inline","Test"]}},"type":"App"},"identifier":"iMu"}],"exports":["main","runMu","iMu"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[22,17],"start":[1,1]}},"moduleName":["Golden","Inline","Test"]},{"annotation":{"meta":null,"sourceSpan":{"end":[22,17],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Golden","Inline","Test"],"modulePath":"golden/Golden/Inline/Test.purs","reExports":{},"sourceSpan":{"end":[22,17],"start":[1,1]}} -------------------------------------------------------------------------------- /test/ps/output/Golden.Inline.Test/golden.ir: -------------------------------------------------------------------------------- 1 | UberModule 2 | { uberModuleBindings = 3 | [ Standalone 4 | ( QName 5 | { qnameModuleName = ModuleName "Golden.Inline.Test", qnameName = Name "runMu" 6 | }, Abs Nothing 7 | ( ParamNamed Nothing ( Name "v" ) ) 8 | ( App Nothing 9 | ( Ref Nothing ( Local ( Name "v" ) ) 0 ) 10 | ( Ref Nothing ( Local ( Name "v" ) ) 0 ) 11 | ) 12 | ) 13 | ], uberModuleForeigns = [], uberModuleExports = 14 | [ 15 | ( Name "main", LiteralInt Nothing 1 ), 16 | ( Name "runMu", Ref Nothing 17 | ( Imported ( ModuleName "Golden.Inline.Test" ) ( Name "runMu" ) ) 0 18 | ), 19 | ( Name "iMu", Ref Nothing 20 | ( Imported ( ModuleName "Golden.Inline.Test" ) ( Name "runMu" ) ) 0 21 | ) 22 | ] 23 | } -------------------------------------------------------------------------------- /test/ps/output/Golden.Inline.Test/golden.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | M.Golden_Inline_Test_runMu = function(v) return v(v) end 3 | return { 4 | main = 1, 5 | runMu = M.Golden_Inline_Test_runMu, 6 | iMu = M.Golden_Inline_Test_runMu 7 | } 8 | -------------------------------------------------------------------------------- /test/ps/output/Golden.NameShadowing.Test/golden.ir: -------------------------------------------------------------------------------- 1 | UberModule 2 | { uberModuleBindings = 3 | [ Standalone 4 | ( QName 5 | { qnameModuleName = ModuleName "Golden.NameShadowing.Test", qnameName = Name "f" 6 | }, Abs Nothing 7 | ( ParamNamed Nothing ( Name "v" ) ) 8 | ( Abs Nothing 9 | ( ParamNamed Nothing ( Name "v1" ) ) 10 | ( IfThenElse Nothing 11 | ( Eq Nothing ( LiteralInt Nothing 1 ) ( Ref Nothing ( Local ( Name "v" ) ) 0 ) ) 12 | ( LiteralInt Nothing 1 ) 13 | ( IfThenElse Nothing 14 | ( Eq Nothing ( LiteralInt Nothing 1 ) ( Ref Nothing ( Local ( Name "v1" ) ) 0 ) ) 15 | ( LiteralInt Nothing 2 ) 16 | ( LiteralInt Nothing 3 ) 17 | ) 18 | ) 19 | ) 20 | ) 21 | ], uberModuleForeigns = [], uberModuleExports = 22 | [ 23 | ( Name "b", Abs Nothing 24 | ( ParamNamed Nothing ( Name "x" ) ) 25 | ( Abs Nothing 26 | ( ParamNamed Nothing ( Name "x1" ) ) 27 | ( App Nothing 28 | ( App Nothing 29 | ( Ref Nothing 30 | ( Imported ( ModuleName "Golden.NameShadowing.Test" ) ( Name "f" ) ) 0 31 | ) 32 | ( App Nothing 33 | ( App Nothing 34 | ( Ref Nothing 35 | ( Imported ( ModuleName "Golden.NameShadowing.Test" ) ( Name "f" ) ) 0 36 | ) 37 | ( Ref Nothing ( Local ( Name "x" ) ) 0 ) 38 | ) 39 | ( Ref Nothing ( Local ( Name "x1" ) ) 0 ) 40 | ) 41 | ) 42 | ( App Nothing 43 | ( App Nothing 44 | ( Ref Nothing 45 | ( Imported ( ModuleName "Golden.NameShadowing.Test" ) ( Name "f" ) ) 0 46 | ) 47 | ( LiteralInt Nothing 42 ) 48 | ) 49 | ( LiteralInt Nothing 1 ) 50 | ) 51 | ) 52 | ) 53 | ), 54 | ( Name "c", Abs Nothing 55 | ( ParamNamed Nothing ( Name "y" ) ) 56 | ( Abs Nothing 57 | ( ParamNamed Nothing ( Name "x1" ) ) 58 | ( App Nothing 59 | ( App Nothing 60 | ( Ref Nothing 61 | ( Imported ( ModuleName "Golden.NameShadowing.Test" ) ( Name "f" ) ) 0 62 | ) 63 | ( Ref Nothing ( Local ( Name "x1" ) ) 0 ) 64 | ) 65 | ( Ref Nothing ( Local ( Name "y" ) ) 0 ) 66 | ) 67 | ) 68 | ) 69 | ] 70 | } -------------------------------------------------------------------------------- /test/ps/output/Golden.NameShadowing.Test/golden.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | M.Golden_NameShadowing_Test_f = function(v) 3 | return function(v1) 4 | if 1 == v then return 1 else if 1 == v1 then return 2 else return 3 end end 5 | end 6 | end 7 | return { 8 | b = function(x) 9 | return function(x1) 10 | return M.Golden_NameShadowing_Test_f(M.Golden_NameShadowing_Test_f(x)(x1))(M.Golden_NameShadowing_Test_f(42)(1)) 11 | end 12 | end, 13 | c = function(y) 14 | return function(x1) return M.Golden_NameShadowing_Test_f(x1)(y) end 15 | end 16 | } 17 | -------------------------------------------------------------------------------- /test/ps/output/Golden.Nested.Test/corefn.json: -------------------------------------------------------------------------------- 1 | {"builtWith":"0.15.15","comments":[],"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,25],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[3,25],"start":[3,1]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[3,25],"start":[3,1]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[4,9],"start":[4,8]}},"binderType":"LiteralBinder","literal":{"literalType":"IntLiteral","value":0}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[4,16],"start":[4,12]}},"type":"Literal","value":{"literalType":"BooleanLiteral","value":true}},"isGuarded":false},{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[5,9],"start":[5,8]}},"binderType":"NullBinder"}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[5,17],"start":[5,12]}},"type":"Literal","value":{"literalType":"BooleanLiteral","value":false}},"isGuarded":false}],"caseExpressions":[{"annotation":{"meta":null,"sourceSpan":{"end":[4,16],"start":[4,1]}},"type":"Var","value":{"identifier":"v","sourcePos":[0,0]}}],"type":"Case"},"type":"Abs"},"identifier":"isZero"},{"annotation":{"meta":null,"sourceSpan":{"end":[7,15],"start":[7,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[11,45],"start":[9,3]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[11,45],"start":[9,3]}},"binderType":"LiteralBinder","literal":{"literalType":"BooleanLiteral","value":true}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[10,44],"start":[10,11]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[10,44],"start":[10,11]}},"binderType":"LiteralBinder","literal":{"literalType":"BooleanLiteral","value":true}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[10,32],"start":[10,28]}},"type":"Literal","value":{"literalType":"StringLiteral","value":"ok"}},"isGuarded":false},{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[10,44],"start":[10,11]}},"binderType":"NullBinder"}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[10,44],"start":[10,38]}},"type":"Literal","value":{"literalType":"StringLiteral","value":"fine"}},"isGuarded":false}],"caseExpressions":[{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[10,20],"start":[10,14]}},"type":"Var","value":{"identifier":"isZero","moduleName":["Golden","Nested","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[10,22],"start":[10,14]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[10,22],"start":[10,21]}},"type":"Literal","value":{"literalType":"IntLiteral","value":1}},"type":"App"}],"type":"Case"},"isGuarded":false},{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[11,45],"start":[9,3]}},"binderType":"NullBinder"}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[11,44],"start":[11,11]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[11,44],"start":[11,11]}},"binderType":"LiteralBinder","literal":{"literalType":"BooleanLiteral","value":true}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[11,32],"start":[11,28]}},"type":"Literal","value":{"literalType":"StringLiteral","value":"ha"}},"isGuarded":false},{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[11,44],"start":[11,11]}},"binderType":"NullBinder"}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[11,44],"start":[11,38]}},"type":"Literal","value":{"literalType":"StringLiteral","value":"cool"}},"isGuarded":false}],"caseExpressions":[{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[11,20],"start":[11,14]}},"type":"Var","value":{"identifier":"isZero","moduleName":["Golden","Nested","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[11,22],"start":[11,14]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[11,22],"start":[11,21]}},"type":"Literal","value":{"literalType":"IntLiteral","value":0}},"type":"App"}],"type":"Case"},"isGuarded":false}],"caseExpressions":[{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[9,12],"start":[9,6]}},"type":"Var","value":{"identifier":"isZero","moduleName":["Golden","Nested","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[9,14],"start":[9,6]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[9,14],"start":[9,13]}},"type":"Literal","value":{"literalType":"IntLiteral","value":1}},"type":"App"}],"type":"Case"},"identifier":"main"}],"exports":["isZero","main"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[11,45],"start":[1,1]}},"moduleName":["Golden","Nested","Test"]},{"annotation":{"meta":null,"sourceSpan":{"end":[11,45],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Golden","Nested","Test"],"modulePath":"golden/Golden/Nested/Test.purs","reExports":{},"sourceSpan":{"end":[11,45],"start":[1,1]}} -------------------------------------------------------------------------------- /test/ps/output/Golden.Nested.Test/golden.ir: -------------------------------------------------------------------------------- 1 | UberModule 2 | { uberModuleBindings = 3 | [ Standalone 4 | ( QName 5 | { qnameModuleName = ModuleName "Golden.Nested.Test", qnameName = Name "isZero" 6 | }, Abs Nothing 7 | ( ParamNamed Nothing ( Name "v" ) ) 8 | ( IfThenElse Nothing 9 | ( Eq Nothing 10 | ( LiteralInt Nothing 0 ) 11 | ( Ref Nothing ( Local ( Name "v" ) ) 0 ) 12 | ) ( LiteralBool Nothing True ) ( LiteralBool Nothing False ) 13 | ) 14 | ) 15 | ], uberModuleForeigns = [], uberModuleExports = 16 | [ 17 | ( Name "isZero", Ref Nothing 18 | ( Imported ( ModuleName "Golden.Nested.Test" ) ( Name "isZero" ) ) 0 19 | ), 20 | ( Name "main", IfThenElse Nothing 21 | ( App Nothing 22 | ( Ref Nothing ( Imported ( ModuleName "Golden.Nested.Test" ) ( Name "isZero" ) ) 0 ) 23 | ( LiteralInt Nothing 1 ) 24 | ) 25 | ( IfThenElse Nothing 26 | ( App Nothing 27 | ( Ref Nothing ( Imported ( ModuleName "Golden.Nested.Test" ) ( Name "isZero" ) ) 0 ) 28 | ( LiteralInt Nothing 1 ) 29 | ) 30 | ( LiteralString Nothing "ok" ) 31 | ( LiteralString Nothing "fine" ) 32 | ) 33 | ( IfThenElse Nothing 34 | ( App Nothing 35 | ( Ref Nothing ( Imported ( ModuleName "Golden.Nested.Test" ) ( Name "isZero" ) ) 0 ) 36 | ( LiteralInt Nothing 0 ) 37 | ) 38 | ( LiteralString Nothing "ha" ) 39 | ( LiteralString Nothing "cool" ) 40 | ) 41 | ) 42 | ] 43 | } -------------------------------------------------------------------------------- /test/ps/output/Golden.Nested.Test/golden.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | M.Golden_Nested_Test_isZero = function(v) 3 | if 0 == v then return true else return false end 4 | end 5 | return { 6 | isZero = M.Golden_Nested_Test_isZero, 7 | main = (function() 8 | if M.Golden_Nested_Test_isZero(1) then 9 | if M.Golden_Nested_Test_isZero(1) then return "ok" else return "fine" end 10 | else 11 | if M.Golden_Nested_Test_isZero(0) then return "ha" else return "cool" end 12 | end 13 | end)() 14 | } 15 | -------------------------------------------------------------------------------- /test/ps/output/Golden.Newtype.Test/corefn.json: -------------------------------------------------------------------------------- 1 | {"builtWith":"0.15.15","comments":[],"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,31],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[3,31],"start":[3,1]}},"argument":"x","body":{"annotation":{"meta":null,"sourceSpan":{"end":[3,31],"start":[3,1]}},"type":"Var","value":{"identifier":"x","sourcePos":[0,0]}},"type":"Abs"},"identifier":"NT"},{"annotation":{"meta":null,"sourceSpan":{"end":[8,26],"start":[8,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[9,7],"start":[9,5]}},"type":"Var","value":{"identifier":"NT","moduleName":["Golden","Newtype","Test"]}},"identifier":"g"},{"annotation":{"meta":null,"sourceSpan":{"end":[5,15],"start":[5,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[5,15],"start":[5,1]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[5,15],"start":[5,1]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[6,8],"start":[6,4]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[6,8],"start":[6,7]}},"binderType":"VarBinder","identifier":"n"}],"constructorName":{"identifier":"NT","moduleName":["Golden","Newtype","Test"]},"typeName":{"identifier":"NT","moduleName":["Golden","Newtype","Test"]}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[6,17],"start":[6,12]}},"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[6,13],"start":[6,12]}},"type":"Var","value":{"identifier":"n","sourcePos":[6,7]}},"fieldName":"foo","type":"Accessor"},"isGuarded":false}],"caseExpressions":[{"annotation":{"meta":null,"sourceSpan":{"end":[6,17],"start":[6,1]}},"type":"Var","value":{"identifier":"v","sourcePos":[0,0]}}],"type":"Case"},"type":"Abs"},"identifier":"f"}],"exports":["NT","f","g"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[9,7],"start":[1,1]}},"moduleName":["Golden","Newtype","Test"]},{"annotation":{"meta":null,"sourceSpan":{"end":[9,7],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Golden","Newtype","Test"],"modulePath":"golden/Golden/Newtype/Test.purs","reExports":{},"sourceSpan":{"end":[9,7],"start":[1,1]}} -------------------------------------------------------------------------------- /test/ps/output/Golden.Newtype.Test/golden.ir: -------------------------------------------------------------------------------- 1 | UberModule 2 | { uberModuleBindings = 3 | [ Standalone 4 | ( QName 5 | { qnameModuleName = ModuleName "Golden.Newtype.Test", qnameName = Name "NT" }, Abs Nothing 6 | ( ParamNamed Nothing ( Name "x" ) ) 7 | ( Ref Nothing ( Local ( Name "x" ) ) 0 ) 8 | ) 9 | ], uberModuleForeigns = [], uberModuleExports = 10 | [ 11 | ( Name "NT", Ref Nothing ( Imported ( ModuleName "Golden.Newtype.Test" ) ( Name "NT" ) ) 0 ), 12 | ( Name "f", Abs Nothing 13 | ( ParamNamed Nothing ( Name "v" ) ) 14 | ( ObjectProp Nothing ( Ref Nothing ( Local ( Name "v" ) ) 0 ) ( PropName "foo" ) ) 15 | ), 16 | ( Name "g", Ref Nothing ( Imported ( ModuleName "Golden.Newtype.Test" ) ( Name "NT" ) ) 0 ) 17 | ] 18 | } -------------------------------------------------------------------------------- /test/ps/output/Golden.Newtype.Test/golden.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | M.Golden_Newtype_Test_NT = function(x) return x end 3 | return { 4 | NT = M.Golden_Newtype_Test_NT, 5 | f = function(v) return v.foo end, 6 | g = M.Golden_Newtype_Test_NT 7 | } 8 | -------------------------------------------------------------------------------- /test/ps/output/Golden.PatternMatching.Test1/golden.lua: -------------------------------------------------------------------------------- 1 | return { 2 | Zero = { ["$ctor"] = "Golden.PatternMatching.Test1∷N.Zero" }, 3 | Succ = function(value0) 4 | return { 5 | ["$ctor"] = "Golden.PatternMatching.Test1∷N.Succ", 6 | value0 = value0 7 | } 8 | end, 9 | Num = function(value0) 10 | return { ["$ctor"] = "Golden.PatternMatching.Test1∷E.Num", value0 = value0 } 11 | end, 12 | Not = function(value0) 13 | return { ["$ctor"] = "Golden.PatternMatching.Test1∷E.Not", value0 = value0 } 14 | end, 15 | pat = function(e) 16 | if "Golden.PatternMatching.Test1∷E.Not" == e["$ctor"] then 17 | if "Golden.PatternMatching.Test1∷E.Num" == e.value0["$ctor"] then 18 | if "Golden.PatternMatching.Test1∷N.Succ" == e.value0.value0["$ctor"] then 19 | return 1 20 | else 21 | if "Golden.PatternMatching.Test1∷N.Zero" == e.value0.value0["$ctor"] then 22 | return 2 23 | else 24 | return 6 25 | end 26 | end 27 | else 28 | if "Golden.PatternMatching.Test1∷E.Not" == e.value0["$ctor"] then 29 | if "Golden.PatternMatching.Test1∷E.Num" == e.value0.value0["$ctor"] then 30 | if "Golden.PatternMatching.Test1∷N.Succ" == e.value0.value0.value0["$ctor"] then 31 | return 3 32 | else 33 | return 6 34 | end 35 | else 36 | return 6 37 | end 38 | else 39 | return 6 40 | end 41 | end 42 | else 43 | if "Golden.PatternMatching.Test1∷E.Num" == e["$ctor"] then 44 | if "Golden.PatternMatching.Test1∷N.Succ" == e.value0["$ctor"] then 45 | return 4 46 | else 47 | return 5 48 | end 49 | else 50 | return 6 51 | end 52 | end 53 | end, 54 | T = function(value0) 55 | return function(value1) 56 | return { 57 | ["$ctor"] = "Golden.PatternMatching.Test1∷Tuple.T", 58 | value0 = value0, 59 | value1 = value1 60 | } 61 | end 62 | end, 63 | fst = function(v) return v.value0 end, 64 | snd = function(v) return v.value1 end 65 | } 66 | -------------------------------------------------------------------------------- /test/ps/output/Golden.PatternMatching.Test2/golden.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | M.Golden_PatternMatching_Test2_bat = function(n) 3 | if "Golden.PatternMatching.Test1∷N.Zero" == n["$ctor"] then 4 | return 1 5 | else 6 | if "Golden.PatternMatching.Test1∷N.Succ" == n["$ctor"] then 7 | return M.Golden_PatternMatching_Test2_bat(n.value0) 8 | else 9 | return error("No patterns matched") 10 | end 11 | end 12 | end 13 | return { 14 | Zero = { ["$ctor"] = "Golden.PatternMatching.Test2∷N.Zero" }, 15 | Succ = function(value0) 16 | return { 17 | ["$ctor"] = "Golden.PatternMatching.Test2∷N.Succ", 18 | value0 = value0 19 | } 20 | end, 21 | Add = function(value0) 22 | return function(value1) 23 | return { 24 | ["$ctor"] = "Golden.PatternMatching.Test2∷N.Add", 25 | value0 = value0, 26 | value1 = value1 27 | } 28 | end 29 | end, 30 | Mul = function(value0) 31 | return function(value1) 32 | return { 33 | ["$ctor"] = "Golden.PatternMatching.Test2∷N.Mul", 34 | value0 = value0, 35 | value1 = value1 36 | } 37 | end 38 | end, 39 | pat = function(e) 40 | if "Golden.PatternMatching.Test2∷N.Add" == e["$ctor"] then 41 | if "Golden.PatternMatching.Test2∷N.Zero" == e.value1["$ctor"] then 42 | if "Golden.PatternMatching.Test2∷N.Add" == e.value0["$ctor"] then 43 | return 1 44 | else 45 | if "Golden.PatternMatching.Test2∷N.Mul" == e.value0["$ctor"] then 46 | return 2 47 | else 48 | return 5 49 | end 50 | end 51 | else 52 | if "Golden.PatternMatching.Test2∷N.Mul" == e.value1["$ctor"] then 53 | return 3 54 | else 55 | if "Golden.PatternMatching.Test2∷N.Add" == e.value1["$ctor"] then 56 | return 4 57 | else 58 | if "Golden.PatternMatching.Test2∷N.Zero" == e.value1["$ctor"] then 59 | return 5 60 | else 61 | return 6 62 | end 63 | end 64 | end 65 | end 66 | else 67 | return 6 68 | end 69 | end, 70 | bat = M.Golden_PatternMatching_Test2_bat 71 | } 72 | -------------------------------------------------------------------------------- /test/ps/output/Golden.RecDataDefs.Test/corefn.json: -------------------------------------------------------------------------------- 1 | {"builtWith":"0.15.15","comments":[],"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,18],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[3,18],"start":[3,1]}},"constructorName":"A","fieldNames":[],"type":"Constructor","typeName":"A"},"identifier":"A"},{"annotation":{"meta":null,"sourceSpan":{"end":[3,18],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[3,18],"start":[3,1]}},"constructorName":"AB","fieldNames":["value0"],"type":"Constructor","typeName":"A"},"identifier":"AB"},{"annotation":{"meta":null,"sourceSpan":{"end":[4,18],"start":[4,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[4,18],"start":[4,1]}},"constructorName":"B","fieldNames":[],"type":"Constructor","typeName":"B"},"identifier":"B"},{"annotation":{"meta":null,"sourceSpan":{"end":[4,18],"start":[4,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[4,18],"start":[4,1]}},"constructorName":"BA","fieldNames":["value0"],"type":"Constructor","typeName":"B"},"identifier":"BA"},{"annotation":{"meta":null,"sourceSpan":{"end":[9,7],"start":[9,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":{"constructorType":"SumType","identifiers":[],"metaType":"IsConstructor"},"sourceSpan":{"end":[10,6],"start":[10,5]}},"type":"Var","value":{"identifier":"B","moduleName":["Golden","RecDataDefs","Test"]}},"identifier":"b"},{"annotation":{"meta":null,"sourceSpan":{"end":[12,8],"start":[12,1]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"constructorType":"SumType","identifiers":["value0"],"metaType":"IsConstructor"},"sourceSpan":{"end":[13,8],"start":[13,6]}},"type":"Var","value":{"identifier":"AB","moduleName":["Golden","RecDataDefs","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[13,10],"start":[13,6]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[13,10],"start":[13,9]}},"type":"Var","value":{"identifier":"b","moduleName":["Golden","RecDataDefs","Test"]}},"type":"App"},"identifier":"ab"},{"annotation":{"meta":null,"sourceSpan":{"end":[15,8],"start":[15,1]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"constructorType":"SumType","identifiers":["value0"],"metaType":"IsConstructor"},"sourceSpan":{"end":[16,8],"start":[16,6]}},"type":"Var","value":{"identifier":"BA","moduleName":["Golden","RecDataDefs","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[16,11],"start":[16,6]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[16,11],"start":[16,9]}},"type":"Var","value":{"identifier":"ab","moduleName":["Golden","RecDataDefs","Test"]}},"type":"App"},"identifier":"ba"},{"annotation":{"meta":null,"sourceSpan":{"end":[6,7],"start":[6,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":{"constructorType":"SumType","identifiers":[],"metaType":"IsConstructor"},"sourceSpan":{"end":[7,6],"start":[7,5]}},"type":"Var","value":{"identifier":"A","moduleName":["Golden","RecDataDefs","Test"]}},"identifier":"a"}],"exports":["A","AB","B","BA","a","b","ab","ba"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[16,11],"start":[1,1]}},"moduleName":["Golden","RecDataDefs","Test"]},{"annotation":{"meta":null,"sourceSpan":{"end":[16,11],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Golden","RecDataDefs","Test"],"modulePath":"golden/Golden/RecDataDefs/Test.purs","reExports":{},"sourceSpan":{"end":[16,11],"start":[1,1]}} -------------------------------------------------------------------------------- /test/ps/output/Golden.RecDataDefs.Test/golden.ir: -------------------------------------------------------------------------------- 1 | UberModule 2 | { uberModuleBindings = 3 | [ Standalone 4 | ( QName 5 | { qnameModuleName = ModuleName "Golden.RecDataDefs.Test", qnameName = Name "A" 6 | }, Ctor Nothing SumType 7 | ( ModuleName "Golden.RecDataDefs.Test" ) 8 | ( TyName "A" ) 9 | ( CtorName "A" ) [] 10 | ), Standalone 11 | ( QName 12 | { qnameModuleName = ModuleName "Golden.RecDataDefs.Test", qnameName = Name "AB" 13 | }, Ctor Nothing SumType 14 | ( ModuleName "Golden.RecDataDefs.Test" ) 15 | ( TyName "A" ) 16 | ( CtorName "AB" ) 17 | [ FieldName "value0" ] 18 | ), Standalone 19 | ( QName 20 | { qnameModuleName = ModuleName "Golden.RecDataDefs.Test", qnameName = Name "B" 21 | }, Ctor Nothing SumType 22 | ( ModuleName "Golden.RecDataDefs.Test" ) 23 | ( TyName "B" ) 24 | ( CtorName "B" ) [] 25 | ), Standalone 26 | ( QName 27 | { qnameModuleName = ModuleName "Golden.RecDataDefs.Test", qnameName = Name "BA" 28 | }, Ctor Nothing SumType 29 | ( ModuleName "Golden.RecDataDefs.Test" ) 30 | ( TyName "B" ) 31 | ( CtorName "BA" ) 32 | [ FieldName "value0" ] 33 | ), Standalone 34 | ( QName 35 | { qnameModuleName = ModuleName "Golden.RecDataDefs.Test", qnameName = Name "ab" 36 | }, App Nothing 37 | ( Ref Nothing ( Imported ( ModuleName "Golden.RecDataDefs.Test" ) ( Name "AB" ) ) 0 ) 38 | ( Ref Nothing ( Imported ( ModuleName "Golden.RecDataDefs.Test" ) ( Name "B" ) ) 0 ) 39 | ) 40 | ], uberModuleForeigns = [], uberModuleExports = 41 | [ 42 | ( Name "A", Ref Nothing 43 | ( Imported ( ModuleName "Golden.RecDataDefs.Test" ) ( Name "A" ) ) 0 44 | ), 45 | ( Name "AB", Ref Nothing 46 | ( Imported ( ModuleName "Golden.RecDataDefs.Test" ) ( Name "AB" ) ) 0 47 | ), 48 | ( Name "B", Ref Nothing 49 | ( Imported ( ModuleName "Golden.RecDataDefs.Test" ) ( Name "B" ) ) 0 50 | ), 51 | ( Name "BA", Ref Nothing 52 | ( Imported ( ModuleName "Golden.RecDataDefs.Test" ) ( Name "BA" ) ) 0 53 | ), 54 | ( Name "a", Ref Nothing 55 | ( Imported ( ModuleName "Golden.RecDataDefs.Test" ) ( Name "A" ) ) 0 56 | ), 57 | ( Name "b", Ref Nothing 58 | ( Imported ( ModuleName "Golden.RecDataDefs.Test" ) ( Name "B" ) ) 0 59 | ), 60 | ( Name "ab", Ref Nothing 61 | ( Imported ( ModuleName "Golden.RecDataDefs.Test" ) ( Name "ab" ) ) 0 62 | ), 63 | ( Name "ba", App Nothing 64 | ( Ref Nothing ( Imported ( ModuleName "Golden.RecDataDefs.Test" ) ( Name "BA" ) ) 0 ) 65 | ( Ref Nothing ( Imported ( ModuleName "Golden.RecDataDefs.Test" ) ( Name "ab" ) ) 0 ) 66 | ) 67 | ] 68 | } -------------------------------------------------------------------------------- /test/ps/output/Golden.RecDataDefs.Test/golden.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | M.Golden_RecDataDefs_Test_A = { ["$ctor"] = "Golden.RecDataDefs.Test∷A.A" } 3 | M.Golden_RecDataDefs_Test_AB = function(value0) 4 | return { ["$ctor"] = "Golden.RecDataDefs.Test∷A.AB", value0 = value0 } 5 | end 6 | M.Golden_RecDataDefs_Test_B = { ["$ctor"] = "Golden.RecDataDefs.Test∷B.B" } 7 | M.Golden_RecDataDefs_Test_BA = function(value0) 8 | return { ["$ctor"] = "Golden.RecDataDefs.Test∷B.BA", value0 = value0 } 9 | end 10 | M.Golden_RecDataDefs_Test_ab = M.Golden_RecDataDefs_Test_AB(M.Golden_RecDataDefs_Test_B) 11 | return { 12 | A = M.Golden_RecDataDefs_Test_A, 13 | AB = M.Golden_RecDataDefs_Test_AB, 14 | B = M.Golden_RecDataDefs_Test_B, 15 | BA = M.Golden_RecDataDefs_Test_BA, 16 | a = M.Golden_RecDataDefs_Test_A, 17 | b = M.Golden_RecDataDefs_Test_B, 18 | ab = M.Golden_RecDataDefs_Test_ab, 19 | ba = M.Golden_RecDataDefs_Test_BA(M.Golden_RecDataDefs_Test_ab) 20 | } 21 | -------------------------------------------------------------------------------- /test/ps/output/Golden.RecordsAccess.Test/corefn.json: -------------------------------------------------------------------------------- 1 | {"builtWith":"0.15.15","comments":[],"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[17,18],"start":[17,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[17,18],"start":[17,1]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[19,13],"start":[18,11]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[19,8],"start":[19,3]}},"binderType":"LiteralBinder","literal":{"literalType":"ObjectLiteral","value":[["x",{"annotation":{"meta":null,"sourceSpan":{"end":[19,6],"start":[19,5]}},"binderType":"VarBinder","identifier":"x"}]]}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[19,13],"start":[19,12]}},"type":"Var","value":{"identifier":"x","sourcePos":[19,5]}},"isGuarded":false}],"caseExpressions":[{"annotation":{"meta":null,"sourceSpan":{"end":[18,17],"start":[18,16]}},"type":"Var","value":{"identifier":"v","sourcePos":[18,1]}}],"type":"Case"},"type":"Abs"},"identifier":"test4"},{"annotation":{"meta":null,"sourceSpan":{"end":[14,18],"start":[14,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[14,18],"start":[14,1]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[14,18],"start":[14,1]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[15,12],"start":[15,7]}},"binderType":"LiteralBinder","literal":{"literalType":"ObjectLiteral","value":[["x",{"annotation":{"meta":null,"sourceSpan":{"end":[15,10],"start":[15,9]}},"binderType":"VarBinder","identifier":"x"}]]}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[15,16],"start":[15,15]}},"type":"Var","value":{"identifier":"x","sourcePos":[15,9]}},"isGuarded":false}],"caseExpressions":[{"annotation":{"meta":null,"sourceSpan":{"end":[15,16],"start":[15,1]}},"type":"Var","value":{"identifier":"v","sourcePos":[0,0]}}],"type":"Case"},"type":"Abs"},"identifier":"test3"},{"annotation":{"meta":null,"sourceSpan":{"end":[11,18],"start":[11,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[12,12],"start":[12,9]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[12,12],"start":[12,9]}},"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"v","sourcePos":[0,0]}},"fieldName":"x","type":"Accessor"},"type":"Abs"},"identifier":"test2"},{"annotation":{"meta":null,"sourceSpan":{"end":[5,7],"start":[5,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[6,22],"start":[6,5]}},"type":"Literal","value":{"literalType":"ObjectLiteral","value":[["x",{"annotation":{"meta":null,"sourceSpan":{"end":[6,11],"start":[6,10]}},"type":"Literal","value":{"literalType":"IntLiteral","value":1}}],["y",{"annotation":{"meta":null,"sourceSpan":{"end":[6,20],"start":[6,16]}},"type":"Literal","value":{"literalType":"BooleanLiteral","value":true}}]]}},"identifier":"r"},{"annotation":{"meta":null,"sourceSpan":{"end":[8,13],"start":[8,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[9,12],"start":[9,9]}},"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[9,10],"start":[9,9]}},"type":"Var","value":{"identifier":"r","moduleName":["Golden","RecordsAccess","Test"]}},"fieldName":"x","type":"Accessor"},"identifier":"test1"}],"exports":["r","test1","test2","test3","test4"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[19,13],"start":[1,1]}},"moduleName":["Golden","RecordsAccess","Test"]},{"annotation":{"meta":null,"sourceSpan":{"end":[19,13],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Golden","RecordsAccess","Test"],"modulePath":"golden/Golden/RecordsAccess/Test.purs","reExports":{},"sourceSpan":{"end":[19,13],"start":[1,1]}} -------------------------------------------------------------------------------- /test/ps/output/Golden.RecordsAccess.Test/golden.ir: -------------------------------------------------------------------------------- 1 | UberModule 2 | { uberModuleBindings = 3 | [ Standalone 4 | ( QName 5 | { qnameModuleName = ModuleName "Golden.RecordsAccess.Test", qnameName = Name "r" 6 | }, LiteralObject Nothing 7 | [ ( PropName "x", LiteralInt Nothing 1 ), ( PropName "y", LiteralBool Nothing True ) ] 8 | ) 9 | ], uberModuleForeigns = [], uberModuleExports = 10 | [ 11 | ( Name "r", Ref Nothing 12 | ( Imported ( ModuleName "Golden.RecordsAccess.Test" ) ( Name "r" ) ) 0 13 | ), 14 | ( Name "test1", ObjectProp Nothing 15 | ( Ref Nothing ( Imported ( ModuleName "Golden.RecordsAccess.Test" ) ( Name "r" ) ) 0 ) 16 | ( PropName "x" ) 17 | ), 18 | ( Name "test2", Abs Nothing 19 | ( ParamNamed Nothing ( Name "v" ) ) 20 | ( ObjectProp Nothing ( Ref Nothing ( Local ( Name "v" ) ) 0 ) ( PropName "x" ) ) 21 | ), 22 | ( Name "test3", Abs Nothing 23 | ( ParamNamed Nothing ( Name "v" ) ) 24 | ( ObjectProp Nothing ( Ref Nothing ( Local ( Name "v" ) ) 0 ) ( PropName "x" ) ) 25 | ), 26 | ( Name "test4", Abs Nothing 27 | ( ParamNamed Nothing ( Name "v" ) ) 28 | ( ObjectProp Nothing ( Ref Nothing ( Local ( Name "v" ) ) 0 ) ( PropName "x" ) ) 29 | ) 30 | ] 31 | } -------------------------------------------------------------------------------- /test/ps/output/Golden.RecordsAccess.Test/golden.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | M.Golden_RecordsAccess_Test_r = { x = 1, y = true } 3 | return { 4 | r = M.Golden_RecordsAccess_Test_r, 5 | test1 = M.Golden_RecordsAccess_Test_r.x, 6 | test2 = function(v) return v.x end, 7 | test3 = function(v) return v.x end, 8 | test4 = function(v) return v.x end 9 | } 10 | -------------------------------------------------------------------------------- /test/ps/output/Golden.RecordsUpdate.Test/corefn.json: -------------------------------------------------------------------------------- 1 | {"builtWith":"0.15.15","comments":[],"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[20,36],"start":[20,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[21,20],"start":[21,9]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[21,20],"start":[21,9]}},"copy":null,"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"v","sourcePos":[0,0]}},"type":"ObjectUpdate","updates":[["x",{"annotation":{"meta":null,"sourceSpan":{"end":[21,18],"start":[21,17]}},"type":"Literal","value":{"literalType":"IntLiteral","value":1}}]]},"type":"Abs"},"identifier":"test4"},{"annotation":{"meta":null,"sourceSpan":{"end":[15,16],"start":[15,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[16,28],"start":[16,9]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[16,28],"start":[16,9]}},"copy":["x","y"],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"v","sourcePos":[0,0]}},"type":"ObjectUpdate","updates":[["z",{"annotation":{"meta":null,"sourceSpan":{"end":[16,28],"start":[16,9]}},"copy":["z"],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[16,28],"start":[16,9]}},"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"v","sourcePos":[0,0]}},"fieldName":"z","type":"Accessor"},"type":"ObjectUpdate","updates":[["p",{"annotation":{"meta":null,"sourceSpan":{"end":[16,24],"start":[16,21]}},"type":"Literal","value":{"literalType":"CharLiteral","value":"b"}}]]}]]},"type":"Abs"},"identifier":"test3"},{"annotation":{"meta":null,"sourceSpan":{"end":[12,16],"start":[12,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[13,24],"start":[13,9]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[13,24],"start":[13,9]}},"copy":["x","z"],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"v","sourcePos":[0,0]}},"type":"ObjectUpdate","updates":[["y",{"annotation":{"meta":null,"sourceSpan":{"end":[13,22],"start":[13,17]}},"type":"Literal","value":{"literalType":"BooleanLiteral","value":false}}]]},"type":"Abs"},"identifier":"test2"},{"annotation":{"meta":null,"sourceSpan":{"end":[6,7],"start":[6,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[7,47],"start":[7,5]}},"type":"Literal","value":{"literalType":"ObjectLiteral","value":[["x",{"annotation":{"meta":null,"sourceSpan":{"end":[7,11],"start":[7,10]}},"type":"Literal","value":{"literalType":"IntLiteral","value":1}}],["y",{"annotation":{"meta":null,"sourceSpan":{"end":[7,20],"start":[7,16]}},"type":"Literal","value":{"literalType":"BooleanLiteral","value":true}}],["z",{"annotation":{"meta":null,"sourceSpan":{"end":[7,45],"start":[7,25]}},"type":"Literal","value":{"literalType":"ObjectLiteral","value":[["z",{"annotation":{"meta":null,"sourceSpan":{"end":[7,35],"start":[7,30]}},"type":"Literal","value":{"literalType":"StringLiteral","value":"foo"}}],["p",{"annotation":{"meta":null,"sourceSpan":{"end":[7,43],"start":[7,40]}},"type":"Literal","value":{"literalType":"CharLiteral","value":"a"}}]]}}]]}},"identifier":"r"},{"annotation":{"meta":null,"sourceSpan":{"end":[9,11],"start":[9,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[10,20],"start":[10,9]}},"binds":[{"annotation":{"meta":null,"sourceSpan":{"end":[10,20],"start":[10,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[10,10],"start":[10,9]}},"type":"Var","value":{"identifier":"r","moduleName":["Golden","RecordsUpdate","Test"]}},"identifier":"v"}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[10,20],"start":[10,9]}},"copy":["y","z"],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"v","sourcePos":[10,1]}},"type":"ObjectUpdate","updates":[["x",{"annotation":{"meta":null,"sourceSpan":{"end":[10,18],"start":[10,17]}},"type":"Literal","value":{"literalType":"IntLiteral","value":2}}]]},"type":"Let"},"identifier":"test1"}],"exports":["r","test1","test2","test3","test4"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[21,20],"start":[1,1]}},"moduleName":["Golden","RecordsUpdate","Test"]},{"annotation":{"meta":null,"sourceSpan":{"end":[21,20],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Golden","RecordsUpdate","Test"],"modulePath":"golden/Golden/RecordsUpdate/Test.purs","reExports":{},"sourceSpan":{"end":[21,20],"start":[1,1]}} -------------------------------------------------------------------------------- /test/ps/output/Golden.RecordsUpdate.Test/golden.ir: -------------------------------------------------------------------------------- 1 | UberModule 2 | { uberModuleBindings = 3 | [ Standalone 4 | ( QName 5 | { qnameModuleName = ModuleName "Golden.RecordsUpdate.Test", qnameName = Name "r" 6 | }, LiteralObject Nothing 7 | [ 8 | ( PropName "x", LiteralInt Nothing 1 ), 9 | ( PropName "y", LiteralBool Nothing True ), 10 | ( PropName "z", LiteralObject Nothing 11 | [ 12 | ( PropName "z", LiteralString Nothing "foo" ), 13 | ( PropName "p", LiteralChar Nothing 'a' ) 14 | ] 15 | ) 16 | ] 17 | ) 18 | ], uberModuleForeigns = [], uberModuleExports = 19 | [ 20 | ( Name "r", Ref Nothing 21 | ( Imported ( ModuleName "Golden.RecordsUpdate.Test" ) ( Name "r" ) ) 0 22 | ), 23 | ( Name "test1", ObjectUpdate Nothing 24 | ( Ref Nothing ( Imported ( ModuleName "Golden.RecordsUpdate.Test" ) ( Name "r" ) ) 0 ) 25 | ( ( PropName "x", LiteralInt Nothing 2 ) :| [] ) 26 | ), 27 | ( Name "test2", Abs Nothing 28 | ( ParamNamed Nothing ( Name "v" ) ) 29 | ( ObjectUpdate Nothing 30 | ( Ref Nothing ( Local ( Name "v" ) ) 0 ) 31 | ( ( PropName "y", LiteralBool Nothing False ) :| [] ) 32 | ) 33 | ), 34 | ( Name "test3", Abs Nothing 35 | ( ParamNamed Nothing ( Name "v" ) ) 36 | ( ObjectUpdate Nothing 37 | ( Ref Nothing ( Local ( Name "v" ) ) 0 ) 38 | ( 39 | ( PropName "z", ObjectUpdate Nothing 40 | ( ObjectProp Nothing ( Ref Nothing ( Local ( Name "v" ) ) 0 ) ( PropName "z" ) ) 41 | ( ( PropName "p", LiteralChar Nothing 'b' ) :| [] ) 42 | ) :| [] 43 | ) 44 | ) 45 | ), 46 | ( Name "test4", Abs Nothing 47 | ( ParamNamed Nothing ( Name "v" ) ) 48 | ( ObjectUpdate Nothing 49 | ( Ref Nothing ( Local ( Name "v" ) ) 0 ) 50 | ( ( PropName "x", LiteralInt Nothing 1 ) :| [] ) 51 | ) 52 | ) 53 | ] 54 | } -------------------------------------------------------------------------------- /test/ps/output/Golden.RecordsUpdate.Test/golden.lua: -------------------------------------------------------------------------------- 1 | local function PSLUA_object_update(o, patches) 2 | local o_copy = {} 3 | for k, v in pairs(o) do 4 | local patch_v = patches[k] 5 | if patch_v ~= nil then 6 | o_copy[k] = patch_v 7 | else 8 | o_copy[k] = v 9 | end 10 | end 11 | return o_copy 12 | end 13 | local M = {} 14 | M.Golden_RecordsUpdate_Test_r = { x = 1, y = true, z = { z = "foo", p = "a" } } 15 | return { 16 | r = M.Golden_RecordsUpdate_Test_r, 17 | test1 = PSLUA_object_update(M.Golden_RecordsUpdate_Test_r, { x = 2 }), 18 | test2 = function(v) return PSLUA_object_update(v, { y = false }) end, 19 | test3 = function(v) 20 | return PSLUA_object_update(v, { z = PSLUA_object_update(v.z, { p = "b" }) }) 21 | end, 22 | test4 = function(v) return PSLUA_object_update(v, { x = 1 }) end 23 | } 24 | -------------------------------------------------------------------------------- /test/ps/output/Golden.RecursiveBindings.Test/golden.lua: -------------------------------------------------------------------------------- 1 | return { 2 | letRec = (function() 3 | local no 4 | local yes 5 | no = function(v) 6 | if v then 7 | return yes(false) 8 | else 9 | if false == v then 10 | return yes(true) 11 | else 12 | return error("No patterns matched") 13 | end 14 | end 15 | end 16 | yes = function(v) 17 | if v then 18 | return no(false) 19 | else 20 | if false == v then 21 | return no(true) 22 | else 23 | return error("No patterns matched") 24 | end 25 | end 26 | end 27 | return no(false) 28 | end)(), 29 | whereRec = (function() 30 | local no 31 | local yes 32 | no = function(v) 33 | if v then 34 | return yes(false) 35 | else 36 | if false == v then 37 | return yes(true) 38 | else 39 | return error("No patterns matched") 40 | end 41 | end 42 | end 43 | yes = function(v) 44 | if v then 45 | return no(false) 46 | else 47 | if false == v then 48 | return no(true) 49 | else 50 | return error("No patterns matched") 51 | end 52 | end 53 | end 54 | return no(false) 55 | end)(), 56 | letRecMixed = (function() 57 | local z = 1 58 | local a 59 | local b 60 | a = function() return b(z) end 61 | b = function() return a(z) end 62 | local f = function() return a end 63 | local y = f(z)(z) 64 | return f(f(y)(y))(f(y)(0)) 65 | end)() 66 | } 67 | -------------------------------------------------------------------------------- /test/ps/output/Golden.Reexport.Exports/corefn.json: -------------------------------------------------------------------------------- 1 | {"builtWith":"0.15.15","comments":[],"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,16],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[4,13],"start":[4,12]}},"type":"Literal","value":{"literalType":"IntLiteral","value":1}},"identifier":"binding1"}],"exports":["binding1"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[4,13],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Golden","Reexport","Exports"],"modulePath":"golden/Golden/Reexport/Exports.purs","reExports":{},"sourceSpan":{"end":[4,13],"start":[1,1]}} -------------------------------------------------------------------------------- /test/ps/output/Golden.Reexport.Exports/golden.ir: -------------------------------------------------------------------------------- 1 | UberModule 2 | { uberModuleBindings = [], uberModuleForeigns = [], uberModuleExports = 3 | [ ( Name "binding1", LiteralInt Nothing 1 ) ] 4 | } -------------------------------------------------------------------------------- /test/ps/output/Golden.Reexport.Exports/golden.lua: -------------------------------------------------------------------------------- 1 | return { binding1 = 1 } 2 | -------------------------------------------------------------------------------- /test/ps/output/Golden.Reexport.ReExports/corefn.json: -------------------------------------------------------------------------------- 1 | {"builtWith":"0.15.15","comments":[],"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[8,16],"start":[8,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[9,13],"start":[9,12]}},"type":"Literal","value":{"literalType":"IntLiteral","value":2}},"identifier":"binding2"}],"exports":["binding2"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[6,56],"start":[6,1]}},"moduleName":["Golden","Reexport","Exports"]},{"annotation":{"meta":null,"sourceSpan":{"end":[9,13],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Golden","Reexport","ReExports"],"modulePath":"golden/Golden/Reexport/ReExports.purs","reExports":{"Golden.Reexport.Exports":["binding1"]},"sourceSpan":{"end":[9,13],"start":[1,1]}} -------------------------------------------------------------------------------- /test/ps/output/Golden.Reexport.ReExports/golden.ir: -------------------------------------------------------------------------------- 1 | UberModule 2 | { uberModuleBindings = [], uberModuleForeigns = [], uberModuleExports = 3 | [ ( Name "binding2", LiteralInt Nothing 2 ) ] 4 | } -------------------------------------------------------------------------------- /test/ps/output/Golden.Reexport.ReExports/golden.lua: -------------------------------------------------------------------------------- 1 | return { binding2 = 2 } 2 | -------------------------------------------------------------------------------- /test/ps/output/Golden.Reexport.Test/corefn.json: -------------------------------------------------------------------------------- 1 | {"builtWith":"0.15.15","comments":[],"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[5,22],"start":[5,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[6,35],"start":[6,12]}},"type":"Literal","value":{"literalType":"ArrayLiteral","value":[{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[6,22],"start":[6,14]}},"type":"Var","value":{"identifier":"binding1","moduleName":["Golden","Reexport","Exports"]}},{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[6,33],"start":[6,25]}},"type":"Var","value":{"identifier":"binding2","moduleName":["Golden","Reexport","ReExports"]}}]}},"identifier":"binding3"}],"exports":["binding3"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[6,35],"start":[1,1]}},"moduleName":["Golden","Reexport","Exports"]},{"annotation":{"meta":null,"sourceSpan":{"end":[6,35],"start":[1,1]}},"moduleName":["Golden","Reexport","ReExports"]},{"annotation":{"meta":null,"sourceSpan":{"end":[6,35],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Golden","Reexport","Test"],"modulePath":"golden/Golden/Reexport/Test.purs","reExports":{},"sourceSpan":{"end":[6,35],"start":[1,1]}} -------------------------------------------------------------------------------- /test/ps/output/Golden.Reexport.Test/golden.ir: -------------------------------------------------------------------------------- 1 | UberModule 2 | { uberModuleBindings = [], uberModuleForeigns = [], uberModuleExports = 3 | [ ( Name "binding3", LiteralArray Nothing [ LiteralInt Nothing 1, LiteralInt Nothing 2 ] ) ] 4 | } -------------------------------------------------------------------------------- /test/ps/output/Golden.Reexport.Test/golden.lua: -------------------------------------------------------------------------------- 1 | return { binding3 = { [1] = 1, [2] = 2 } } 2 | -------------------------------------------------------------------------------- /test/ps/output/Golden.TestReturnTableField/corefn.json: -------------------------------------------------------------------------------- 1 | {"builtWith":"0.15.15","comments":[],"decls":[],"exports":["u"],"foreign":["u"],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[4,22],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Golden","TestReturnTableField"],"modulePath":"golden/Golden/ReturnTableField/Test.purs","reExports":{},"sourceSpan":{"end":[4,22],"start":[1,1]}} -------------------------------------------------------------------------------- /test/ps/output/Golden.TestReturnTableField/golden.ir: -------------------------------------------------------------------------------- 1 | UberModule 2 | { uberModuleBindings = [], uberModuleForeigns = [], uberModuleExports = 3 | [ 4 | ( Name "u", ObjectProp ( Just Always ) 5 | ( ForeignImport Nothing 6 | ( ModuleName "Golden.TestReturnTableField" ) "golden/Golden/ReturnTableField/Test.purs" 7 | [ ( Nothing, Name "u" ) ] 8 | ) 9 | ( PropName "u" ) 10 | ) 11 | ] 12 | } -------------------------------------------------------------------------------- /test/ps/output/Golden.TestReturnTableField/golden.lua: -------------------------------------------------------------------------------- 1 | return { u = nil } 2 | -------------------------------------------------------------------------------- /test/ps/output/Golden.Unbinding.Test/corefn.json: -------------------------------------------------------------------------------- 1 | {"builtWith":"0.15.15","comments":[],"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[5,10],"start":[5,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[5,10],"start":[5,1]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[5,10],"start":[5,1]}},"argument":"v1","body":{"annotation":{"meta":null,"sourceSpan":{"end":[5,10],"start":[5,9]}},"type":"Literal","value":{"literalType":"IntLiteral","value":3}},"type":"Abs"},"type":"Abs"},"identifier":"f"},{"annotation":{"meta":null,"sourceSpan":{"end":[4,6],"start":[4,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[4,6],"start":[4,5]}},"type":"Literal","value":{"literalType":"IntLiteral","value":2}},"identifier":"b"},{"annotation":{"meta":null,"sourceSpan":{"end":[3,6],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[3,6],"start":[3,5]}},"type":"Literal","value":{"literalType":"IntLiteral","value":1}},"identifier":"a"},{"annotation":{"meta":null,"sourceSpan":{"end":[6,16],"start":[6,1]}},"bindType":"NonRec","expression":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[6,6],"start":[6,5]}},"type":"Var","value":{"identifier":"f","moduleName":["Golden","Unbinding","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[6,8],"start":[6,5]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[6,8],"start":[6,7]}},"type":"Var","value":{"identifier":"a","moduleName":["Golden","Unbinding","Test"]}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[6,16],"start":[6,5]}},"argument":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[6,11],"start":[6,10]}},"type":"Var","value":{"identifier":"f","moduleName":["Golden","Unbinding","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[6,13],"start":[6,10]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[6,13],"start":[6,12]}},"type":"Var","value":{"identifier":"b","moduleName":["Golden","Unbinding","Test"]}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[6,15],"start":[6,10]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[6,15],"start":[6,14]}},"type":"Var","value":{"identifier":"a","moduleName":["Golden","Unbinding","Test"]}},"type":"App"},"type":"App"},"identifier":"c"}],"exports":["a","b","f","c"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[6,16],"start":[1,1]}},"moduleName":["Golden","Unbinding","Test"]},{"annotation":{"meta":null,"sourceSpan":{"end":[6,16],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Golden","Unbinding","Test"],"modulePath":"golden/Golden/Unbinding/Test.purs","reExports":{},"sourceSpan":{"end":[6,16],"start":[1,1]}} -------------------------------------------------------------------------------- /test/ps/output/Golden.Unbinding.Test/golden.ir: -------------------------------------------------------------------------------- 1 | UberModule 2 | { uberModuleBindings = 3 | [ Standalone 4 | ( QName 5 | { qnameModuleName = ModuleName "Golden.Unbinding.Test", qnameName = Name "f" 6 | }, Abs Nothing ( ParamUnused Nothing ) 7 | ( Abs Nothing ( ParamUnused Nothing ) ( LiteralInt Nothing 3 ) ) 8 | ) 9 | ], uberModuleForeigns = [], uberModuleExports = 10 | [ 11 | ( Name "a", LiteralInt Nothing 1 ), 12 | ( Name "b", LiteralInt Nothing 2 ), 13 | ( Name "f", Ref Nothing ( Imported ( ModuleName "Golden.Unbinding.Test" ) ( Name "f" ) ) 0 ), 14 | ( Name "c", App Nothing 15 | ( App Nothing 16 | ( Ref Nothing ( Imported ( ModuleName "Golden.Unbinding.Test" ) ( Name "f" ) ) 0 ) 17 | ( LiteralInt Nothing 1 ) 18 | ) 19 | ( App Nothing 20 | ( App Nothing 21 | ( Ref Nothing ( Imported ( ModuleName "Golden.Unbinding.Test" ) ( Name "f" ) ) 0 ) 22 | ( LiteralInt Nothing 2 ) 23 | ) 24 | ( LiteralInt Nothing 1 ) 25 | ) 26 | ) 27 | ] 28 | } -------------------------------------------------------------------------------- /test/ps/output/Golden.Unbinding.Test/golden.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | M.Golden_Unbinding_Test_f = function() return function() return 3 end end 3 | return { 4 | a = 1, 5 | b = 2, 6 | f = M.Golden_Unbinding_Test_f, 7 | c = M.Golden_Unbinding_Test_f(1)(M.Golden_Unbinding_Test_f(2)(1)) 8 | } 9 | -------------------------------------------------------------------------------- /test/ps/output/Golden.Values.Test/corefn.json: -------------------------------------------------------------------------------- 1 | {"builtWith":"0.15.15","comments":[],"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,9],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[4,6],"start":[4,5]}},"type":"Literal","value":{"literalType":"IntLiteral","value":1}},"identifier":"i"},{"annotation":{"meta":null,"sourceSpan":{"end":[18,20],"start":[18,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[18,20],"start":[18,1]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[19,11],"start":[19,7]}},"type":"Literal","value":{"literalType":"BooleanLiteral","value":true}},"type":"Abs"},"identifier":"f"},{"annotation":{"meta":null,"sourceSpan":{"end":[9,10],"start":[9,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[10,8],"start":[10,5]}},"type":"Literal","value":{"literalType":"CharLiteral","value":"c"}},"identifier":"c"},{"annotation":{"meta":null,"sourceSpan":{"end":[6,13],"start":[6,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[7,9],"start":[7,5]}},"type":"Literal","value":{"literalType":"BooleanLiteral","value":true}},"identifier":"b"},{"annotation":{"meta":null,"sourceSpan":{"end":[15,43],"start":[15,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[16,16],"start":[16,5]}},"type":"Literal","value":{"literalType":"ObjectLiteral","value":[["i",{"annotation":{"meta":null,"sourceSpan":{"end":[16,8],"start":[16,7]}},"type":"Var","value":{"identifier":"i","moduleName":["Golden","Values","Test"]}}],["b",{"annotation":{"meta":null,"sourceSpan":{"end":[16,11],"start":[16,10]}},"type":"Var","value":{"identifier":"b","moduleName":["Golden","Values","Test"]}}],["c",{"annotation":{"meta":null,"sourceSpan":{"end":[16,14],"start":[16,13]}},"type":"Var","value":{"identifier":"c","moduleName":["Golden","Values","Test"]}}]]}},"identifier":"o"},{"annotation":{"meta":null,"sourceSpan":{"end":[12,15],"start":[12,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[13,16],"start":[13,5]}},"type":"Literal","value":{"literalType":"ArrayLiteral","value":[{"annotation":{"meta":null,"sourceSpan":{"end":[13,8],"start":[13,7]}},"type":"Literal","value":{"literalType":"IntLiteral","value":1}},{"annotation":{"meta":null,"sourceSpan":{"end":[13,11],"start":[13,10]}},"type":"Literal","value":{"literalType":"IntLiteral","value":2}},{"annotation":{"meta":null,"sourceSpan":{"end":[13,14],"start":[13,13]}},"type":"Literal","value":{"literalType":"IntLiteral","value":3}}]}},"identifier":"a"}],"exports":["i","b","c","a","o","f"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[19,11],"start":[1,1]}},"moduleName":["Golden","Values","Test"]},{"annotation":{"meta":null,"sourceSpan":{"end":[19,11],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Golden","Values","Test"],"modulePath":"golden/Golden/Values/Test.purs","reExports":{},"sourceSpan":{"end":[19,11],"start":[1,1]}} -------------------------------------------------------------------------------- /test/ps/output/Golden.Values.Test/golden.ir: -------------------------------------------------------------------------------- 1 | UberModule 2 | { uberModuleBindings = [], uberModuleForeigns = [], uberModuleExports = 3 | [ 4 | ( Name "i", LiteralInt Nothing 1 ), 5 | ( Name "b", LiteralBool Nothing True ), 6 | ( Name "c", LiteralChar Nothing 'c' ), 7 | ( Name "a", LiteralArray Nothing 8 | [ LiteralInt Nothing 1, LiteralInt Nothing 2, LiteralInt Nothing 3 ] 9 | ), 10 | ( Name "o", LiteralObject Nothing 11 | [ 12 | ( PropName "i", LiteralInt Nothing 1 ), 13 | ( PropName "b", LiteralBool Nothing True ), 14 | ( PropName "c", LiteralChar Nothing 'c' ) 15 | ] 16 | ), 17 | ( Name "f", Abs Nothing ( ParamUnused Nothing ) ( LiteralBool Nothing True ) ) 18 | ] 19 | } -------------------------------------------------------------------------------- /test/ps/output/Golden.Values.Test/golden.lua: -------------------------------------------------------------------------------- 1 | return { 2 | i = 1, 3 | b = true, 4 | c = "c", 5 | a = { [1] = 1, [2] = 2, [3] = 3 }, 6 | o = { i = 1, b = true, c = "c" }, 7 | f = function() return true end 8 | } 9 | -------------------------------------------------------------------------------- /test/ps/packages.dhall: -------------------------------------------------------------------------------- 1 | let upstream-ps = 2 | https://github.com/purescript/package-sets/releases/download/psc-0.15.15-20240419/packages.dhall 3 | sha256:50c4ee579bf2c38671ac97df821c2cc4221fb3f6ad79c807bb6e4597ab6d1e95 4 | 5 | let upstream-lua = 6 | https://github.com/Unisay/purescript-lua-package-sets/releases/download/psc-0.15.15-20240425/packages.dhall 7 | sha256:3721bc8a2f6681e16fb505b8b0256650d9fd47977755fde9947852343888f14b 8 | 9 | in upstream-ps // upstream-lua 10 | -------------------------------------------------------------------------------- /test/ps/spago.dhall: -------------------------------------------------------------------------------- 1 | { name = "test-project" 2 | , dependencies = [ "console", "effect", "foldable-traversable", "prelude" ] 3 | , packages = ./packages.dhall 4 | , sources = [ "golden/**/*.purs" ] 5 | } 6 | -------------------------------------------------------------------------------- /treefmt.toml: -------------------------------------------------------------------------------- 1 | [formatter.haskell] 2 | command = "fourmolu" 3 | options = [ 4 | "--ghc-opt", 5 | "-XImportQualifiedPost", 6 | "--ghc-opt", 7 | "-XTypeApplications", 8 | "--record-brace-space", 9 | "true", 10 | "--single-constraint-parens", 11 | "never", 12 | "--mode", 13 | "inplace", 14 | ] 15 | includes = ["*.hs"] 16 | 17 | [formatter.cabal] 18 | command = "cabal-fmt" 19 | options = ["--inplace"] 20 | includes = ["*.cabal"] 21 | 22 | [formatter.nix] 23 | command = "nixfmt" 24 | includes = ["*.nix"] 25 | 26 | [formatter.yaml] 27 | command = "yamlfmt" 28 | includes = ["*.yaml", "*.yml" ] 29 | --------------------------------------------------------------------------------