├── .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 | [](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 |
--------------------------------------------------------------------------------