diff --git a/.envrc b/.envrc index 3c3edd1..ffe5221 100644 --- a/.envrc +++ b/.envrc @@ -1,2 +1,3 @@ use flake PATH_add ./scripts +[[ -f .envrc.local ]] && source_env .envrc.local diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..58119aa --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,26 @@ +name: Purescript Lua CI +on: + push: + branches: [main] + pull_request: +jobs: + tests: + runs-on: ubuntu-latest + steps: + - name: "📥 Checkout repository" + uses: actions/checkout@v3 + - name: "❄ Install Nix" + uses: cachix/install-nix-action@v22 + with: + github_access_token: ${{ secrets.GITHUB_TOKEN }} + extra_nix_config: | + access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} + substituters = https://hydra.iohk.io https://cache.nixos.org/ + trusted-public-keys = hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= + - uses: cachix/cachix-action@v12 + with: + name: purescript-lua + authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" + - name: "🔨 Build & test" + run: >- + nix develop --accept-flake-config --allow-import-from-derivation --command cabal test all --test-show-details=direct diff --git a/.gitignore b/.gitignore index 86fdf05..f45c27f 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ result-* .psc-ide-port /output/ .vscode/settings.json +.envrc.local diff --git a/README.md b/README.md index 39c51e2..f56f793 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,15 @@ # Purescript Backend for Lua -Status: (2023-07-05) the project is in the "_ready to be experimented with_" state (read: it likely contains bugs but is already usable). +[![Purescript Lua CI](https://github.com/Unisay/purescript-lua/actions/workflows/ci.yaml/badge.svg)](https://github.com/Unisay/purescript-lua/actions/workflows/ci.yaml) + +🔋 Status: (2023-07-05) the project is in the "_ready to be experimented with_" state (read: it likely contains bugs but is already usable). + +💡 If you have an idea on how to use Purescript to Lua compilation please contribute it here: +https://github.com/Unisay/purescript-lua/discussions/categories/ideas ## Features -- [x] Lua code bundling: emits either a Lua module or "App". +- [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). - [x] FFI with Lua. - [x] Dead Code Elimination (DCE). - [x] Code inlining. @@ -15,6 +20,12 @@ Status: (2023-07-05) the project is in the "_ready to be experimented with_" sta For the moment the best way to start is to use `nix` to intall `pslua`. +Consider configuring [Cachix](https://docs.cachix.org/installation) as a binary nix cache to avoid rebuilding a ton of dependencies: + +``` +cachix use purescript-lua +``` + Here is an [example](https://github.com/Unisay/purescript-lua-example) project. 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,7 +44,7 @@ Assuming that `pslua` executable is already available on your PATH pslua \ --foreign-path . \ --ps-output output \ - --lua-output-file dist/acme.lua \ + --lua-output-file dist/Acme_Main.lua \ --entry Acme.Main '' } @@ -49,6 +60,14 @@ nix run 'github:Unisay/purescript-lua' -- --help ## Installation +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: + +``` +wget -c https://github.com/Unisay/purescript-lua/releases/download/0.1.1-alpha/pslua-linux_x86_64.tar.gz -O - | tar -xz +``` + +alternatively, + ### Using nix with flakes ``` diff --git a/hie.yaml b/hie.yaml index b016c94..41f3c8e 100644 --- a/hie.yaml +++ b/hie.yaml @@ -2,9 +2,7 @@ cradle: cabal: - path: "exe" component: "pslua:exe:pslua" - - path: "lib" component: "lib:pslua" - - path: "test" component: "pslua:test:spec" diff --git a/lib/Language/PureScript/Backend/IR.hs b/lib/Language/PureScript/Backend/IR.hs index adb9e32..558e461 100644 --- a/lib/Language/PureScript/Backend/IR.hs +++ b/lib/Language/PureScript/Backend/IR.hs @@ -5,27 +5,28 @@ module Language.PureScript.Backend.IR import Control.Monad.Error.Class (MonadError (throwError)) import Control.Monad.Writer.Class (MonadWriter (..)) -import qualified Data.Char as Char +import Data.Char qualified as Char import Data.Foldable (foldrM) -import qualified Data.List as List +import Data.List qualified as List import Data.List.NonEmpty ((<|)) -import qualified Data.List.NonEmpty as NE -import qualified Data.Map.Lazy as Map +import Data.List.NonEmpty qualified as NE +import Data.Map.Lazy qualified as Map import Data.Tagged (Tagged (Tagged)) -import qualified Data.Text as Text +import Data.Text qualified as Text import Data.Traversable (for) import Language.PureScript.Backend.IR.Types -import qualified Language.PureScript.CoreFn as Cfn +import Language.PureScript.CoreFn qualified as Cfn import Language.PureScript.CoreFn.Laziness (applyLazinessTransform) import Language.PureScript.Names (ModuleName) -import qualified Language.PureScript.Names as PS +import Language.PureScript.Names qualified as Names +import Language.PureScript.Names qualified as PS import Language.PureScript.PSString ( PSString , decodeStringEither ) import Numeric (showHex) import Relude.Extra (toFst) -import qualified Relude.Unsafe as Unsafe +import Relude.Unsafe qualified as Unsafe import Prelude hiding (identity) data Context = Context @@ -444,37 +445,29 @@ mkCaseClauses = mkClauses mempty ifThenElse (literalBool b `eq` expr) <$> nextMatch history clause' <*> nextClause history - PatCtor _ty constructor → do - case Map.lookup expr history of - Just (c, True) → - if c == constructor - then -- This constructor matched positively before, - -- proceed matching nested constructors. - nextMatch history clause' - else -- Other constructor matched positively before, - -- this one can't match, proceed to next clause. - nextClause history - Just (c, False) - | c == constructor → - -- This constructor matched negatively before, - -- proceed to the next clause. - nextClause history - _ → do - let qctor = - constructor - & fmap renderCtorName - & literalString - . \case - Local name → name - Imported modname c → - PS.runModuleName modname <> "." <> c - - history' b = Map.insert expr (constructor, b) history - -- Either this constructor is matched for the first time, - -- or other constructor didn't pass the match before. - ifThenElse (qctor `eq` reflectCtor expr) - <$> nextMatch (history' True) clause' - <*> nextClause (history' False) + PatCtor ty ctr → case Map.lookup expr history of + Just (ctr', True) → + if ctr' == ctr + then -- This constructor matched positively before, + -- proceed matching nested constructors. + nextMatch history clause' + else -- Other constructor matched positively before, + -- this one can't match, proceed to next clause. + nextClause history + Just (ctr', False) + | ctr' == ctr → + -- This constructor matched negatively before, + -- proceed to the next clause. + nextClause history + _ → + -- Either this constructor is matched for the first time, + -- or other constructor didn't pass the match before. + ifThenElse + (literalString (ctorId ty ctr) `eq` reflectCtor expr) + <$> nextMatch (history' True) clause' + <*> nextClause (history' False) + where + history' b = Map.insert expr (ctr, b) history where nextMatch hist clause = mkClause hist clause heuristic nextClause @@ -527,7 +520,7 @@ data CaseClause = CaseClause data Pattern = PatAny - | PatCtor (Qualified TyName) (Qualified CtorName) + | PatCtor TyName CtorName | PatInteger Integer | PatFloating Double | PatString Text @@ -577,15 +570,16 @@ mkBinder matchExp = go mempty _ → throwError NewtypeCtorBinderHasUnexpectedNumberOfNestedBinders else do nestedMatches ← - for (zip [0 ..] binders) \(index, binder) → - go (TakeIndex index : stepsToFocus) binder + for (zip [0 ..] binders) \(index ∷ Int, binder) → + let prop = PropName ("value" <> show index) + in go (TakeProp prop : stepsToFocus) binder pure Match { matchExp , matchPat = PatCtor - (mkQualified mkTyName tyName) - (mkQualified mkCtorName ctorName) + (mkTyName (Names.disqualify tyName)) + (mkCtorName (Names.disqualify ctorName)) , stepsToFocus , matchBinds = mempty , nestedMatches @@ -643,7 +637,7 @@ mkBinder matchExp = go mempty , nestedMatches = mempty } -type MatchHistory = Map Exp (Qualified CtorName, Bool) +type MatchHistory = Map Exp (CtorName, Bool) alternativeToClauses ∷ [Exp] → Cfn.CaseAlternative Cfn.Ann → RepM CaseClause diff --git a/lib/Language/PureScript/Backend/IR/DCE.hs b/lib/Language/PureScript/Backend/IR/DCE.hs index c6c5045..39ae031 100644 --- a/lib/Language/PureScript/Backend/IR/DCE.hs +++ b/lib/Language/PureScript/Backend/IR/DCE.hs @@ -19,17 +19,17 @@ import Language.PureScript.Backend.IR.Types , RawExp (..) , RewriteMod (..) , Rewritten (..) - , bindingNames + , annotateExpM + , groupingNames , listGrouping , rewriteExpTopDown ) import Language.PureScript.Names (ModuleName) -import Shower (shower) data EntryPoint = EntryPoint ModuleName [Name] deriving stock (Show) -deriving stock instance Show AExp +-- deriving stock instance Show AExp eliminateDeadCode ∷ UberModule → UberModule eliminateDeadCode uber@UberModule {..} = @@ -71,9 +71,9 @@ eliminateDeadCode uber@UberModule {..} = annotatedBindings ∷ [Grouping (Id, QName, AExp)] (annotatedExports, annotatedBindings) = runAnnM do annExports ← forM uberModuleExports \(name, expr) → - (,name,) <$> nextId <*> annotateExp expr + (,name,) <$> nextId <*> annotateExpWithIds expr annBindings ← forM uberModuleBindings $ traverse \(qname, expr) → - (,qname,) <$> nextId <*> annotateExp expr + (,qname,) <$> nextId <*> annotateExpWithIds expr pure (annExports, annBindings) dceAnnotatedExp ∷ AExp → Exp @@ -201,7 +201,7 @@ eliminateDeadCode uber@UberModule {..} = adjacencyListForExpr scope' body <> snd (foldl' adjacencyListForGrouping (scope, mempty) groupings) where - scope' = foldr addToScope scope (bindingNames =<< toList groupings) + scope' = foldr addToScope scope (groupingNames =<< toList groupings) addToScope (nameId, name) = addLocalToScope nameId name 0 where adjacencyListForGrouping @@ -288,39 +288,9 @@ nextId = AnnM do runAnnM ∷ AnnM a → a runAnnM = (`evalState` 0) . unAnnM -annotateExp ∷ Exp → AnnM AExp -annotateExp = \case - LiteralInt i → pure $ LiteralInt i - LiteralFloat f → pure $ LiteralFloat f - LiteralString s → pure $ LiteralString s - LiteralChar c → pure $ LiteralChar c - LiteralBool b → pure $ LiteralBool b - LiteralArray as → LiteralArray <$> traverse ann as - LiteralObject ps → LiteralObject <$> traverse (traverse ann) ps - ReflectCtor a → ReflectCtor <$> ann a - Eq a b → Eq <$> ann a <*> ann b - DataArgumentByIndex index a → DataArgumentByIndex index <$> ann a - ArrayLength a → ArrayLength <$> ann a - ArrayIndex a index → flip ArrayIndex index <$> ann a - ObjectProp a prop → flip ObjectProp prop <$> ann a - ObjectUpdate a ps → ObjectUpdate <$> ann a <*> traverse (traverse ann) ps - Abs param body → Abs <$> ann_ param <*> ann body - App a b → App <$> ann a <*> ann b - Ref qname index → pure $ Ref qname index - Let binds body → - Let - <$> traverse (traverse (bitraverse ann_ ann)) binds - <*> ann body - IfThenElse i t e → IfThenElse <$> ann i <*> ann t <*> ann e - Ctor aty ty ctor fs → pure $ Ctor aty ty ctor fs - Exception m → pure $ Exception m - ForeignImport m p → pure $ ForeignImport m p - where - ann ∷ Annotated Identity RawExp → AnnM (Id, AExp) - ann = liftA2 (,) nextId . annotateExp . runIdentity - - ann_ ∷ Identity a → AnnM (Id, a) - ann_ p = (,runIdentity p) <$> nextId +annotateExpWithIds ∷ Exp → AnnM (RawExp ((,) Id)) +annotateExpWithIds = + annotateExpM identity (const nextId) (const nextId) (const nextId) deannotateExp ∷ AExp → Exp deannotateExp = \case diff --git a/lib/Language/PureScript/Backend/IR/Linker.hs b/lib/Language/PureScript/Backend/IR/Linker.hs index c3ad9a6..7d74a6d 100644 --- a/lib/Language/PureScript/Backend/IR/Linker.hs +++ b/lib/Language/PureScript/Backend/IR/Linker.hs @@ -13,7 +13,7 @@ import Language.PureScript.Backend.IR.Types , QName (QName) , Qualified (Imported, Local) , RawExp (..) - , bindingNames + , groupingNames , objectProp , ref , refImported @@ -92,7 +92,7 @@ qualifiedModuleBindings Module {moduleName, moduleBindings, moduleForeigns} = qualifyBinding = bimap (QName moduleName) (qualifyTopRefs moduleName topRefs) where topRefs ∷ Map Name Index = Map.fromList do - (,0) <$> ((moduleBindings >>= bindingNames) <> moduleForeigns) + (,0) <$> ((moduleBindings >>= groupingNames) <> moduleForeigns) qualifyTopRefs ∷ ModuleName → Map Name Index → Exp → Exp qualifyTopRefs moduleName = go @@ -127,7 +127,7 @@ qualifyTopRefs moduleName = go qualifyBody = go topNames' where topNames' = foldr (Map.adjust (+ 1) . unAnn) topNames boundNames - boundNames = toList groupings >>= bindingNames + boundNames = toList groupings >>= groupingNames App argument function → App (go' <$> argument) (go' <$> function) LiteralArray as → LiteralArray (go' <<$>> as) LiteralObject props → LiteralObject (fmap go' <<$>> props) diff --git a/lib/Language/PureScript/Backend/IR/Optimizer.hs b/lib/Language/PureScript/Backend/IR/Optimizer.hs index 3b47c3c..f2f7d9f 100644 --- a/lib/Language/PureScript/Backend/IR/Optimizer.hs +++ b/lib/Language/PureScript/Backend/IR/Optimizer.hs @@ -1,8 +1,11 @@ module Language.PureScript.Backend.IR.Optimizer where +import Data.List.NonEmpty qualified as NE import Data.Map qualified as Map +import Data.Set qualified as Set import Language.PureScript.Backend.IR.DCE qualified as DCE import Language.PureScript.Backend.IR.Linker (UberModule (..)) +import Language.PureScript.Backend.IR.Query (collectBoundNames) import Language.PureScript.Backend.IR.Types ( Annotated , Exp @@ -25,9 +28,131 @@ import Language.PureScript.Backend.IR.Types , thenRewrite , unAnn ) +import Language.PureScript.Backend.IR.Types qualified as IR optimizedUberModule ∷ UberModule → UberModule -optimizedUberModule = idempotently $ DCE.eliminateDeadCode . optimizeModule +optimizedUberModule = + renameShadowedNames . idempotently (DCE.eliminateDeadCode . optimizeModule) + +renameShadowedNames ∷ UberModule → UberModule +renameShadowedNames UberModule {..} = + UberModule + { uberModuleBindings = uberModuleBindings' + , uberModuleExports = uberModuleExports' + } + where + uberModuleBindings' ∷ [Grouping (QName, Exp)] = uberModuleBindings + uberModuleExports' ∷ [(Name, Exp)] = + renameShadowedNamesInExpr mempty <<$>> uberModuleExports + +type RenamesInScope = Map Name [Name] + +renameShadowedNamesInExpr ∷ RenamesInScope → RawExp Identity → RawExp Identity +renameShadowedNamesInExpr scope = go + where + go = \case + IR.LiteralInt i → + IR.LiteralInt i + IR.LiteralFloat f → + IR.LiteralFloat f + IR.LiteralString s → + IR.LiteralString s + IR.LiteralChar c → + IR.LiteralChar c + IR.LiteralBool b → + IR.LiteralBool b + IR.LiteralArray as → + IR.LiteralArray (go <<$>> as) + IR.LiteralObject ps → + IR.LiteralObject ((go <$>) <<$>> ps) + IR.ReflectCtor a → + IR.ReflectCtor (go <$> a) + IR.Eq a b → + IR.Eq (go <$> a) (go <$> b) + IR.DataArgumentByIndex index a → + IR.DataArgumentByIndex index (go <$> a) + IR.ArrayLength a → + IR.ArrayLength (go <$> a) + IR.ArrayIndex a index → + IR.ArrayIndex (go <$> a) index + IR.ObjectProp a prop → + IR.ObjectProp (go <$> a) prop + IR.ObjectUpdate a ps → + IR.ObjectUpdate (go <$> a) ((go <$>) <<$>> ps) + IR.Abs param body → + IR.Abs param' (renameShadowedNamesInExpr scope' <$> body) + where + (param', scope') = + case IR.unAnn param of + IR.ParamUnused → + (param, scope) + IR.ParamNamed name → + first + (pure . IR.ParamNamed) + (withScopedName (IR.unAnn body) scope name) + IR.App a b → + IR.App (go <$> a) (go <$> b) + IR.Ref qname index → + case qname of + IR.Local lname + | Just renames ← Map.lookup lname scope + , Just rename ← renames !!? fromIntegral (IR.unIndex index) → + IR.Ref (IR.Local rename) 0 + _ → IR.Ref qname index + IR.Let binds body → + IR.Let (NE.fromList (reverse binds')) body' + where + scope' ∷ RenamesInScope + binds' ∷ [Grouping (Identity Name, Identity Exp)] + (scope', binds') = foldl' f (scope, []) (toList binds) + f + ∷ (RenamesInScope, [Grouping (Identity Name, Identity Exp)]) + → Grouping (Identity Name, Identity Exp) + → (RenamesInScope, [Grouping (Identity Name, Identity Exp)]) + f (sc, bs) = \case + Standalone (IR.unAnn → name, expr) → + withScopedName (IR.unAnn expr) sc name & \(name', sc') → + let expr' = renameShadowedNamesInExpr sc <$> expr + in (sc', Standalone (pure name', expr') : bs) + RecursiveGroup (toList → recGroup) → + (: bs) . RecursiveGroup . NE.fromList <$> foldl' g (sc, []) recGroup + where + g + ∷ (RenamesInScope, [(Identity Name, Identity Exp)]) + → (Identity Name, Identity Exp) + → (RenamesInScope, [(Identity Name, Identity Exp)]) + g (sc', recBinds) (IR.unAnn → name, expr) = + withScopedName (IR.unAnn expr) sc' name & \(name', sc'') → + let expr' = renameShadowedNamesInExpr sc' <$> expr + in (sc'', (pure name', expr') : recBinds) + body' = renameShadowedNamesInExpr scope' <$> body + IR.IfThenElse i t e → + IR.IfThenElse (go <$> i) (go <$> t) (go <$> e) + IR.Ctor aty ty ctr fs → + IR.Ctor aty ty ctr fs + IR.Exception m → + IR.Exception m + IR.ForeignImport m p → + IR.ForeignImport m p + where + withScopedName ∷ Exp → Map Name [Name] → Name → (Name, Map Name [Name]) + withScopedName e sc name = case Map.lookup name sc of + Nothing → (name, Map.insert name [name] sc) + Just renames → + ( rename + , Map.insert rename [] $ Map.insert name (rename : renames) sc + ) + where + nextIndex = length renames + usedNames = Map.keysSet sc <> collectBoundNames e + rename = uniqueName usedNames name nextIndex + + uniqueName ∷ Set Name → Name → Int → Name + uniqueName usedNames n i = + let nextName = Name (nameToText n <> show i) + in if Set.member nextName usedNames + then uniqueName usedNames n (i + 1) + else nextName idempotently ∷ Eq a ⇒ (a → a) → a → a idempotently = fix $ \i f a → @@ -43,7 +168,6 @@ optimizeModule UberModule {..} = UberModule { uberModuleBindings = uberModuleBindings' , uberModuleExports = uberModuleExports' - , .. } where (uberModuleBindings', uberModuleExports') = diff --git a/lib/Language/PureScript/Backend/IR/Query.hs b/lib/Language/PureScript/Backend/IR/Query.hs index 6cf5799..18da18e 100644 --- a/lib/Language/PureScript/Backend/IR/Query.hs +++ b/lib/Language/PureScript/Backend/IR/Query.hs @@ -1,6 +1,8 @@ module Language.PureScript.Backend.IR.Query where +import Control.Monad.Trans.Accum (Accum, add, execAccum) import Data.Map qualified as Map +import Data.Set qualified as Set import Language.PureScript.Backend.IR.Linker (UberModule (..)) import Language.PureScript.Backend.IR.Types ( Exp @@ -8,8 +10,11 @@ import Language.PureScript.Backend.IR.Types , Qualified (..) , countFreeRef , countFreeRefs + , groupingNames , listGrouping + , traverseExpBottomUp ) +import Language.PureScript.Backend.IR.Types qualified as IR import Language.PureScript.Names (runModuleName) usesRuntimeLazy ∷ UberModule → Bool @@ -37,3 +42,18 @@ findPrimModuleInExpr expr = Map.keys (countFreeRefs expr) & any \case Local _name → False Imported moduleName _name → runModuleName moduleName == "Prim" + +collectBoundNames ∷ Exp → Set Name +collectBoundNames = + (`execAccum` Set.empty) . traverseExpBottomUp @_ @(Accum (Set Name)) \e → + case e of + IR.Abs (IR.unAnn → IR.ParamNamed name) _body → + e <$ add (Set.singleton name) + IR.Let groupings _body → + e <$ add do + Set.fromList + [ IR.unAnn iname + | grouping ← toList groupings + , iname ← groupingNames grouping + ] + _ → pure e diff --git a/lib/Language/PureScript/Backend/IR/Types.hs b/lib/Language/PureScript/Backend/IR/Types.hs index a72d598..188dc87 100644 --- a/lib/Language/PureScript/Backend/IR/Types.hs +++ b/lib/Language/PureScript/Backend/IR/Types.hs @@ -32,8 +32,8 @@ listGrouping = \case Standalone a → [a] RecursiveGroup as → toList as -bindingNames ∷ Grouping (name, exp) → [name] -bindingNames = fmap fst . listGrouping +groupingNames ∷ Grouping (name, exp) → [name] +groupingNames = fmap fst . listGrouping bindingExprs ∷ Grouping (name, Exp) → [Exp] bindingExprs = fmap snd . listGrouping @@ -112,6 +112,9 @@ isRecursiveLiteral = \case data AlgebraicType = SumType | ProductType deriving stock (Generic, Eq, Ord, Show, Enum, Bounded) +ctorId ∷ TyName → CtorName → Text +ctorId tyName ctorName = renderTyName tyName <> "." <> renderCtorName ctorName + -------------------------------------------------------------------------------- -- Names ----------------------------------------------------------------------- @@ -187,7 +190,8 @@ abstraction p e = Abs (pure p) (pure e) identity ∷ Exp identity = abstraction (ParamNamed name) (refLocal name 0) where name = Name "x" -lets ∷ Applicative n ⇒ NonEmpty (Grouping (Name, RawExp n)) → RawExp n → RawExp n +lets + ∷ Applicative n ⇒ NonEmpty (Grouping (Name, RawExp n)) → RawExp n → RawExp n lets binds body = Let (bimap pure pure <<$>> binds) (pure body) application ∷ Applicative n ⇒ RawExp n → RawExp n → RawExp n @@ -281,12 +285,57 @@ literalObject ps = LiteralObject (pure <<$>> ps) -------------------------------------------------------------------------------- -- Traversals ------------------------------------------------------------------ +annotateExpM + ∷ ∀ b m + . Applicative m + ⇒ (∀ x. m x → m x) + → (RawExp Identity → m b) + → (Parameter → m b) + → (Name → m b) + → (RawExp Identity → m (RawExp ((,) b))) +annotateExpM around annotateExp annotateParam annotateName = + around . \case + LiteralInt i → pure $ LiteralInt i + LiteralFloat f → pure $ LiteralFloat f + LiteralString s → pure $ LiteralString s + LiteralChar c → pure $ LiteralChar c + LiteralBool b → pure $ LiteralBool b + LiteralArray as → LiteralArray <$> traverse ann as + LiteralObject ps → LiteralObject <$> traverse (traverse ann) ps + ReflectCtor a → ReflectCtor <$> ann a + Eq a b → Eq <$> ann a <*> ann b + DataArgumentByIndex index a → DataArgumentByIndex index <$> ann a + ArrayLength a → ArrayLength <$> ann a + ArrayIndex a index → flip ArrayIndex index <$> ann a + ObjectProp a prop → flip ObjectProp prop <$> ann a + ObjectUpdate a ps → ObjectUpdate <$> ann a <*> traverse (traverse ann) ps + Abs param body → Abs <$> annParam param <*> ann body + App a b → App <$> ann a <*> ann b + Ref qname index → pure $ Ref qname index + Let binds body → + Let <$> traverse (traverse (bitraverse annLetName ann)) binds <*> ann body + IfThenElse i t e → IfThenElse <$> ann i <*> ann t <*> ann e + Ctor aty ty ctr fs → pure $ Ctor aty ty ctr fs + Exception m → pure $ Exception m + ForeignImport m p → pure $ ForeignImport m p + where + ann ∷ Identity (RawExp Identity) → m (b, RawExp ((,) b)) + ann (unAnn → expr) = + (,) + <$> annotateExp expr + <*> annotateExpM around annotateExp annotateParam annotateName expr + + annParam ∷ Identity Parameter → m (b, Parameter) + annParam (unAnn → param) = (,param) <$> annotateParam param + + annLetName ∷ Identity Name → m (b, Name) + annLetName (unAnn → name) = (,name) <$> annotateName name + traverseExpBottomUp ∷ ∀ n m . (Monad m, Traversable n) ⇒ (RawExp n → m (RawExp n)) - → RawExp n - → m (RawExp n) + → (RawExp n → m (RawExp n)) traverseExpBottomUp visit = go where go ∷ RawExp n → m (RawExp n) @@ -436,7 +485,7 @@ countFreeRefs = fmap getSum . MMap.toMap . countFreeRefs' mempty where minIndexes' = foldr (\name → Map.insertWith (+) name 1) minIndexes $ - toList binds >>= fmap (Local . runIdentity) . bindingNames + toList binds >>= fmap (Local . runIdentity) . groupingNames countsInBinds = toList binds >>= \case Standalone (unAnn → boundName, expr) → @@ -548,7 +597,7 @@ substitute name idx replacement = substitute' idx boundNames = runIdentity . fst <$> grouping body' = substitute name index' replacement' <$> body where - boundNames = toList binds >>= fmap runIdentity . bindingNames + boundNames = toList binds >>= fmap runIdentity . groupingNames index' = if name `elem` fmap Local boundNames then index + 1 else index replacement' = foldr (\n r → shift 1 n 0 r) replacement boundNames App argument function → App (go <$> argument) (go <$> function) @@ -619,7 +668,7 @@ shift offset namespace minIndex expression = | otherwise = minIndex body' = shift offset namespace minIndex' <$> body where - boundNames' = toList binds >>= fmap unAnn . bindingNames + boundNames' = toList binds >>= fmap unAnn . groupingNames minIndex' | namespace `elem` boundNames' = minIndex + 1 | otherwise = minIndex diff --git a/lib/Language/PureScript/Backend/Lua.hs b/lib/Language/PureScript/Backend/Lua.hs index 18ee140..7c5df5b 100644 --- a/lib/Language/PureScript/Backend/Lua.hs +++ b/lib/Language/PureScript/Backend/Lua.hs @@ -10,6 +10,7 @@ module Language.PureScript.Backend.Lua import Control.Monad (ap) import Control.Monad.Oops (CouldBe, Variant) import Control.Monad.Oops qualified as Oops +import Control.Monad.Trans.Accum (AccumT, add, runAccumT) import Data.DList qualified as DList import Data.List qualified as List import Data.Set qualified as Set @@ -32,7 +33,19 @@ import Language.PureScript.Names qualified as PS import Path (Abs, Dir, Path, toFilePath) import Prelude hiding (exp, local) -type LuaM e a = StateT Natural (ExceptT (Variant e) IO) a +type LuaM e a = + AccumT UsesObjectUpdate (StateT Natural (ExceptT (Variant e) IO)) a + +data UsesObjectUpdate = NoObjectUpdate | UsesObjectUpdate + deriving stock (Eq, Ord, Show) + +instance Semigroup UsesObjectUpdate where + _ <> UsesObjectUpdate = UsesObjectUpdate + UsesObjectUpdate <> _ = UsesObjectUpdate + NoObjectUpdate <> NoObjectUpdate = NoObjectUpdate + +instance Monoid UsesObjectUpdate where + mempty = NoObjectUpdate data Error = UnexpectedRefBound ModuleName IR.Exp @@ -49,41 +62,42 @@ fromUberModule → Linker.UberModule → ExceptT (Variant e) IO Lua.Chunk fromUberModule foreigns needsRuntimeLazy appOrModule uber = (`evalStateT` 0) do - bindings ← - Linker.uberModuleBindings uber & foldMapM \case - IR.Standalone (IR.QName modname name, irExp) → do - exp ← fromExp foreigns Set.empty modname irExp - pure $ DList.singleton (Lua.local1 (fromQName modname name) exp) - IR.RecursiveGroup recGroup → do - recBinds ← forM (toList recGroup) \(IR.QName modname name, irExp) → - (fromQName modname name,) <$> fromExp foreigns Set.empty modname irExp - let declarations = Lua.local0 . fst <$> DList.fromList recBinds - assignments = DList.fromList do - recBinds <&> \(name, exp) → Lua.assign (Lua.VarName name) exp - pure $ declarations <> assignments - - returnExp ← - case appOrModule of - AsModule modname → - Lua.table <$> do - forM (uberModuleExports uber) \(fromName → name, expr) → - Lua.tableRowNV name <$> fromExp foreigns mempty modname expr - AsApplication modname ident → do - case List.lookup name (uberModuleExports uber) of - Just expr → do - entry ← fromExp foreigns mempty modname expr - pure $ Lua.functionCall entry [] - _ → Oops.throw $ AppEntryPointNotFound modname ident - where - name = IR.identToName ident + (chunk, usesObjectUpdate) ← (`runAccumT` NoObjectUpdate) do + bindings ← + Linker.uberModuleBindings uber & foldMapM \case + IR.Standalone (IR.QName modname name, irExp) → do + exp ← fromExp foreigns Set.empty modname irExp + pure $ DList.singleton (Lua.local1 (fromQName modname name) exp) + IR.RecursiveGroup recGroup → do + recBinds ← forM (toList recGroup) \(IR.QName modname name, irExp) → + (fromQName modname name,) <$> fromExp foreigns Set.empty modname irExp + let declarations = Lua.local0 . fst <$> DList.fromList recBinds + assignments = DList.fromList do + recBinds <&> \(name, exp) → Lua.assign (Lua.VarName name) exp + pure $ declarations <> assignments + + returnExp ← + case appOrModule of + AsModule modname → + Lua.table <$> do + forM (uberModuleExports uber) \(fromName → name, expr) → + Lua.tableRowNV name <$> fromExp foreigns mempty modname expr + AsApplication modname ident → do + case List.lookup name (uberModuleExports uber) of + Just expr → do + entry ← fromExp foreigns mempty modname expr + pure $ Lua.functionCall entry [] + _ → Oops.throw $ AppEntryPointNotFound modname ident + where + name = IR.identToName ident + + pure $ DList.snoc bindings (Lua.Return (Lua.ann returnExp)) pure . mconcat $ - [ if usesPrimModule uber then [Fixture.prim] else empty - , if untag needsRuntimeLazy && usesRuntimeLazy uber - then pure Fixture.runtimeLazy - else empty - , DList.toList bindings - , [Lua.Return (Lua.ann returnExp)] + [ [Fixture.prim | usesPrimModule uber] + , [Fixture.runtimeLazy | untag needsRuntimeLazy && usesRuntimeLazy uber] + , [Fixture.objectUpdate | UsesObjectUpdate ← [usesObjectUpdate]] + , DList.toList chunk ] fromQName ∷ ModuleName → IR.Name → Lua.Name @@ -92,6 +106,12 @@ fromQName modname name = qualifyName modname (fromName name) fromName ∷ HasCallStack ⇒ IR.Name → Lua.Name fromName = Name.makeSafe . IR.nameToText +fromNameWithIndex ∷ HasCallStack ⇒ IR.Name → IR.Index → Lua.Name +fromNameWithIndex name (IR.unIndex → index) = + if index == 0 + then fromName name + else Name.makeSafe $ IR.nameToText name <> show index + fromModuleName ∷ ModuleName → Lua.Name fromModuleName = Name.makeSafe . runModuleName @@ -124,20 +144,17 @@ fromExp foreigns topLevelNames modname ir = case ir of Lua.table <$> for kvs \(prop, exp) → Lua.tableRowNV (fromPropName prop) <$> go (IR.unAnn exp) IR.ReflectCtor e → - flip Lua.varIndex keyCtor <$> go (IR.unAnn e) + (`Lua.varIndex` keyCtor) <$> go (IR.unAnn e) IR.DataArgumentByIndex i e → - flip Lua.varIndex (Lua.Integer (fromIntegral i)) <$> go (IR.unAnn e) + (`Lua.varField` Lua.unsafeName ("value" <> show i)) <$> go (IR.unAnn e) IR.Eq l r → Lua.equalTo <$> go (IR.unAnn l) <*> go (IR.unAnn r) - IR.Ctor _algebraicTy _tyName ctorName fieldNames → - pure $ Lua.functionDef (ParamNamed <$> args) [Lua.return value] + IR.Ctor _algebraicTy tyName ctorName fieldNames → + pure $ foldr wrap value args where + wrap name expr = Lua.functionDef [ParamNamed name] [Lua.return expr] value = Lua.table $ ctorRow : attributes - ctorValue = - Name.toText (fromModuleName modname) - <> "." - <> IR.renderCtorName ctorName - ctorRow = Lua.tableRowKV keyCtor (Lua.String ctorValue) + ctorRow = Lua.tableRowKV keyCtor (Lua.String (IR.ctorId tyName ctorName)) args = Name.unsafeName . IR.renderFieldName <$> fieldNames attributes = args <&> ap Lua.tableRowNV Lua.varName IR.ArrayLength e → @@ -146,31 +163,33 @@ fromExp foreigns topLevelNames modname ir = case ir of flip Lua.varIndex (Lua.Integer (fromIntegral index)) <$> go (IR.unAnn expr) IR.ObjectProp expr propName → flip Lua.varField (fromPropName propName) <$> go (IR.unAnn expr) - IR.ObjectUpdate _expr _patches → - Prelude.error "fromObjectUpdate is not implemented" + IR.ObjectUpdate expr propValues → do + add UsesObjectUpdate + obj ← go (IR.unAnn expr) + vals ← + Lua.table <$> for (toList propValues) \(propName, IR.unAnn → e) → + Lua.tableRowNV (fromPropName propName) <$> go e + pure $ Lua.functionCall (Lua.varName Fixture.objectUpdateName) [obj, vals] IR.Abs param expr → do e ← go $ IR.unAnn expr luaParam ← Lua.ParamNamed <$> case IR.unAnn param of - IR.ParamUnused → do - index ← get - modify' (+ 1) - pure $ Lua.unsafeName ("unused" <> show index) + IR.ParamUnused → uniqueName "unused" IR.ParamNamed name → pure (fromName name) pure $ Lua.functionDef [luaParam] [Lua.return e] IR.App expr param → do e ← go $ IR.unAnn expr a ← go $ IR.unAnn param pure $ Lua.functionCall e [a] - IR.Ref qualifiedName _index → + IR.Ref qualifiedName index → pure case qualifiedName of IR.Local name | topLevelName ← fromQName modname name , Set.member topLevelName topLevelNames → Lua.varName topLevelName IR.Local name → - Lua.varName (fromName name) + Lua.varName (fromNameWithIndex name index) IR.Imported modname' name → Lua.varName (fromQName modname' name) IR.Let bindings bodyExp → do @@ -224,5 +243,11 @@ fromIfThenElse cond thenExp elseExp = Lua.functionCall fun [] -------------------------------------------------------------------------------- -- Helpers --------------------------------------------------------------------- +uniqueName ∷ MonadState Natural m ⇒ Text → m Lua.Name +uniqueName prefix = do + index ← get + modify' (+ 1) + pure $ Lua.unsafeName (prefix <> show index) + qualifyName ∷ ModuleName → Lua.Name → Lua.Name qualifyName modname = Name.join2 (fromModuleName modname) diff --git a/lib/Language/PureScript/Backend/Lua/Fixture.hs b/lib/Language/PureScript/Backend/Lua/Fixture.hs index 9edd013..b9946e1 100644 --- a/lib/Language/PureScript/Backend/Lua/Fixture.hs +++ b/lib/Language/PureScript/Backend/Lua/Fixture.hs @@ -2,6 +2,7 @@ module Language.PureScript.Backend.Lua.Fixture where +import Data.String.Interpolate (__i) import Language.PureScript.Backend.Lua.Name (Name, name) import Language.PureScript.Backend.Lua.Name qualified as Name import Language.PureScript.Backend.Lua.Types hiding (var) @@ -12,39 +13,52 @@ import Language.PureScript.Backend.Lua.Types hiding (var) prim ∷ Statement prim = local1 (Name.join2 [name|Prim|] [name|undefined|]) Nil +runtimeLazyName ∷ Name +runtimeLazyName = [name|_S___runtime_lazy|] + runtimeLazy ∷ Statement -runtimeLazy = local1 [name|_S___runtime_lazy|] do - let fun ∷ Name → [Statement] → Exp - fun n = Function [((), ParamNamed n)] . fmap ann - var ∷ Name → Var - var = VarName - ret ∷ Exp → Statement - ret = Return . ann - fun [name|name|] . pure . ret . fun [name|init|] $ - [ local1 [name|state|] (Integer 0) - , local1 [name|val|] Nil - , ret . functionDef [] $ - [ ifThenElse - (varName [name|state|] `equalTo` Integer 2) - [ret (varName [name|val|])] - [ ifThenElse - (varName [name|state|] `equalTo` Integer 1) - ( pure . ret $ - functionCall - (varName [name|error|]) - [ binOp - Concat - (varName [name|name|]) - ( String - " was needed before it finished initializing" - ) - ] - ) - [ var [name|state|] `assign` Integer 1 - , var [name|val|] `assign` functionCall (varName [name|init|]) [] - , var [name|state|] `assign` Integer 2 - , ret (varName [name|val|]) - ] - ] - ] - ] +runtimeLazy = + ForeignSourceCode + [__i| + local function #{Name.toText runtimeLazyName}(name) + return function(init) + return function() + local state = 0 + local val = nil + if state == 2 then + return val + else + if state == 1 then + return error(name .. " was needed before it finished initializing") + else + state = 1 + val = init() + state = 2 + return val + end + end + end + end + end + |] + +objectUpdateName ∷ Name +objectUpdateName = [name|_S___object_update|] + +objectUpdate ∷ Statement +objectUpdate = + ForeignSourceCode + [__i| + local function #{Name.toText objectUpdateName}(o, patches) + local o_copy = {} + for k, v in pairs(o) do + local patch_v = patches + if patch_v ~= nil then + o_copy[k] = patch_v + else + o_copy[k] = v + end + end + return o_copy + end + |] diff --git a/lib/Language/PureScript/Backend/Lua/Optimizer.hs b/lib/Language/PureScript/Backend/Lua/Optimizer.hs index db09b26..7362984 100644 --- a/lib/Language/PureScript/Backend/Lua/Optimizer.hs +++ b/lib/Language/PureScript/Backend/Lua/Optimizer.hs @@ -25,21 +25,7 @@ import Language.PureScript.Backend.Lua.Types qualified as Lua import Prelude hiding (return) optimizeChunk ∷ Chunk → Chunk -optimizeChunk = fmap optimizeStatement >>> inlineTopLevelLocalDefs - -inlineTopLevelLocalDefs ∷ Chunk → Chunk -inlineTopLevelLocalDefs = snd . foldr inlineTopLevelLocalDef mempty - where - inlineTopLevelLocalDef - ∷ Statement - → (Map Lua.Name (Sum Natural), Chunk) - → (Map Lua.Name (Sum Natural), Chunk) - inlineTopLevelLocalDef statement (counts, result) = - case statement of - Local name (Just value) - | Just (Sum 1) ← Map.lookup name counts → - (counts, substituteVarForValue name (Lua.unAnn value) result) - other → (countRefs other <> counts, other : result) +optimizeChunk = fmap optimizeStatement substituteVarForValue ∷ Lua.Name → Exp → Chunk → Chunk substituteVarForValue name inlinee = diff --git a/lib/Language/PureScript/Backend/Lua/Traversal.hs b/lib/Language/PureScript/Backend/Lua/Traversal.hs index 5c03467..38dbf64 100644 --- a/lib/Language/PureScript/Backend/Lua/Traversal.hs +++ b/lib/Language/PureScript/Backend/Lua/Traversal.hs @@ -40,7 +40,7 @@ everywhereExpM f g = goe tableRows ← forM rows \case TableRowKV (Ann k) (Ann v) → tableRowKV <$> goe k <*> goe v TableRowNV n (Ann e) → tableRowNV n <$> goe e - f $ tableCtor tableRows + f $ table tableRows UnOp op (Ann e) → f . unOp op =<< goe e BinOp op (Ann e1) (Ann e2) → diff --git a/lib/Language/PureScript/Backend/Lua/Types.hs b/lib/Language/PureScript/Backend/Lua/Types.hs index db90973..0e357aa 100644 --- a/lib/Language/PureScript/Backend/Lua/Types.hs +++ b/lib/Language/PureScript/Backend/Lua/Types.hs @@ -272,9 +272,6 @@ functionDef params body = Function (ann <$> params) (ann <$> body) functionCall ∷ Exp → [Exp] → Exp functionCall f args = FunctionCall (ann f) (ann <$> args) -tableCtor ∷ [TableRow] → Exp -tableCtor = TableCtor . fmap ann - unOp ∷ UnaryOp → Exp → Exp unOp op e = UnOp op (ann e) diff --git a/lib/Language/PureScript/CoreFn/Expr.hs b/lib/Language/PureScript/CoreFn/Expr.hs index 8bf6c38..b6cd2e6 100644 --- a/lib/Language/PureScript/CoreFn/Expr.hs +++ b/lib/Language/PureScript/CoreFn/Expr.hs @@ -11,32 +11,23 @@ import Language.PureScript.PSString (PSString) Data type for expressions and terms -} data Expr a - = -- | - -- A literal value + = -- A literal value Literal a (Literal (Expr a)) - | -- | - -- A data constructor (type name, constructor name, field names) + | -- A data constructor (type name, constructor name, field names) Constructor a (ProperName 'TypeName) (ProperName 'ConstructorName) [Ident] - | -- | - -- A record property accessor + | -- A record property accessor Accessor a PSString (Expr a) - | -- | - -- Partial record update + | -- Partial record update ObjectUpdate a (Expr a) [(PSString, Expr a)] - | -- | - -- Function introduction + | -- Function introduction Abs a Ident (Expr a) - | -- | - -- Function application + | -- Function application App a (Expr a) (Expr a) - | -- | - -- Variable + | -- Variable Var a (Qualified Ident) - | -- | - -- A case expression + | -- A case expression Case a [Expr a] [CaseAlternative a] - | -- | - -- A let binding + | -- A let binding Let a [Bind a] (Expr a) deriving stock (Eq, Ord, Show, Functor) diff --git a/lib/Language/PureScript/CoreFn/FromJSON.hs b/lib/Language/PureScript/CoreFn/FromJSON.hs index e8aeaf6..c7491e6 100644 --- a/lib/Language/PureScript/CoreFn/FromJSON.hs +++ b/lib/Language/PureScript/CoreFn/FromJSON.hs @@ -258,7 +258,8 @@ exprFromJSON modulePath = withObject "Expr" exprFromObj caseFromObj o = do ann ← o .: "annotation" >>= annFromJSON modulePath cs ← o .: "caseExpressions" >>= listParser (exprFromJSON modulePath) - cas ← o .: "caseAlternatives" >>= listParser (caseAlternativeFromJSON modulePath) + cas ← + o .: "caseAlternatives" >>= listParser (caseAlternativeFromJSON modulePath) return $ Case ann cs cas letFromObj o = do diff --git a/lib/Language/PureScript/CoreFn/Laziness.hs b/lib/Language/PureScript/CoreFn/Laziness.hs index 0bd4024..e2fcbcd 100644 --- a/lib/Language/PureScript/CoreFn/Laziness.hs +++ b/lib/Language/PureScript/CoreFn/Laziness.hs @@ -419,7 +419,9 @@ searchReachable maxIdx lookupEdges = mrtFlatten . Unsafe.head <$> mem mem = A.listArray (0, maxIdx) - [ [cutLoops <*> fmap (IM.mapWithKey memoizedNode) . lookupEdges $ (i, f) | f ← [toEnum 0 ..]] + [ [ cutLoops <*> fmap (IM.mapWithKey memoizedNode) . lookupEdges $ (i, f) + | f ← [toEnum 0 ..] + ] | i ← [0 .. maxIdx] ] diff --git a/lib/Language/PureScript/Names.hs b/lib/Language/PureScript/Names.hs index da9a2a2..0db9064 100644 --- a/lib/Language/PureScript/Names.hs +++ b/lib/Language/PureScript/Names.hs @@ -262,5 +262,8 @@ instance ToJSONKey ModuleName where instance FromJSONKey ModuleName where fromJSONKey = fmap moduleNameFromString fromJSONKey -$(deriveJSON (defaultOptions {sumEncoding = ObjectWithSingleField}) ''InternalIdentData) +$( deriveJSON + (defaultOptions {sumEncoding = ObjectWithSingleField}) + ''InternalIdentData + ) $(deriveJSON (defaultOptions {sumEncoding = ObjectWithSingleField}) ''Ident) diff --git a/nix/hix.nix b/nix/hix.nix index cb773ac..425a9fb 100644 --- a/nix/hix.nix +++ b/nix/hix.nix @@ -40,6 +40,8 @@ purescript spago treefmt + upx + yamlfmt ]; }; } diff --git a/pslua.cabal b/pslua.cabal index de94ba4..c918fd4 100644 --- a/pslua.cabal +++ b/pslua.cabal @@ -97,6 +97,7 @@ common shared , relude ^>=1.2 , scientific ^>=0.3.7.0 , shower ^>=0.2.0.3 + , string-interpolate ^>=0.3.2.1 , tagged ^>=0.8.6.1 , template-haskell ^>=2.18 , text ^>=1.2.5.0 diff --git a/scripts/prepare_release b/scripts/prepare_release new file mode 100755 index 0000000..65d171a --- /dev/null +++ b/scripts/prepare_release @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +set -euxo pipefail + +nix build '.#static' +mkdir -p dist +rm -f -- dist/pslua-linux_x86_64.tar.gz +rm -f -- dist/pslua +upx --best ./result/bin/pslua -o ./dist/pslua +rm -rf ./result +tar -czcf dist/pslua-linux_x86_64.tar.gz -C ./dist pslua diff --git a/test/Language/PureScript/Backend/IR/OptimizerSpec.hs b/test/Language/PureScript/Backend/IR/OptimizerSpec.hs index 1ea6ae3..8849a44 100644 --- a/test/Language/PureScript/Backend/IR/OptimizerSpec.hs +++ b/test/Language/PureScript/Backend/IR/OptimizerSpec.hs @@ -9,13 +9,16 @@ import Language.PureScript.Backend.IR.Linker qualified as Linker import Language.PureScript.Backend.IR.Optimizer ( optimizedExpression , optimizedUberModule + , renameShadowedNamesInExpr ) import Language.PureScript.Backend.IR.Types ( Exp , Grouping (Standalone) , Module (..) , Name (..) + , Parameter (..) , RawExp (..) + , abstraction , application , eq , ifThenElse @@ -23,6 +26,7 @@ import Language.PureScript.Backend.IR.Types , lets , literalBool , literalInt + , refLocal , refLocal0 ) import Language.PureScript.Names (moduleNameFromString) @@ -63,8 +67,8 @@ spec = describe "IR Optimizer" do test "inlines expressions referenced once" do name ← forAll Gen.name - inlinee ← - forAll $ mfilter (\e → not (isRef e || isLiteral e)) Gen.exp + inlinee ← forAll $ fmap optimizedExpression do + mfilter (\e → not (isRef e || isLiteral e)) Gen.exp let body = refLocal0 name original = let1 name inlinee body expected = let1 name inlinee inlinee @@ -102,6 +106,92 @@ spec = describe "IR Optimizer" do annotateShow expected optimizedUberModule original === expected + describe "renames shadowed names" do + test "nested λ-abstractions" do + name ← forAll Gen.name + let + name1 = Name $ nameToText name <> "1" + name2 = Name $ nameToText name <> "2" + name3 = Name $ nameToText name <> "3" + + let original = + abstraction + (ParamNamed name) + ( abstraction + (ParamNamed name) + ( application + (refLocal name 0) + ( abstraction + (ParamNamed name) + ( abstraction + (ParamNamed name1) + ( application + (refLocal name 0) + (refLocal name 2) + ) + ) + ) + ) + ) + + renamed = + abstraction + (ParamNamed name) + ( abstraction + (ParamNamed name2) + ( application + (refLocal name2 0) + ( abstraction + (ParamNamed name3) + ( abstraction + (ParamNamed name1) + ( application + (refLocal name3 0) + (refLocal name 0) + ) + ) + ) + ) + ) + renameShadowedNamesInExpr mempty original === renamed + + test "nested let-bindings" do + nameA ← forAll Gen.name + nameB ← forAll $ mfilter (/= nameA) Gen.name + valueA ← forAll Gen.literalNonRecursiveExp + valueB ← forAll Gen.literalNonRecursiveExp + let original = + lets + (Standalone (nameA, valueA) :| [Standalone (nameB, valueB)]) + ( lets + ( Standalone (nameA, refLocal nameA 0) + :| [Standalone (nameB, refLocal nameB 0)] + ) + ( application + (application (refLocal nameA 0) (refLocal nameA 1)) + (application (refLocal nameB 0) (refLocal nameB 1)) + ) + ) + + nameA1 = Name $ nameToText nameA <> "1" + nameB1 = Name $ nameToText nameB <> "1" + + renamed = + lets + ( Standalone (nameA, valueA) + :| [Standalone (nameB, valueB)] + ) + ( lets + ( Standalone (nameA1, refLocal nameA 0) + :| [Standalone (nameB1, refLocal nameB 0)] + ) + ( application + (application (refLocal nameA1 0) (refLocal nameA 0)) + (application (refLocal nameB1 0) (refLocal nameB 0)) + ) + ) + renameShadowedNamesInExpr mempty original === renamed + -------------------------------------------------------------------------------- -- Helpers --------------------------------------------------------------------- diff --git a/test/Language/PureScript/Backend/Lua/Gen.hs b/test/Language/PureScript/Backend/Lua/Gen.hs index 4284377..f581025 100644 --- a/test/Language/PureScript/Backend/Lua/Gen.hs +++ b/test/Language/PureScript/Backend/Lua/Gen.hs @@ -132,7 +132,7 @@ binOp ∷ Gen Lua.Exp binOp = Lua.binOp <$> Gen.enumBounded <*> expression <*> expression table ∷ Gen Lua.Exp -table = Lua.tableCtor <$> Gen.list (Range.linear 0 5) tableRow +table = Lua.table <$> Gen.list (Range.linear 0 5) tableRow recursiveVar ∷ Gen Lua.Exp recursiveVar = do diff --git a/test/ps/golden/Golden/TestNameShadowing.purs b/test/ps/golden/Golden/TestNameShadowing.purs new file mode 100644 index 0000000..04504e3 --- /dev/null +++ b/test/ps/golden/Golden/TestNameShadowing.purs @@ -0,0 +1,15 @@ +module Golden.TestNameShadowing (b, c) where + +a :: Int -> Int +a x = f x 1 + +b :: Int -> Int -> Int +b x x1 = f (f x x1) (a 42) + +c ∷ Int -> Int -> Int +c = \x -> (\y -> \x -> f x y) x + +f :: Int -> Int -> Int +f 1 _ = 1 +f _ 1 = 2 +f _ _ = 3 diff --git a/test/ps/golden/Golden/TestPatternMatching1.purs b/test/ps/golden/Golden/TestPatternMatching1.purs index f6cb0aa..71e1978 100644 --- a/test/ps/golden/Golden/TestPatternMatching1.purs +++ b/test/ps/golden/Golden/TestPatternMatching1.purs @@ -11,3 +11,11 @@ pat e = case e of Num (Succ _) -> 4 Num _ -> 5 _ -> 6 + +data Tuple = T Int Int + +fst :: Tuple -> Int +fst (T x _) = x + +snd :: Tuple -> Int +snd (T _ y) = y diff --git a/test/ps/golden/Golden/TestRecordsUpdate.purs b/test/ps/golden/Golden/TestRecordsUpdate.purs new file mode 100644 index 0000000..66143c2 --- /dev/null +++ b/test/ps/golden/Golden/TestRecordsUpdate.purs @@ -0,0 +1,21 @@ +module Golden.TestRecordsUpdate where + +type R = { x :: Int, y :: Boolean, z :: Z } +type Z = { z :: String , p :: Char } + +r :: R +r = { x: 1, y: true, z: { z: "foo", p: 'a' } } + +test1 :: R +test1 = r { x = 2 } + +test2 :: R -> R +test2 = _ { y = false } + +test3 :: R -> R +test3 = _ { z { p = 'b' } } + +type Poly r = { x :: Int, y :: Char | r } + +test4 :: forall r. Poly r -> Poly r +test4 = _ { x = 1 } diff --git a/test/ps/output/Golden.TestCaseStatements/golden.ir b/test/ps/output/Golden.TestCaseStatements/golden.ir index d40e77e..ee07985 100644 --- a/test/ps/output/Golden.TestCaseStatements/golden.ir +++ b/test/ps/output/Golden.TestCaseStatements/golden.ir @@ -108,7 +108,7 @@ UberModule ( IfThenElse ( Identity ( Eq - ( Identity ( LiteralString "Golden.TestCaseStatements.J" ) ) + ( Identity ( LiteralString "M.J" ) ) ( Identity ( ReflectCtor ( Identity ( Ref ( Local ( Name "m" ) ) 0 ) ) ) ) @@ -118,14 +118,17 @@ UberModule ( IfThenElse ( Identity ( Eq - ( Identity ( LiteralString "Golden.TestCaseStatements.N" ) ) + ( Identity ( LiteralString "M.N" ) ) ( Identity ( ReflectCtor ( Identity ( Ref ( Local ( Name "n" ) ) 0 ) ) ) ) ) ) ( Identity - ( ArrayIndex ( Identity ( Ref ( Local ( Name "m" ) ) 0 ) ) 0 ) + ( ObjectProp + ( Identity ( Ref ( Local ( Name "m" ) ) 0 ) ) + ( PropName "value0" ) + ) ) ( Identity ( App diff --git a/test/ps/output/Golden.TestCaseStatements/golden.lua b/test/ps/output/Golden.TestCaseStatements/golden.lua index b4b4d05..b0bfac3 100644 --- a/test/ps/output/Golden.TestCaseStatements/golden.lua +++ b/test/ps/output/Golden.TestCaseStatements/golden.lua @@ -1,12 +1,13 @@ +local Golden_TestValues_I_f = function(unused0) return true end return { a = 1, b = "b", c = (function() local v = function(unused1) return 0 end return (function() - if true == (function(unused0) return true end)(2) then + if true == Golden_TestValues_I_f(2) then return (function() - if true == (function(unused0) return true end)(1) then + if true == Golden_TestValues_I_f(1) then return 42 else return v(true) @@ -17,10 +18,8 @@ return { end end)() end)(), - J = function(value0) - return { ["$ctor"] = "Golden_TestCaseStatements.J", value0 = value0 } - end, - N = function() return { ["$ctor"] = "Golden_TestCaseStatements.N" } end, + J = function(value0) return { ["$ctor"] = "M.J", value0 = value0 } end, + N = { ["$ctor"] = "M.N" }, d = function(m) return function(n) return function(x) @@ -30,10 +29,10 @@ return { return (function() if "x" == x then return (function() - if "Golden.TestCaseStatements.J" == m["$ctor"] then + if "M.J" == m["$ctor"] then return (function() - if "Golden.TestCaseStatements.N" == n["$ctor"] then - return m[0] + if "M.N" == n["$ctor"] then + return m.value0 else return v(true) end diff --git a/test/ps/output/Golden.TestDataDeclarations1/golden.lua b/test/ps/output/Golden.TestDataDeclarations1/golden.lua index 90a5d24..259ea63 100644 --- a/test/ps/output/Golden.TestDataDeclarations1/golden.lua +++ b/test/ps/output/Golden.TestDataDeclarations1/golden.lua @@ -1,34 +1,30 @@ return { - U = function() return { ["$ctor"] = "Golden_TestDataDeclarations1.U" } end, - P3 = function(value0, value1, value2) - return { - ["$ctor"] = "Golden_TestDataDeclarations1.P3", - value0 = value0, - value1 = value1, - value2 = value2 - } + U = { ["$ctor"] = "Unit.U" }, + P3 = function(value0) + return function(value1) + return function(value2) + return { + ["$ctor"] = "TProduct.P3", + value0 = value0, + value1 = value1, + value2 = value2 + } + end + end end, PF = function(value0) - return { ["$ctor"] = "Golden_TestDataDeclarations1.PF", value0 = value0 } + return { ["$ctor"] = "TProductWithFields.PF", value0 = value0 } end, - S0 = function() return { ["$ctor"] = "Golden_TestDataDeclarations1.S0" } end, - S1 = function(value0) - return { ["$ctor"] = "Golden_TestDataDeclarations1.S1", value0 = value0 } - end, - S2 = function(value0, value1) - return { - ["$ctor"] = "Golden_TestDataDeclarations1.S2", - value0 = value0, - value1 = value1 - } - end, - Nop = function() - return { ["$ctor"] = "Golden_TestDataDeclarations1.Nop" } + S0 = { ["$ctor"] = "TSum.S0" }, + S1 = function(value0) return { ["$ctor"] = "TSum.S1", value0 = value0 } end, + S2 = function(value0) + return function(value1) + return { ["$ctor"] = "TSum.S2", value0 = value0, value1 = value1 } + end end, + Nop = { ["$ctor"] = "Rec.Nop" }, More = function(value0) - return { ["$ctor"] = "Golden_TestDataDeclarations1.More", value0 = value0 } + return { ["$ctor"] = "Rec.More", value0 = value0 } end, - CtorSameName = function() - return { ["$ctor"] = "Golden_TestDataDeclarations1.CtorSameName" } - end + CtorSameName = { ["$ctor"] = "TySameName.CtorSameName" } } diff --git a/test/ps/output/Golden.TestDataDeclarations2/golden.ir b/test/ps/output/Golden.TestDataDeclarations2/golden.ir index b2fa4ad..916beb1 100644 --- a/test/ps/output/Golden.TestDataDeclarations2/golden.ir +++ b/test/ps/output/Golden.TestDataDeclarations2/golden.ir @@ -14,7 +14,7 @@ UberModule ( IfThenElse ( Identity ( Eq - ( Identity ( LiteralString "Golden.TestDataDeclarations1.CtorSameName" ) ) + ( Identity ( LiteralString "TySameName.CtorSameName" ) ) ( Identity ( ReflectCtor ( Identity ( Ref ( Local ( Name "v" ) ) 0 ) ) ) ) ) ) @@ -22,7 +22,7 @@ UberModule ( IfThenElse ( Identity ( Eq - ( Identity ( LiteralString "Golden.TestDataDeclarations2.CtorSameName" ) ) + ( Identity ( LiteralString "TySameName.CtorSameName" ) ) ( Identity ( ReflectCtor ( Identity ( Ref ( Local ( Name "v1" ) ) 0 ) ) ) ) ) ) diff --git a/test/ps/output/Golden.TestDataDeclarations2/golden.lua b/test/ps/output/Golden.TestDataDeclarations2/golden.lua index ba8d3f8..d156aa4 100644 --- a/test/ps/output/Golden.TestDataDeclarations2/golden.lua +++ b/test/ps/output/Golden.TestDataDeclarations2/golden.lua @@ -1,12 +1,10 @@ return { - CtorSameName = function() - return { ["$ctor"] = "Golden_TestDataDeclarations2.CtorSameName" } - end, + CtorSameName = { ["$ctor"] = "TySameName.CtorSameName" }, test = function(v) return function(v1) - if "Golden.TestDataDeclarations1.CtorSameName" == v["$ctor"] then + if "TySameName.CtorSameName" == v["$ctor"] then return (function() - if "Golden.TestDataDeclarations2.CtorSameName" == v1["$ctor"] then + if "TySameName.CtorSameName" == v1["$ctor"] then return true else return error("No patterns matched") diff --git a/test/ps/output/Golden.TestHelloPrelude/golden.ir b/test/ps/output/Golden.TestHelloPrelude/golden.ir index 6d2c2d7..eb2b277 100644 --- a/test/ps/output/Golden.TestHelloPrelude/golden.ir +++ b/test/ps/output/Golden.TestHelloPrelude/golden.ir @@ -406,7 +406,7 @@ UberModule ( ObjectProp ( Identity ( ForeignImport - ( ModuleName "Data.Unit" ) ".spago/prelude/v6.0.3/src/Data/Unit.purs" + ( ModuleName "Data.Unit" ) ".spago/prelude/v6.0.2/src/Data/Unit.purs" ) ) ( PropName "unit" ) diff --git a/test/ps/output/Golden.TestHelloPrelude/golden.lua b/test/ps/output/Golden.TestHelloPrelude/golden.lua index cbdd003..08cb9c0 100644 --- a/test/ps/output/Golden.TestHelloPrelude/golden.lua +++ b/test/ps/output/Golden.TestHelloPrelude/golden.lua @@ -1,196 +1,123 @@ -local Effect_I_monadEffect -local Effect_I_bindEffect -local Effect_I_applicativeEffect -local Effect_I__S___lazy_functorEffect -local Effect_I__S___lazy_applyEffect -Effect_I_monadEffect = { - Applicative0 = function(unused0) return Effect_I_applicativeEffect end, - Bind1 = function(unused1) return Effect_I_bindEffect end -} -Effect_I_bindEffect = { - bind = ((function() - return { - - pureE = function(a) - return function() - return a +local Prim_I_undefined = nil +local function _S___runtime_lazy(name) + return function(init) + return function() + local state = 0 + local val = nil + if state == 2 then + return val + else + if state == 1 then + return error(name .. " was needed before it finished initializing") + else + state = 1 + val = init() + state = 2 + return val end end + end + end +end +local Effect_I_foreign = (function() + return { - , bindE = function(a) - return function(f) - return function() - return f(a())() - end - end + pureE = function(a) + return function() + return a end + end - , untilE = function(f) + , bindE = function(a) + return function(f) return function() - while not f() do end + return f(a())() end end + end - , whileE = function(f) - return function(a) - return function() - while f() do - a() - end - end - end + , untilE = function(f) + return function() + while not f() do end end + end - , forE = function(lo) - return function(hi) - return function(f) - return function() - for i = lo, hi do - f(i)() - end - end + , whileE = function(f) + return function(a) + return function() + while f() do + a() end end end + end - , foreachE = function(as) + , forE = function(lo) + return function(hi) return function(f) return function() - for i, v in ipairs(as) do - f(v)() + for i = lo, hi do + f(i)() end end end end + end - } - end)()).bindE, - Apply0 = function(unused2) return Effect_I__S___lazy_applyEffect(0) end -} -Effect_I_applicativeEffect = { - pure = ((function() - return { - - pureE = function(a) - return function() - return a - end - end - - , bindE = function(a) - return function(f) - return function() - return f(a())() - end - end - end - - , untilE = function(f) + , foreachE = function(as) + return function(f) return function() - while not f() do end - end - end - - , whileE = function(f) - return function(a) - return function() - while f() do - a() - end - end - end - end - - , forE = function(lo) - return function(hi) - return function(f) - return function() - for i = lo, hi do - f(i)() - end - end - end - end - end - - , foreachE = function(as) - return function(f) - return function() - for i, v in ipairs(as) do - f(v)() - end + for i, v in ipairs(as) do + f(v)() end end end + end - } - end)()).pureE, + } +end)() +local Control_Applicative_I_pure = function(dict) return dict.pure end +local Effect_I_monadEffect +local Effect_I_bindEffect +local Effect_I_applicativeEffect +local Effect_I__S___lazy_functorEffect +local Effect_I__S___lazy_applyEffect +Effect_I_monadEffect = { + Applicative0 = function(unused0) return Effect_I_applicativeEffect end, + Bind1 = function(unused1) return Effect_I_bindEffect end +} +Effect_I_bindEffect = { + bind = Effect_I_foreign.bindE, + Apply0 = function(unused2) return Effect_I__S___lazy_applyEffect(0) end +} +Effect_I_applicativeEffect = { + pure = Effect_I_foreign.pureE, Apply0 = function(unused3) return Effect_I__S___lazy_applyEffect(0) end } -Effect_I__S___lazy_functorEffect = (function(name) - return function(init) - return function() - local state = 0 - local val = nil - if state == 2 then - return val - else - if state == 1 then - return error(name .. " was needed before it finished initializing") - else - state = 1 - val = init() - state = 2 - return val - end - end - end - end -end)("functorEffect")(function(unused4) +Effect_I__S___lazy_functorEffect = _S___runtime_lazy("functorEffect")(function( unused4 ) return { map = (function(dictApplicative) return function(f) return function(a) return (function(dict) return dict.apply - end)(dictApplicative.Apply0(nil))((function(dict) - return dict.pure - end)(dictApplicative)(f))(a) + end)(dictApplicative.Apply0(Prim_I_undefined))(Control_Applicative_I_pure(dictApplicative)(f))(a) end end end)(Effect_I_applicativeEffect) } end) -Effect_I__S___lazy_applyEffect = (function(name) - return function(init) - return function() - local state = 0 - local val = nil - if state == 2 then - return val - else - if state == 1 then - return error(name .. " was needed before it finished initializing") - else - state = 1 - val = init() - state = 2 - return val - end - end - end - end -end)("applyEffect")(function(unused6) +Effect_I__S___lazy_applyEffect = _S___runtime_lazy("applyEffect")(function( unused6 ) return { apply = (function(dictMonad) return function(f) - local bind = (function(dict) return dict.bind end)(dictMonad.Bind1(nil)) + local bind = (function(dict) + return dict.bind + end)(dictMonad.Bind1(Prim_I_undefined)) return function(a) return bind(f)(function(fPrime) return bind(a)(function(aPrime) - return (function(dict) - return dict.pure - end)(dictMonad.Applicative0(nil))(fPrime(aPrime)) + return Control_Applicative_I_pure(dictMonad.Applicative0(Prim_I_undefined))(fPrime(aPrime)) end) end) end @@ -201,7 +128,7 @@ end)("applyEffect")(function(unused6) end) return { main = (function(dictApplicative) - return (function(dict) return dict.pure end)(dictApplicative)(((function() + return Control_Applicative_I_pure(dictApplicative)(((function() return {unit = nil} end)()).unit) end)(Effect_I_applicativeEffect) diff --git a/test/ps/output/Golden.TestNameShadowing/corefn.json b/test/ps/output/Golden.TestNameShadowing/corefn.json new file mode 100644 index 0000000..a017df4 --- /dev/null +++ b/test/ps/output/Golden.TestNameShadowing/corefn.json @@ -0,0 +1 @@ +{"builtWith":"0.15.9","comments":[],"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[12,23],"start":[12,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[12,23],"start":[12,1]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[12,23],"start":[12,1]}},"argument":"v1","body":{"annotation":{"meta":null,"sourceSpan":{"end":[12,23],"start":[12,1]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[13,4],"start":[13,3]}},"binderType":"LiteralBinder","literal":{"literalType":"IntLiteral","value":1}},{"annotation":{"meta":null,"sourceSpan":{"end":[13,6],"start":[13,5]}},"binderType":"NullBinder"}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[13,10],"start":[13,9]}},"type":"Literal","value":{"literalType":"IntLiteral","value":1}},"isGuarded":false},{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[14,4],"start":[14,3]}},"binderType":"NullBinder"},{"annotation":{"meta":null,"sourceSpan":{"end":[14,6],"start":[14,5]}},"binderType":"LiteralBinder","literal":{"literalType":"IntLiteral","value":1}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[14,10],"start":[14,9]}},"type":"Literal","value":{"literalType":"IntLiteral","value":2}},"isGuarded":false},{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[15,4],"start":[15,3]}},"binderType":"NullBinder"},{"annotation":{"meta":null,"sourceSpan":{"end":[15,6],"start":[15,5]}},"binderType":"NullBinder"}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[15,10],"start":[15,9]}},"type":"Literal","value":{"literalType":"IntLiteral","value":3}},"isGuarded":false}],"caseExpressions":[{"annotation":{"meta":null,"sourceSpan":{"end":[13,10],"start":[13,1]}},"type":"Var","value":{"identifier":"v","sourcePos":[0,0]}},{"annotation":{"meta":null,"sourceSpan":{"end":[13,10],"start":[13,1]}},"type":"Var","value":{"identifier":"v1","sourcePos":[0,0]}}],"type":"Case"},"type":"Abs"},"type":"Abs"},"identifier":"f"},{"annotation":{"meta":null,"sourceSpan":{"end":[9,22],"start":[9,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[10,32],"start":[10,5]}},"argument":"x","body":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[10,29],"start":[10,12]}},"argument":"y","body":{"annotation":{"meta":null,"sourceSpan":{"end":[10,29],"start":[10,18]}},"argument":"x1","body":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[10,25],"start":[10,24]}},"type":"Var","value":{"identifier":"f","moduleName":["Golden","TestNameShadowing"]}},"annotation":{"meta":null,"sourceSpan":{"end":[10,27],"start":[10,24]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[10,27],"start":[10,26]}},"type":"Var","value":{"identifier":"x1","sourcePos":[10,19]}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[10,29],"start":[10,24]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[10,29],"start":[10,28]}},"type":"Var","value":{"identifier":"y","sourcePos":[10,13]}},"type":"App"},"type":"Abs"},"type":"Abs"},"annotation":{"meta":null,"sourceSpan":{"end":[10,32],"start":[10,11]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[10,32],"start":[10,31]}},"type":"Var","value":{"identifier":"x","sourcePos":[10,6]}},"type":"App"},"type":"Abs"},"identifier":"c"},{"annotation":{"meta":null,"sourceSpan":{"end":[3,16],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[3,16],"start":[3,1]}},"argument":"x","body":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[4,8],"start":[4,7]}},"type":"Var","value":{"identifier":"f","moduleName":["Golden","TestNameShadowing"]}},"annotation":{"meta":null,"sourceSpan":{"end":[4,10],"start":[4,7]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[4,10],"start":[4,9]}},"type":"Var","value":{"identifier":"x","sourcePos":[4,1]}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[4,13],"start":[4,7]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[4,13],"start":[4,12]}},"type":"Literal","value":{"literalType":"IntLiteral","value":1}},"type":"App"},"type":"Abs"},"identifier":"a"},{"annotation":{"meta":null,"sourceSpan":{"end":[6,23],"start":[6,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[6,23],"start":[6,1]}},"argument":"x","body":{"annotation":{"meta":null,"sourceSpan":{"end":[6,23],"start":[6,1]}},"argument":"x1","body":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[7,11],"start":[7,10]}},"type":"Var","value":{"identifier":"f","moduleName":["Golden","TestNameShadowing"]}},"annotation":{"meta":null,"sourceSpan":{"end":[7,20],"start":[7,10]}},"argument":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[7,14],"start":[7,13]}},"type":"Var","value":{"identifier":"f","moduleName":["Golden","TestNameShadowing"]}},"annotation":{"meta":null,"sourceSpan":{"end":[7,16],"start":[7,13]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[7,16],"start":[7,15]}},"type":"Var","value":{"identifier":"x","sourcePos":[7,1]}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[7,19],"start":[7,13]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[7,19],"start":[7,17]}},"type":"Var","value":{"identifier":"x1","sourcePos":[7,1]}},"type":"App"},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[7,27],"start":[7,10]}},"argument":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[7,23],"start":[7,22]}},"type":"Var","value":{"identifier":"a","moduleName":["Golden","TestNameShadowing"]}},"annotation":{"meta":null,"sourceSpan":{"end":[7,26],"start":[7,22]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[7,26],"start":[7,24]}},"type":"Literal","value":{"literalType":"IntLiteral","value":42}},"type":"App"},"type":"App"},"type":"Abs"},"type":"Abs"},"identifier":"b"}],"exports":["b","c"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[15,10],"start":[1,1]}},"moduleName":["Golden","TestNameShadowing"]},{"annotation":{"meta":null,"sourceSpan":{"end":[15,10],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Golden","TestNameShadowing"],"modulePath":"golden/Golden/TestNameShadowing.purs","reExports":{},"sourceSpan":{"end":[15,10],"start":[1,1]}} \ No newline at end of file diff --git a/test/ps/output/Golden.TestNameShadowing/golden.ir b/test/ps/output/Golden.TestNameShadowing/golden.ir new file mode 100644 index 0000000..6857619 --- /dev/null +++ b/test/ps/output/Golden.TestNameShadowing/golden.ir @@ -0,0 +1,137 @@ +UberModule + { uberModuleBindings = + [ Standalone + ( QName + { qnameModuleName = ModuleName "Golden.TestNameShadowing", qnameName = Name "f" }, Abs + ( Identity ( ParamNamed ( Name "v" ) ) ) + ( Identity + ( Abs + ( Identity ( ParamNamed ( Name "v1" ) ) ) + ( Identity + ( IfThenElse + ( Identity + ( Eq ( Identity ( LiteralInt 1 ) ) ( Identity ( Ref ( Local ( Name "v" ) ) 0 ) ) ) + ) + ( Identity ( LiteralInt 1 ) ) + ( Identity + ( IfThenElse + ( Identity + ( Eq + ( Identity ( LiteralInt 1 ) ) + ( Identity ( Ref ( Local ( Name "v1" ) ) 0 ) ) + ) + ) + ( Identity ( LiteralInt 2 ) ) + ( Identity ( LiteralInt 3 ) ) + ) + ) + ) + ) + ) + ) + ) + ], uberModuleExports = + [ + ( Name "b", Abs + ( Identity ( ParamNamed ( Name "x" ) ) ) + ( Identity + ( Abs + ( Identity ( ParamNamed ( Name "x1" ) ) ) + ( Identity + ( App + ( Identity + ( App + ( Identity + ( Ref ( Imported ( ModuleName "Golden.TestNameShadowing" ) ( Name "f" ) ) 0 ) + ) + ( Identity + ( App + ( Identity + ( App + ( Identity + ( Ref + ( Imported + ( ModuleName "Golden.TestNameShadowing" ) + ( Name "f" ) + ) 0 + ) + ) + ( Identity ( Ref ( Local ( Name "x" ) ) 0 ) ) + ) + ) + ( Identity ( Ref ( Local ( Name "x1" ) ) 0 ) ) + ) + ) + ) + ) + ( Identity + ( App + ( Identity + ( Abs + ( Identity ( ParamNamed ( Name "x2" ) ) ) + ( Identity + ( App + ( Identity + ( App + ( Identity + ( Ref + ( Imported + ( ModuleName "Golden.TestNameShadowing" ) + ( Name "f" ) + ) 0 + ) + ) + ( Identity ( Ref ( Local ( Name "x2" ) ) 0 ) ) + ) + ) + ( Identity ( LiteralInt 1 ) ) + ) + ) + ) + ) + ( Identity ( LiteralInt 42 ) ) + ) + ) + ) + ) + ) + ) + ), + ( Name "c", Abs + ( Identity ( ParamNamed ( Name "x" ) ) ) + ( Identity + ( App + ( Identity + ( Abs + ( Identity ( ParamNamed ( Name "y" ) ) ) + ( Identity + ( Abs + ( Identity ( ParamNamed ( Name "x1" ) ) ) + ( Identity + ( App + ( Identity + ( App + ( Identity + ( Ref + ( Imported + ( ModuleName "Golden.TestNameShadowing" ) + ( Name "f" ) + ) 0 + ) + ) + ( Identity ( Ref ( Local ( Name "x1" ) ) 0 ) ) + ) + ) + ( Identity ( Ref ( Local ( Name "y" ) ) 0 ) ) + ) + ) + ) + ) + ) + ) + ( Identity ( Ref ( Local ( Name "x" ) ) 0 ) ) + ) + ) + ) + ] + } \ No newline at end of file diff --git a/test/ps/output/Golden.TestNameShadowing/golden.lua b/test/ps/output/Golden.TestNameShadowing/golden.lua new file mode 100644 index 0000000..1d4ef59 --- /dev/null +++ b/test/ps/output/Golden.TestNameShadowing/golden.lua @@ -0,0 +1,23 @@ +local Golden_TestNameShadowing_I_f = function(v) + return function(v1) + if 1 == v then + return 1 + else + return (function() if 1 == v1 then return 2 else return 3 end end)() + end + end +end +return { + b = function(x) + return function(x1) + return Golden_TestNameShadowing_I_f(Golden_TestNameShadowing_I_f(x)(x1))((function( x2 ) + return Golden_TestNameShadowing_I_f(x2)(1) + end)(42)) + end + end, + c = function(x) + return (function(y) + return function(x1) return Golden_TestNameShadowing_I_f(x1)(y) end + end)(x) + end +} diff --git a/test/ps/output/Golden.TestNewtype/golden.lua b/test/ps/output/Golden.TestNewtype/golden.lua index f79c30d..4050845 100644 --- a/test/ps/output/Golden.TestNewtype/golden.lua +++ b/test/ps/output/Golden.TestNewtype/golden.lua @@ -1,5 +1,6 @@ +local Golden_TestNewtype_I_NT = function(x) return x end return { - NT = function(x) return x end, + NT = Golden_TestNewtype_I_NT, f = function(v) return v.foo end, - g = function(x) return x end + g = Golden_TestNewtype_I_NT } diff --git a/test/ps/output/Golden.TestPatternMatching1/corefn.json b/test/ps/output/Golden.TestPatternMatching1/corefn.json index f61e4ee..da11c3d 100644 --- a/test/ps/output/Golden.TestPatternMatching1/corefn.json +++ b/test/ps/output/Golden.TestPatternMatching1/corefn.json @@ -1 +1,1413 @@ -{"builtWith":"0.15.9","comments":[],"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,23],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[3,23],"start":[3,1]}},"constructorName":"Zero","fieldNames":[],"type":"Constructor","typeName":"N"},"identifier":"Zero"},{"annotation":{"meta":null,"sourceSpan":{"end":[3,23],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[3,23],"start":[3,1]}},"constructorName":"Succ","fieldNames":["value0"],"type":"Constructor","typeName":"N"},"identifier":"Succ"},{"annotation":{"meta":null,"sourceSpan":{"end":[4,23],"start":[4,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[4,23],"start":[4,1]}},"constructorName":"Num","fieldNames":["value0"],"type":"Constructor","typeName":"E"},"identifier":"Num"},{"annotation":{"meta":null,"sourceSpan":{"end":[4,23],"start":[4,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[4,23],"start":[4,1]}},"constructorName":"Not","fieldNames":["value0"],"type":"Constructor","typeName":"E"},"identifier":"Not"},{"annotation":{"meta":null,"sourceSpan":{"end":[6,16],"start":[6,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[6,16],"start":[6,1]}},"argument":"e","body":{"annotation":{"meta":null,"sourceSpan":{"end":[13,9],"start":[7,9]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":{"constructorType":"SumType","identifiers":["value0"],"metaType":"IsConstructor"},"sourceSpan":{"end":[8,21],"start":[8,3]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":{"constructorType":"SumType","identifiers":["value0"],"metaType":"IsConstructor"},"sourceSpan":{"end":[8,20],"start":[8,8]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":{"constructorType":"SumType","identifiers":["value0"],"metaType":"IsConstructor"},"sourceSpan":{"end":[8,19],"start":[8,13]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[8,19],"start":[8,18]}},"binderType":"NullBinder"}],"constructorName":{"identifier":"Succ","moduleName":["Golden","TestPatternMatching1"]},"typeName":{"identifier":"N","moduleName":["Golden","TestPatternMatching1"]}}],"constructorName":{"identifier":"Num","moduleName":["Golden","TestPatternMatching1"]},"typeName":{"identifier":"E","moduleName":["Golden","TestPatternMatching1"]}}],"constructorName":{"identifier":"Not","moduleName":["Golden","TestPatternMatching1"]},"typeName":{"identifier":"E","moduleName":["Golden","TestPatternMatching1"]}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[8,26],"start":[8,25]}},"type":"Literal","value":{"literalType":"IntLiteral","value":1}},"isGuarded":false},{"binders":[{"annotation":{"meta":{"constructorType":"SumType","identifiers":["value0"],"metaType":"IsConstructor"},"sourceSpan":{"end":[9,17],"start":[9,3]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":{"constructorType":"SumType","identifiers":["value0"],"metaType":"IsConstructor"},"sourceSpan":{"end":[9,16],"start":[9,8]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":{"constructorType":"SumType","identifiers":[],"metaType":"IsConstructor"},"sourceSpan":{"end":[9,16],"start":[9,12]}},"binderType":"ConstructorBinder","binders":[],"constructorName":{"identifier":"Zero","moduleName":["Golden","TestPatternMatching1"]},"typeName":{"identifier":"N","moduleName":["Golden","TestPatternMatching1"]}}],"constructorName":{"identifier":"Num","moduleName":["Golden","TestPatternMatching1"]},"typeName":{"identifier":"E","moduleName":["Golden","TestPatternMatching1"]}}],"constructorName":{"identifier":"Not","moduleName":["Golden","TestPatternMatching1"]},"typeName":{"identifier":"E","moduleName":["Golden","TestPatternMatching1"]}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[9,22],"start":[9,21]}},"type":"Literal","value":{"literalType":"IntLiteral","value":2}},"isGuarded":false},{"binders":[{"annotation":{"meta":{"constructorType":"SumType","identifiers":["value0"],"metaType":"IsConstructor"},"sourceSpan":{"end":[10,27],"start":[10,3]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":{"constructorType":"SumType","identifiers":["value0"],"metaType":"IsConstructor"},"sourceSpan":{"end":[10,26],"start":[10,8]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":{"constructorType":"SumType","identifiers":["value0"],"metaType":"IsConstructor"},"sourceSpan":{"end":[10,25],"start":[10,13]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":{"constructorType":"SumType","identifiers":["value0"],"metaType":"IsConstructor"},"sourceSpan":{"end":[10,24],"start":[10,18]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[10,24],"start":[10,23]}},"binderType":"NullBinder"}],"constructorName":{"identifier":"Succ","moduleName":["Golden","TestPatternMatching1"]},"typeName":{"identifier":"N","moduleName":["Golden","TestPatternMatching1"]}}],"constructorName":{"identifier":"Num","moduleName":["Golden","TestPatternMatching1"]},"typeName":{"identifier":"E","moduleName":["Golden","TestPatternMatching1"]}}],"constructorName":{"identifier":"Not","moduleName":["Golden","TestPatternMatching1"]},"typeName":{"identifier":"E","moduleName":["Golden","TestPatternMatching1"]}}],"constructorName":{"identifier":"Not","moduleName":["Golden","TestPatternMatching1"]},"typeName":{"identifier":"E","moduleName":["Golden","TestPatternMatching1"]}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[10,32],"start":[10,31]}},"type":"Literal","value":{"literalType":"IntLiteral","value":3}},"isGuarded":false},{"binders":[{"annotation":{"meta":{"constructorType":"SumType","identifiers":["value0"],"metaType":"IsConstructor"},"sourceSpan":{"end":[11,15],"start":[11,3]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":{"constructorType":"SumType","identifiers":["value0"],"metaType":"IsConstructor"},"sourceSpan":{"end":[11,14],"start":[11,8]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[11,14],"start":[11,13]}},"binderType":"NullBinder"}],"constructorName":{"identifier":"Succ","moduleName":["Golden","TestPatternMatching1"]},"typeName":{"identifier":"N","moduleName":["Golden","TestPatternMatching1"]}}],"constructorName":{"identifier":"Num","moduleName":["Golden","TestPatternMatching1"]},"typeName":{"identifier":"E","moduleName":["Golden","TestPatternMatching1"]}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[11,20],"start":[11,19]}},"type":"Literal","value":{"literalType":"IntLiteral","value":4}},"isGuarded":false},{"binders":[{"annotation":{"meta":{"constructorType":"SumType","identifiers":["value0"],"metaType":"IsConstructor"},"sourceSpan":{"end":[12,8],"start":[12,3]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[12,8],"start":[12,7]}},"binderType":"NullBinder"}],"constructorName":{"identifier":"Num","moduleName":["Golden","TestPatternMatching1"]},"typeName":{"identifier":"E","moduleName":["Golden","TestPatternMatching1"]}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[12,13],"start":[12,12]}},"type":"Literal","value":{"literalType":"IntLiteral","value":5}},"isGuarded":false},{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[13,4],"start":[13,3]}},"binderType":"NullBinder"}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[13,9],"start":[13,8]}},"type":"Literal","value":{"literalType":"IntLiteral","value":6}},"isGuarded":false}],"caseExpressions":[{"annotation":{"meta":null,"sourceSpan":{"end":[7,15],"start":[7,14]}},"type":"Var","value":{"identifier":"e","sourcePos":[7,1]}}],"type":"Case"},"type":"Abs"},"identifier":"pat"}],"exports":["Zero","Succ","Num","Not","pat"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[13,9],"start":[1,1]}},"moduleName":["Golden","TestPatternMatching1"]},{"annotation":{"meta":null,"sourceSpan":{"end":[13,9],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Golden","TestPatternMatching1"],"modulePath":"golden/Golden/TestPatternMatching1.purs","reExports":{},"sourceSpan":{"end":[13,9],"start":[1,1]}} \ No newline at end of file +{ + "builtWith": "0.15.9", + "comments": [], + "decls": [ + { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 15, + 23 + ], + "start": [ + 15, + 1 + ] + } + }, + "bindType": "NonRec", + "expression": { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 15, + 23 + ], + "start": [ + 15, + 1 + ] + } + }, + "constructorName": "T", + "fieldNames": [ + "value0", + "value1" + ], + "type": "Constructor", + "typeName": "Tuple" + }, + "identifier": "T" + }, + { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 3, + 23 + ], + "start": [ + 3, + 1 + ] + } + }, + "bindType": "NonRec", + "expression": { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 3, + 23 + ], + "start": [ + 3, + 1 + ] + } + }, + "constructorName": "Zero", + "fieldNames": [], + "type": "Constructor", + "typeName": "N" + }, + "identifier": "Zero" + }, + { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 3, + 23 + ], + "start": [ + 3, + 1 + ] + } + }, + "bindType": "NonRec", + "expression": { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 3, + 23 + ], + "start": [ + 3, + 1 + ] + } + }, + "constructorName": "Succ", + "fieldNames": [ + "value0" + ], + "type": "Constructor", + "typeName": "N" + }, + "identifier": "Succ" + }, + { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 4, + 23 + ], + "start": [ + 4, + 1 + ] + } + }, + "bindType": "NonRec", + "expression": { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 4, + 23 + ], + "start": [ + 4, + 1 + ] + } + }, + "constructorName": "Num", + "fieldNames": [ + "value0" + ], + "type": "Constructor", + "typeName": "E" + }, + "identifier": "Num" + }, + { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 4, + 23 + ], + "start": [ + 4, + 1 + ] + } + }, + "bindType": "NonRec", + "expression": { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 4, + 23 + ], + "start": [ + 4, + 1 + ] + } + }, + "constructorName": "Not", + "fieldNames": [ + "value0" + ], + "type": "Constructor", + "typeName": "E" + }, + "identifier": "Not" + }, + { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 20, + 20 + ], + "start": [ + 20, + 1 + ] + } + }, + "bindType": "NonRec", + "expression": { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 20, + 20 + ], + "start": [ + 20, + 1 + ] + } + }, + "argument": "v", + "body": { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 20, + 20 + ], + "start": [ + 20, + 1 + ] + } + }, + "caseAlternatives": [ + { + "binders": [ + { + "annotation": { + "meta": { + "constructorType": "ProductType", + "identifiers": [ + "value0", + "value1" + ], + "metaType": "IsConstructor" + }, + "sourceSpan": { + "end": [ + 21, + 11 + ], + "start": [ + 21, + 6 + ] + } + }, + "binderType": "ConstructorBinder", + "binders": [ + { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 21, + 9 + ], + "start": [ + 21, + 8 + ] + } + }, + "binderType": "NullBinder" + }, + { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 21, + 11 + ], + "start": [ + 21, + 10 + ] + } + }, + "binderType": "VarBinder", + "identifier": "y" + } + ], + "constructorName": { + "identifier": "T", + "moduleName": [ + "Golden", + "TestPatternMatching1" + ] + }, + "typeName": { + "identifier": "Tuple", + "moduleName": [ + "Golden", + "TestPatternMatching1" + ] + } + } + ], + "expression": { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 21, + 16 + ], + "start": [ + 21, + 15 + ] + } + }, + "type": "Var", + "value": { + "identifier": "y", + "sourcePos": [ + 21, + 10 + ] + } + }, + "isGuarded": false + } + ], + "caseExpressions": [ + { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 21, + 16 + ], + "start": [ + 21, + 1 + ] + } + }, + "type": "Var", + "value": { + "identifier": "v", + "sourcePos": [ + 0, + 0 + ] + } + } + ], + "type": "Case" + }, + "type": "Abs" + }, + "identifier": "snd" + }, + { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 6, + 16 + ], + "start": [ + 6, + 1 + ] + } + }, + "bindType": "NonRec", + "expression": { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 6, + 16 + ], + "start": [ + 6, + 1 + ] + } + }, + "argument": "e", + "body": { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 13, + 9 + ], + "start": [ + 7, + 9 + ] + } + }, + "caseAlternatives": [ + { + "binders": [ + { + "annotation": { + "meta": { + "constructorType": "SumType", + "identifiers": [ + "value0" + ], + "metaType": "IsConstructor" + }, + "sourceSpan": { + "end": [ + 8, + 21 + ], + "start": [ + 8, + 3 + ] + } + }, + "binderType": "ConstructorBinder", + "binders": [ + { + "annotation": { + "meta": { + "constructorType": "SumType", + "identifiers": [ + "value0" + ], + "metaType": "IsConstructor" + }, + "sourceSpan": { + "end": [ + 8, + 20 + ], + "start": [ + 8, + 8 + ] + } + }, + "binderType": "ConstructorBinder", + "binders": [ + { + "annotation": { + "meta": { + "constructorType": "SumType", + "identifiers": [ + "value0" + ], + "metaType": "IsConstructor" + }, + "sourceSpan": { + "end": [ + 8, + 19 + ], + "start": [ + 8, + 13 + ] + } + }, + "binderType": "ConstructorBinder", + "binders": [ + { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 8, + 19 + ], + "start": [ + 8, + 18 + ] + } + }, + "binderType": "NullBinder" + } + ], + "constructorName": { + "identifier": "Succ", + "moduleName": [ + "Golden", + "TestPatternMatching1" + ] + }, + "typeName": { + "identifier": "N", + "moduleName": [ + "Golden", + "TestPatternMatching1" + ] + } + } + ], + "constructorName": { + "identifier": "Num", + "moduleName": [ + "Golden", + "TestPatternMatching1" + ] + }, + "typeName": { + "identifier": "E", + "moduleName": [ + "Golden", + "TestPatternMatching1" + ] + } + } + ], + "constructorName": { + "identifier": "Not", + "moduleName": [ + "Golden", + "TestPatternMatching1" + ] + }, + "typeName": { + "identifier": "E", + "moduleName": [ + "Golden", + "TestPatternMatching1" + ] + } + } + ], + "expression": { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 8, + 26 + ], + "start": [ + 8, + 25 + ] + } + }, + "type": "Literal", + "value": { + "literalType": "IntLiteral", + "value": 1 + } + }, + "isGuarded": false + }, + { + "binders": [ + { + "annotation": { + "meta": { + "constructorType": "SumType", + "identifiers": [ + "value0" + ], + "metaType": "IsConstructor" + }, + "sourceSpan": { + "end": [ + 9, + 17 + ], + "start": [ + 9, + 3 + ] + } + }, + "binderType": "ConstructorBinder", + "binders": [ + { + "annotation": { + "meta": { + "constructorType": "SumType", + "identifiers": [ + "value0" + ], + "metaType": "IsConstructor" + }, + "sourceSpan": { + "end": [ + 9, + 16 + ], + "start": [ + 9, + 8 + ] + } + }, + "binderType": "ConstructorBinder", + "binders": [ + { + "annotation": { + "meta": { + "constructorType": "SumType", + "identifiers": [], + "metaType": "IsConstructor" + }, + "sourceSpan": { + "end": [ + 9, + 16 + ], + "start": [ + 9, + 12 + ] + } + }, + "binderType": "ConstructorBinder", + "binders": [], + "constructorName": { + "identifier": "Zero", + "moduleName": [ + "Golden", + "TestPatternMatching1" + ] + }, + "typeName": { + "identifier": "N", + "moduleName": [ + "Golden", + "TestPatternMatching1" + ] + } + } + ], + "constructorName": { + "identifier": "Num", + "moduleName": [ + "Golden", + "TestPatternMatching1" + ] + }, + "typeName": { + "identifier": "E", + "moduleName": [ + "Golden", + "TestPatternMatching1" + ] + } + } + ], + "constructorName": { + "identifier": "Not", + "moduleName": [ + "Golden", + "TestPatternMatching1" + ] + }, + "typeName": { + "identifier": "E", + "moduleName": [ + "Golden", + "TestPatternMatching1" + ] + } + } + ], + "expression": { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 9, + 22 + ], + "start": [ + 9, + 21 + ] + } + }, + "type": "Literal", + "value": { + "literalType": "IntLiteral", + "value": 2 + } + }, + "isGuarded": false + }, + { + "binders": [ + { + "annotation": { + "meta": { + "constructorType": "SumType", + "identifiers": [ + "value0" + ], + "metaType": "IsConstructor" + }, + "sourceSpan": { + "end": [ + 10, + 27 + ], + "start": [ + 10, + 3 + ] + } + }, + "binderType": "ConstructorBinder", + "binders": [ + { + "annotation": { + "meta": { + "constructorType": "SumType", + "identifiers": [ + "value0" + ], + "metaType": "IsConstructor" + }, + "sourceSpan": { + "end": [ + 10, + 26 + ], + "start": [ + 10, + 8 + ] + } + }, + "binderType": "ConstructorBinder", + "binders": [ + { + "annotation": { + "meta": { + "constructorType": "SumType", + "identifiers": [ + "value0" + ], + "metaType": "IsConstructor" + }, + "sourceSpan": { + "end": [ + 10, + 25 + ], + "start": [ + 10, + 13 + ] + } + }, + "binderType": "ConstructorBinder", + "binders": [ + { + "annotation": { + "meta": { + "constructorType": "SumType", + "identifiers": [ + "value0" + ], + "metaType": "IsConstructor" + }, + "sourceSpan": { + "end": [ + 10, + 24 + ], + "start": [ + 10, + 18 + ] + } + }, + "binderType": "ConstructorBinder", + "binders": [ + { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 10, + 24 + ], + "start": [ + 10, + 23 + ] + } + }, + "binderType": "NullBinder" + } + ], + "constructorName": { + "identifier": "Succ", + "moduleName": [ + "Golden", + "TestPatternMatching1" + ] + }, + "typeName": { + "identifier": "N", + "moduleName": [ + "Golden", + "TestPatternMatching1" + ] + } + } + ], + "constructorName": { + "identifier": "Num", + "moduleName": [ + "Golden", + "TestPatternMatching1" + ] + }, + "typeName": { + "identifier": "E", + "moduleName": [ + "Golden", + "TestPatternMatching1" + ] + } + } + ], + "constructorName": { + "identifier": "Not", + "moduleName": [ + "Golden", + "TestPatternMatching1" + ] + }, + "typeName": { + "identifier": "E", + "moduleName": [ + "Golden", + "TestPatternMatching1" + ] + } + } + ], + "constructorName": { + "identifier": "Not", + "moduleName": [ + "Golden", + "TestPatternMatching1" + ] + }, + "typeName": { + "identifier": "E", + "moduleName": [ + "Golden", + "TestPatternMatching1" + ] + } + } + ], + "expression": { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 10, + 32 + ], + "start": [ + 10, + 31 + ] + } + }, + "type": "Literal", + "value": { + "literalType": "IntLiteral", + "value": 3 + } + }, + "isGuarded": false + }, + { + "binders": [ + { + "annotation": { + "meta": { + "constructorType": "SumType", + "identifiers": [ + "value0" + ], + "metaType": "IsConstructor" + }, + "sourceSpan": { + "end": [ + 11, + 15 + ], + "start": [ + 11, + 3 + ] + } + }, + "binderType": "ConstructorBinder", + "binders": [ + { + "annotation": { + "meta": { + "constructorType": "SumType", + "identifiers": [ + "value0" + ], + "metaType": "IsConstructor" + }, + "sourceSpan": { + "end": [ + 11, + 14 + ], + "start": [ + 11, + 8 + ] + } + }, + "binderType": "ConstructorBinder", + "binders": [ + { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 11, + 14 + ], + "start": [ + 11, + 13 + ] + } + }, + "binderType": "NullBinder" + } + ], + "constructorName": { + "identifier": "Succ", + "moduleName": [ + "Golden", + "TestPatternMatching1" + ] + }, + "typeName": { + "identifier": "N", + "moduleName": [ + "Golden", + "TestPatternMatching1" + ] + } + } + ], + "constructorName": { + "identifier": "Num", + "moduleName": [ + "Golden", + "TestPatternMatching1" + ] + }, + "typeName": { + "identifier": "E", + "moduleName": [ + "Golden", + "TestPatternMatching1" + ] + } + } + ], + "expression": { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 11, + 20 + ], + "start": [ + 11, + 19 + ] + } + }, + "type": "Literal", + "value": { + "literalType": "IntLiteral", + "value": 4 + } + }, + "isGuarded": false + }, + { + "binders": [ + { + "annotation": { + "meta": { + "constructorType": "SumType", + "identifiers": [ + "value0" + ], + "metaType": "IsConstructor" + }, + "sourceSpan": { + "end": [ + 12, + 8 + ], + "start": [ + 12, + 3 + ] + } + }, + "binderType": "ConstructorBinder", + "binders": [ + { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 12, + 8 + ], + "start": [ + 12, + 7 + ] + } + }, + "binderType": "NullBinder" + } + ], + "constructorName": { + "identifier": "Num", + "moduleName": [ + "Golden", + "TestPatternMatching1" + ] + }, + "typeName": { + "identifier": "E", + "moduleName": [ + "Golden", + "TestPatternMatching1" + ] + } + } + ], + "expression": { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 12, + 13 + ], + "start": [ + 12, + 12 + ] + } + }, + "type": "Literal", + "value": { + "literalType": "IntLiteral", + "value": 5 + } + }, + "isGuarded": false + }, + { + "binders": [ + { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 13, + 4 + ], + "start": [ + 13, + 3 + ] + } + }, + "binderType": "NullBinder" + } + ], + "expression": { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 13, + 9 + ], + "start": [ + 13, + 8 + ] + } + }, + "type": "Literal", + "value": { + "literalType": "IntLiteral", + "value": 6 + } + }, + "isGuarded": false + } + ], + "caseExpressions": [ + { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 7, + 15 + ], + "start": [ + 7, + 14 + ] + } + }, + "type": "Var", + "value": { + "identifier": "e", + "sourcePos": [ + 7, + 1 + ] + } + } + ], + "type": "Case" + }, + "type": "Abs" + }, + "identifier": "pat" + }, + { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 17, + 20 + ], + "start": [ + 17, + 1 + ] + } + }, + "bindType": "NonRec", + "expression": { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 17, + 20 + ], + "start": [ + 17, + 1 + ] + } + }, + "argument": "v", + "body": { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 17, + 20 + ], + "start": [ + 17, + 1 + ] + } + }, + "caseAlternatives": [ + { + "binders": [ + { + "annotation": { + "meta": { + "constructorType": "ProductType", + "identifiers": [ + "value0", + "value1" + ], + "metaType": "IsConstructor" + }, + "sourceSpan": { + "end": [ + 18, + 11 + ], + "start": [ + 18, + 6 + ] + } + }, + "binderType": "ConstructorBinder", + "binders": [ + { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 18, + 9 + ], + "start": [ + 18, + 8 + ] + } + }, + "binderType": "VarBinder", + "identifier": "x" + }, + { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 18, + 11 + ], + "start": [ + 18, + 10 + ] + } + }, + "binderType": "NullBinder" + } + ], + "constructorName": { + "identifier": "T", + "moduleName": [ + "Golden", + "TestPatternMatching1" + ] + }, + "typeName": { + "identifier": "Tuple", + "moduleName": [ + "Golden", + "TestPatternMatching1" + ] + } + } + ], + "expression": { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 18, + 16 + ], + "start": [ + 18, + 15 + ] + } + }, + "type": "Var", + "value": { + "identifier": "x", + "sourcePos": [ + 18, + 8 + ] + } + }, + "isGuarded": false + } + ], + "caseExpressions": [ + { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 18, + 16 + ], + "start": [ + 18, + 1 + ] + } + }, + "type": "Var", + "value": { + "identifier": "v", + "sourcePos": [ + 0, + 0 + ] + } + } + ], + "type": "Case" + }, + "type": "Abs" + }, + "identifier": "fst" + } + ], + "exports": [ + "Zero", + "Succ", + "Num", + "Not", + "pat", + "T", + "fst", + "snd" + ], + "foreign": [], + "imports": [ + { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 21, + 16 + ], + "start": [ + 1, + 1 + ] + } + }, + "moduleName": [ + "Golden", + "TestPatternMatching1" + ] + }, + { + "annotation": { + "meta": null, + "sourceSpan": { + "end": [ + 21, + 16 + ], + "start": [ + 1, + 1 + ] + } + }, + "moduleName": [ + "Prim" + ] + } + ], + "moduleName": [ + "Golden", + "TestPatternMatching1" + ], + "modulePath": "golden/Golden/TestPatternMatching1.purs", + "reExports": {}, + "sourceSpan": { + "end": [ + 21, + 16 + ], + "start": [ + 1, + 1 + ] + } +} diff --git a/test/ps/output/Golden.TestPatternMatching1/golden.ir b/test/ps/output/Golden.TestPatternMatching1/golden.ir index 4497d88..70ddf13 100644 --- a/test/ps/output/Golden.TestPatternMatching1/golden.ir +++ b/test/ps/output/Golden.TestPatternMatching1/golden.ir @@ -11,7 +11,7 @@ UberModule ( IfThenElse ( Identity ( Eq - ( Identity ( LiteralString "Golden.TestPatternMatching1.Not" ) ) + ( Identity ( LiteralString "E.Not" ) ) ( Identity ( ReflectCtor ( Identity ( Ref ( Local ( Name "e" ) ) 0 ) ) ) ) ) ) @@ -19,10 +19,15 @@ UberModule ( IfThenElse ( Identity ( Eq - ( Identity ( LiteralString "Golden.TestPatternMatching1.Num" ) ) + ( Identity ( LiteralString "E.Num" ) ) ( Identity ( ReflectCtor - ( Identity ( ArrayIndex ( Identity ( Ref ( Local ( Name "e" ) ) 0 ) ) 0 ) ) + ( Identity + ( ObjectProp + ( Identity ( Ref ( Local ( Name "e" ) ) 0 ) ) + ( PropName "value0" ) + ) + ) ) ) ) @@ -31,14 +36,18 @@ UberModule ( IfThenElse ( Identity ( Eq - ( Identity ( LiteralString "Golden.TestPatternMatching1.Succ" ) ) + ( Identity ( LiteralString "N.Succ" ) ) ( Identity ( ReflectCtor ( Identity - ( ArrayIndex + ( ObjectProp ( Identity - ( ArrayIndex ( Identity ( Ref ( Local ( Name "e" ) ) 0 ) ) 0 ) - ) 0 + ( ObjectProp + ( Identity ( Ref ( Local ( Name "e" ) ) 0 ) ) + ( PropName "value0" ) + ) + ) + ( PropName "value0" ) ) ) ) @@ -50,14 +59,18 @@ UberModule ( IfThenElse ( Identity ( Eq - ( Identity ( LiteralString "Golden.TestPatternMatching1.Zero" ) ) + ( Identity ( LiteralString "N.Zero" ) ) ( Identity ( ReflectCtor ( Identity - ( ArrayIndex + ( ObjectProp ( Identity - ( ArrayIndex ( Identity ( Ref ( Local ( Name "e" ) ) 0 ) ) 0 ) - ) 0 + ( ObjectProp + ( Identity ( Ref ( Local ( Name "e" ) ) 0 ) ) + ( PropName "value0" ) + ) + ) + ( PropName "value0" ) ) ) ) @@ -74,11 +87,14 @@ UberModule ( IfThenElse ( Identity ( Eq - ( Identity ( LiteralString "Golden.TestPatternMatching1.Not" ) ) + ( Identity ( LiteralString "E.Not" ) ) ( Identity ( ReflectCtor ( Identity - ( ArrayIndex ( Identity ( Ref ( Local ( Name "e" ) ) 0 ) ) 0 ) + ( ObjectProp + ( Identity ( Ref ( Local ( Name "e" ) ) 0 ) ) + ( PropName "value0" ) + ) ) ) ) @@ -88,14 +104,18 @@ UberModule ( IfThenElse ( Identity ( Eq - ( Identity ( LiteralString "Golden.TestPatternMatching1.Num" ) ) + ( Identity ( LiteralString "E.Num" ) ) ( Identity ( ReflectCtor ( Identity - ( ArrayIndex + ( ObjectProp ( Identity - ( ArrayIndex ( Identity ( Ref ( Local ( Name "e" ) ) 0 ) ) 0 ) - ) 0 + ( ObjectProp + ( Identity ( Ref ( Local ( Name "e" ) ) 0 ) ) + ( PropName "value0" ) + ) + ) + ( PropName "value0" ) ) ) ) @@ -106,20 +126,23 @@ UberModule ( IfThenElse ( Identity ( Eq - ( Identity ( LiteralString "Golden.TestPatternMatching1.Succ" ) ) + ( Identity ( LiteralString "N.Succ" ) ) ( Identity ( ReflectCtor ( Identity - ( ArrayIndex + ( ObjectProp ( Identity - ( ArrayIndex + ( ObjectProp ( Identity - ( ArrayIndex - ( Identity ( Ref ( Local ( Name "e" ) ) 0 ) ) 0 + ( ObjectProp + ( Identity ( Ref ( Local ( Name "e" ) ) 0 ) ) + ( PropName "value0" ) ) - ) 0 + ) + ( PropName "value0" ) ) - ) 0 + ) + ( PropName "value0" ) ) ) ) @@ -142,7 +165,7 @@ UberModule ( IfThenElse ( Identity ( Eq - ( Identity ( LiteralString "Golden.TestPatternMatching1.Num" ) ) + ( Identity ( LiteralString "E.Num" ) ) ( Identity ( ReflectCtor ( Identity ( Ref ( Local ( Name "e" ) ) 0 ) ) ) ) ) ) @@ -150,11 +173,14 @@ UberModule ( IfThenElse ( Identity ( Eq - ( Identity ( LiteralString "Golden.TestPatternMatching1.Succ" ) ) + ( Identity ( LiteralString "N.Succ" ) ) ( Identity ( ReflectCtor ( Identity - ( ArrayIndex ( Identity ( Ref ( Local ( Name "e" ) ) 0 ) ) 0 ) + ( ObjectProp + ( Identity ( Ref ( Local ( Name "e" ) ) 0 ) ) + ( PropName "value0" ) + ) ) ) ) @@ -169,6 +195,45 @@ UberModule ) ) ) + ), + ( Name "T", Ctor ProductType + ( TyName "Tuple" ) + ( CtorName "T" ) + [ FieldName "value0", FieldName "value1" ] + ), + ( Name "fst", Abs + ( Identity ( ParamNamed ( Name "v" ) ) ) + ( Identity + ( IfThenElse + ( Identity + ( Eq + ( Identity ( LiteralString "Tuple.T" ) ) + ( Identity ( ReflectCtor ( Identity ( Ref ( Local ( Name "v" ) ) 0 ) ) ) ) + ) + ) + ( Identity + ( ObjectProp ( Identity ( Ref ( Local ( Name "v" ) ) 0 ) ) ( PropName "value0" ) ) + ) + ( Identity ( Exception "No patterns matched" ) ) + ) + ) + ), + ( Name "snd", Abs + ( Identity ( ParamNamed ( Name "v" ) ) ) + ( Identity + ( IfThenElse + ( Identity + ( Eq + ( Identity ( LiteralString "Tuple.T" ) ) + ( Identity ( ReflectCtor ( Identity ( Ref ( Local ( Name "v" ) ) 0 ) ) ) ) + ) + ) + ( Identity + ( ObjectProp ( Identity ( Ref ( Local ( Name "v" ) ) 0 ) ) ( PropName "value1" ) ) + ) + ( Identity ( Exception "No patterns matched" ) ) + ) + ) ) ] } \ No newline at end of file diff --git a/test/ps/output/Golden.TestPatternMatching1/golden.lua b/test/ps/output/Golden.TestPatternMatching1/golden.lua index ec61b5a..e95c197 100644 --- a/test/ps/output/Golden.TestPatternMatching1/golden.lua +++ b/test/ps/output/Golden.TestPatternMatching1/golden.lua @@ -1,26 +1,18 @@ return { - Zero = function() - return { ["$ctor"] = "Golden_TestPatternMatching1.Zero" } - end, - Succ = function(value0) - return { ["$ctor"] = "Golden_TestPatternMatching1.Succ", value0 = value0 } - end, - Num = function(value0) - return { ["$ctor"] = "Golden_TestPatternMatching1.Num", value0 = value0 } - end, - Not = function(value0) - return { ["$ctor"] = "Golden_TestPatternMatching1.Not", value0 = value0 } - end, + Zero = { ["$ctor"] = "N.Zero" }, + Succ = function(value0) return { ["$ctor"] = "N.Succ", value0 = value0 } end, + Num = function(value0) return { ["$ctor"] = "E.Num", value0 = value0 } end, + Not = function(value0) return { ["$ctor"] = "E.Not", value0 = value0 } end, pat = function(e) - if "Golden.TestPatternMatching1.Not" == e["$ctor"] then + if "E.Not" == e["$ctor"] then return (function() - if "Golden.TestPatternMatching1.Num" == e[0]["$ctor"] then + if "E.Num" == e.value0["$ctor"] then return (function() - if "Golden.TestPatternMatching1.Succ" == e[0][0]["$ctor"] then + if "N.Succ" == e.value0.value0["$ctor"] then return 1 else return (function() - if "Golden.TestPatternMatching1.Zero" == e[0][0]["$ctor"] then + if "N.Zero" == e.value0.value0["$ctor"] then return 2 else return 6 @@ -30,11 +22,11 @@ return { end)() else return (function() - if "Golden.TestPatternMatching1.Not" == e[0]["$ctor"] then + if "E.Not" == e.value0["$ctor"] then return (function() - if "Golden.TestPatternMatching1.Num" == e[0][0]["$ctor"] then + if "E.Num" == e.value0.value0["$ctor"] then return (function() - if "Golden.TestPatternMatching1.Succ" == e[0][0][0]["$ctor"] then + if "N.Succ" == e.value0.value0.value0["$ctor"] then return 3 else return 6 @@ -52,18 +44,33 @@ return { end)() else return (function() - if "Golden.TestPatternMatching1.Num" == e["$ctor"] then + if "E.Num" == e["$ctor"] then return (function() - if "Golden.TestPatternMatching1.Succ" == e[0]["$ctor"] then - return 4 - else - return 5 - end + if "N.Succ" == e.value0["$ctor"] then return 4 else return 5 end end)() else return 6 end end)() end + end, + T = function(value0) + return function(value1) + return { ["$ctor"] = "Tuple.T", value0 = value0, value1 = value1 } + end + end, + fst = function(v) + if "Tuple.T" == v["$ctor"] then + return v.value0 + else + return error("No patterns matched") + end + end, + snd = function(v) + if "Tuple.T" == v["$ctor"] then + return v.value1 + else + return error("No patterns matched") + end end } diff --git a/test/ps/output/Golden.TestPatternMatching2/golden.ir b/test/ps/output/Golden.TestPatternMatching2/golden.ir index 43368c4..9770c08 100644 --- a/test/ps/output/Golden.TestPatternMatching2/golden.ir +++ b/test/ps/output/Golden.TestPatternMatching2/golden.ir @@ -19,7 +19,7 @@ UberModule ( IfThenElse ( Identity ( Eq - ( Identity ( LiteralString "Golden.TestPatternMatching2.Add" ) ) + ( Identity ( LiteralString "N.Add" ) ) ( Identity ( ReflectCtor ( Identity ( Ref ( Local ( Name "e" ) ) 0 ) ) ) ) ) ) @@ -27,10 +27,15 @@ UberModule ( IfThenElse ( Identity ( Eq - ( Identity ( LiteralString "Golden.TestPatternMatching2.Zero" ) ) + ( Identity ( LiteralString "N.Zero" ) ) ( Identity ( ReflectCtor - ( Identity ( ArrayIndex ( Identity ( Ref ( Local ( Name "e" ) ) 0 ) ) 1 ) ) + ( Identity + ( ObjectProp + ( Identity ( Ref ( Local ( Name "e" ) ) 0 ) ) + ( PropName "value1" ) + ) + ) ) ) ) @@ -39,11 +44,14 @@ UberModule ( IfThenElse ( Identity ( Eq - ( Identity ( LiteralString "Golden.TestPatternMatching2.Add" ) ) + ( Identity ( LiteralString "N.Add" ) ) ( Identity ( ReflectCtor ( Identity - ( ArrayIndex ( Identity ( Ref ( Local ( Name "e" ) ) 0 ) ) 0 ) + ( ObjectProp + ( Identity ( Ref ( Local ( Name "e" ) ) 0 ) ) + ( PropName "value0" ) + ) ) ) ) @@ -54,11 +62,14 @@ UberModule ( IfThenElse ( Identity ( Eq - ( Identity ( LiteralString "Golden.TestPatternMatching2.Mul" ) ) + ( Identity ( LiteralString "N.Mul" ) ) ( Identity ( ReflectCtor ( Identity - ( ArrayIndex ( Identity ( Ref ( Local ( Name "e" ) ) 0 ) ) 0 ) + ( ObjectProp + ( Identity ( Ref ( Local ( Name "e" ) ) 0 ) ) + ( PropName "value0" ) + ) ) ) ) @@ -74,11 +85,14 @@ UberModule ( IfThenElse ( Identity ( Eq - ( Identity ( LiteralString "Golden.TestPatternMatching2.Mul" ) ) + ( Identity ( LiteralString "N.Mul" ) ) ( Identity ( ReflectCtor ( Identity - ( ArrayIndex ( Identity ( Ref ( Local ( Name "e" ) ) 0 ) ) 1 ) + ( ObjectProp + ( Identity ( Ref ( Local ( Name "e" ) ) 0 ) ) + ( PropName "value1" ) + ) ) ) ) @@ -89,11 +103,14 @@ UberModule ( IfThenElse ( Identity ( Eq - ( Identity ( LiteralString "Golden.TestPatternMatching2.Add" ) ) + ( Identity ( LiteralString "N.Add" ) ) ( Identity ( ReflectCtor ( Identity - ( ArrayIndex ( Identity ( Ref ( Local ( Name "e" ) ) 0 ) ) 1 ) + ( ObjectProp + ( Identity ( Ref ( Local ( Name "e" ) ) 0 ) ) + ( PropName "value1" ) + ) ) ) ) @@ -104,11 +121,14 @@ UberModule ( IfThenElse ( Identity ( Eq - ( Identity ( LiteralString "Golden.TestPatternMatching2.Zero" ) ) + ( Identity ( LiteralString "N.Zero" ) ) ( Identity ( ReflectCtor ( Identity - ( ArrayIndex ( Identity ( Ref ( Local ( Name "e" ) ) 0 ) ) 1 ) + ( ObjectProp + ( Identity ( Ref ( Local ( Name "e" ) ) 0 ) ) + ( PropName "value1" ) + ) ) ) ) diff --git a/test/ps/output/Golden.TestPatternMatching2/golden.lua b/test/ps/output/Golden.TestPatternMatching2/golden.lua index 0847a39..37c8420 100644 --- a/test/ps/output/Golden.TestPatternMatching2/golden.lua +++ b/test/ps/output/Golden.TestPatternMatching2/golden.lua @@ -1,52 +1,40 @@ return { - Zero = function() - return { ["$ctor"] = "Golden_TestPatternMatching2.Zero" } - end, - Succ = function(value0) - return { ["$ctor"] = "Golden_TestPatternMatching2.Succ", value0 = value0 } - end, - Add = function(value0, value1) - return { - ["$ctor"] = "Golden_TestPatternMatching2.Add", - value0 = value0, - value1 = value1 - } + Zero = { ["$ctor"] = "N.Zero" }, + Succ = function(value0) return { ["$ctor"] = "N.Succ", value0 = value0 } end, + Add = function(value0) + return function(value1) + return { ["$ctor"] = "N.Add", value0 = value0, value1 = value1 } + end end, - Mul = function(value0, value1) - return { - ["$ctor"] = "Golden_TestPatternMatching2.Mul", - value0 = value0, - value1 = value1 - } + Mul = function(value0) + return function(value1) + return { ["$ctor"] = "N.Mul", value0 = value0, value1 = value1 } + end end, pat = function(e) - if "Golden.TestPatternMatching2.Add" == e["$ctor"] then + if "N.Add" == e["$ctor"] then return (function() - if "Golden.TestPatternMatching2.Zero" == e[1]["$ctor"] then + if "N.Zero" == e.value1["$ctor"] then return (function() - if "Golden.TestPatternMatching2.Add" == e[0]["$ctor"] then + if "N.Add" == e.value0["$ctor"] then return 1 else return (function() - if "Golden.TestPatternMatching2.Mul" == e[0]["$ctor"] then - return 2 - else - return 5 - end + if "N.Mul" == e.value0["$ctor"] then return 2 else return 5 end end)() end end)() else return (function() - if "Golden.TestPatternMatching2.Mul" == e[1]["$ctor"] then + if "N.Mul" == e.value1["$ctor"] then return 3 else return (function() - if "Golden.TestPatternMatching2.Add" == e[1]["$ctor"] then + if "N.Add" == e.value1["$ctor"] then return 4 else return (function() - if "Golden.TestPatternMatching2.Zero" == e[1]["$ctor"] then + if "N.Zero" == e.value1["$ctor"] then return 5 else return 6 diff --git a/test/ps/output/Golden.TestRecDataDefs/golden.lua b/test/ps/output/Golden.TestRecDataDefs/golden.lua index 1b1ae6d..a3b8cf8 100644 --- a/test/ps/output/Golden.TestRecDataDefs/golden.lua +++ b/test/ps/output/Golden.TestRecDataDefs/golden.lua @@ -1,20 +1,19 @@ +local Golden_TestRecDataDefs_I_A = { ["$ctor"] = "A.A" } +local Golden_TestRecDataDefs_I_AB = function(value0) + return { ["$ctor"] = "A.AB", value0 = value0 } +end +local Golden_TestRecDataDefs_I_B = { ["$ctor"] = "B.B" } +local Golden_TestRecDataDefs_I_BA = function(value0) + return { ["$ctor"] = "B.BA", value0 = value0 } +end +local Golden_TestRecDataDefs_I_ab = Golden_TestRecDataDefs_I_AB(Golden_TestRecDataDefs_I_B) return { - A = function() return { ["$ctor"] = "Golden_TestRecDataDefs.A" } end, - AB = function(value0) - return { ["$ctor"] = "Golden_TestRecDataDefs.AB", value0 = value0 } - end, - B = function() return { ["$ctor"] = "Golden_TestRecDataDefs.B" } end, - BA = function(value0) - return { ["$ctor"] = "Golden_TestRecDataDefs.BA", value0 = value0 } - end, - a = function() return { ["$ctor"] = "Golden_TestRecDataDefs.A" } end, - b = function() return { ["$ctor"] = "Golden_TestRecDataDefs.B" } end, - ab = (function(value0) - return { ["$ctor"] = "Golden_TestRecDataDefs.AB", value0 = value0 } - end)(function() return { ["$ctor"] = "Golden_TestRecDataDefs.B" } end), - ba = (function(value0) - return { ["$ctor"] = "Golden_TestRecDataDefs.BA", value0 = value0 } - end)((function(value0) - return { ["$ctor"] = "Golden_TestRecDataDefs.AB", value0 = value0 } - end)(function() return { ["$ctor"] = "Golden_TestRecDataDefs.B" } end)) + A = Golden_TestRecDataDefs_I_A, + AB = Golden_TestRecDataDefs_I_AB, + B = Golden_TestRecDataDefs_I_B, + BA = Golden_TestRecDataDefs_I_BA, + a = Golden_TestRecDataDefs_I_A, + b = Golden_TestRecDataDefs_I_B, + ab = Golden_TestRecDataDefs_I_ab, + ba = Golden_TestRecDataDefs_I_BA(Golden_TestRecDataDefs_I_ab) } diff --git a/test/ps/output/Golden.TestRecordsAccess/golden.lua b/test/ps/output/Golden.TestRecordsAccess/golden.lua index 29343f7..16c3fde 100644 --- a/test/ps/output/Golden.TestRecordsAccess/golden.lua +++ b/test/ps/output/Golden.TestRecordsAccess/golden.lua @@ -1,6 +1,7 @@ +local Golden_TestRecordsAccess_I_r = { x = 1, y = true } return { - r = { x = 1, y = true }, - test1 = ({ x = 1, y = true }).x, + r = Golden_TestRecordsAccess_I_r, + test1 = Golden_TestRecordsAccess_I_r.x, test2 = function(v) return v.x end, test3 = function(v) return v.x end, test4 = function(v) return v.x end diff --git a/test/ps/output/Golden.TestRecordsUpdate/corefn.json b/test/ps/output/Golden.TestRecordsUpdate/corefn.json new file mode 100644 index 0000000..e8d2c05 --- /dev/null +++ b/test/ps/output/Golden.TestRecordsUpdate/corefn.json @@ -0,0 +1 @@ +{"builtWith":"0.15.9","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]}},"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]}},"type":"Literal","value":{"literalType":"ObjectLiteral","value":[["x",{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"v","sourcePos":[0,0]}},"fieldName":"x","type":"Accessor"}],["y",{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"v","sourcePos":[0,0]}},"fieldName":"y","type":"Accessor"}],["z",{"annotation":{"meta":null,"sourceSpan":{"end":[16,28],"start":[16,9]}},"type":"Literal","value":{"literalType":"ObjectLiteral","value":[["z",{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"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"},"fieldName":"z","type":"Accessor"}],["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]}},"type":"Literal","value":{"literalType":"ObjectLiteral","value":[["x",{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"v","sourcePos":[0,0]}},"fieldName":"x","type":"Accessor"}],["y",{"annotation":{"meta":null,"sourceSpan":{"end":[13,22],"start":[13,17]}},"type":"Literal","value":{"literalType":"BooleanLiteral","value":false}}],["z",{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"v","sourcePos":[0,0]}},"fieldName":"z","type":"Accessor"}]]}},"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","TestRecordsUpdate"]}},"identifier":"v"}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[10,20],"start":[10,9]}},"type":"Literal","value":{"literalType":"ObjectLiteral","value":[["x",{"annotation":{"meta":null,"sourceSpan":{"end":[10,18],"start":[10,17]}},"type":"Literal","value":{"literalType":"IntLiteral","value":2}}],["y",{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"v","sourcePos":[10,1]}},"fieldName":"y","type":"Accessor"}],["z",{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"v","sourcePos":[10,1]}},"fieldName":"z","type":"Accessor"}]]}},"type":"Let"},"identifier":"test1"}],"exports":["r","test1","test2","test3","test4"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[21,20],"start":[1,1]}},"moduleName":["Golden","TestRecordsUpdate"]},{"annotation":{"meta":null,"sourceSpan":{"end":[21,20],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Golden","TestRecordsUpdate"],"modulePath":"golden/Golden/TestRecordsUpdate.purs","reExports":{},"sourceSpan":{"end":[21,20],"start":[1,1]}} \ No newline at end of file diff --git a/test/ps/output/Golden.TestRecordsUpdate/golden.ir b/test/ps/output/Golden.TestRecordsUpdate/golden.ir new file mode 100644 index 0000000..27155be --- /dev/null +++ b/test/ps/output/Golden.TestRecordsUpdate/golden.ir @@ -0,0 +1,103 @@ +UberModule + { uberModuleBindings = + [ Standalone + ( QName + { qnameModuleName = ModuleName "Golden.TestRecordsUpdate", qnameName = Name "r" + }, LiteralObject + [ + ( PropName "x", Identity ( LiteralInt 1 ) ), + ( PropName "y", Identity ( LiteralBool True ) ), + ( PropName "z", Identity + ( LiteralObject + [ + ( PropName "z", Identity ( LiteralString "foo" ) ), + ( PropName "p", Identity ( LiteralChar 'a' ) ) + ] + ) + ) + ] + ) + ], uberModuleExports = + [ + ( Name "r", Ref ( Imported ( ModuleName "Golden.TestRecordsUpdate" ) ( Name "r" ) ) 0 ), + ( Name "test1", LiteralObject + [ + ( PropName "x", Identity ( LiteralInt 2 ) ), + ( PropName "y", Identity + ( ObjectProp + ( Identity + ( Ref ( Imported ( ModuleName "Golden.TestRecordsUpdate" ) ( Name "r" ) ) 0 ) + ) + ( PropName "y" ) + ) + ), + ( PropName "z", Identity + ( ObjectProp + ( Identity + ( Ref ( Imported ( ModuleName "Golden.TestRecordsUpdate" ) ( Name "r" ) ) 0 ) + ) + ( PropName "z" ) + ) + ) + ] + ), + ( Name "test2", Abs + ( Identity ( ParamNamed ( Name "v" ) ) ) + ( Identity + ( LiteralObject + [ + ( PropName "x", Identity + ( ObjectProp ( Identity ( Ref ( Local ( Name "v" ) ) 0 ) ) ( PropName "x" ) ) + ), + ( PropName "y", Identity ( LiteralBool False ) ), + ( PropName "z", Identity + ( ObjectProp ( Identity ( Ref ( Local ( Name "v" ) ) 0 ) ) ( PropName "z" ) ) + ) + ] + ) + ) + ), + ( Name "test3", Abs + ( Identity ( ParamNamed ( Name "v" ) ) ) + ( Identity + ( LiteralObject + [ + ( PropName "x", Identity + ( ObjectProp ( Identity ( Ref ( Local ( Name "v" ) ) 0 ) ) ( PropName "x" ) ) + ), + ( PropName "y", Identity + ( ObjectProp ( Identity ( Ref ( Local ( Name "v" ) ) 0 ) ) ( PropName "y" ) ) + ), + ( PropName "z", Identity + ( LiteralObject + [ + ( PropName "z", Identity + ( ObjectProp + ( Identity + ( ObjectProp + ( Identity ( Ref ( Local ( Name "v" ) ) 0 ) ) + ( PropName "z" ) + ) + ) + ( PropName "z" ) + ) + ), + ( PropName "p", Identity ( LiteralChar 'b' ) ) + ] + ) + ) + ] + ) + ) + ), + ( Name "test4", Abs + ( Identity ( ParamNamed ( Name "v" ) ) ) + ( Identity + ( ObjectUpdate + ( Identity ( Ref ( Local ( Name "v" ) ) 0 ) ) + ( ( PropName "x", Identity ( LiteralInt 1 ) ) :| [] ) + ) + ) + ) + ] + } \ No newline at end of file diff --git a/test/ps/output/Golden.TestRecordsUpdate/golden.lua b/test/ps/output/Golden.TestRecordsUpdate/golden.lua new file mode 100644 index 0000000..f4837f9 --- /dev/null +++ b/test/ps/output/Golden.TestRecordsUpdate/golden.lua @@ -0,0 +1,30 @@ +local function _S___object_update(o, patches) + local o_copy = {} + for k, v in pairs(o) do + local patch_v = patches + if patch_v ~= nil then + o_copy[k] = patch_v + else + o_copy[k] = v + end + end + return o_copy +end +local Golden_TestRecordsUpdate_I_r = { + x = 1, + y = true, + z = { z = "foo", p = "a" } +} +return { + r = Golden_TestRecordsUpdate_I_r, + test1 = { + x = 2, + y = Golden_TestRecordsUpdate_I_r.y, + z = Golden_TestRecordsUpdate_I_r.z + }, + test2 = function(v) return { x = v.x, y = false, z = v.z } end, + test3 = function(v) + return { x = v.x, y = v.y, z = { z = v.z.z, p = "b" } } + end, + test4 = function(v) return _S___object_update(v, { x = 1 }) end +} diff --git a/test/ps/output/Golden.TestRecursiveBindings/golden.ir b/test/ps/output/Golden.TestRecursiveBindings/golden.ir index fe0ca14..f7befb1 100644 --- a/test/ps/output/Golden.TestRecursiveBindings/golden.ir +++ b/test/ps/output/Golden.TestRecursiveBindings/golden.ir @@ -5,7 +5,7 @@ UberModule ( RecursiveGroup ( ( Identity - ( Name "yes" ), Identity + ( Name "no" ), Identity ( Abs ( Identity ( ParamNamed ( Name "v" ) ) ) ( Identity @@ -18,7 +18,7 @@ UberModule ) ( Identity ( App - ( Identity ( Ref ( Local ( Name "no" ) ) 0 ) ) + ( Identity ( Ref ( Local ( Name "yes" ) ) 0 ) ) ( Identity ( LiteralBool False ) ) ) ) @@ -32,7 +32,7 @@ UberModule ) ( Identity ( App - ( Identity ( Ref ( Local ( Name "no" ) ) 0 ) ) + ( Identity ( Ref ( Local ( Name "yes" ) ) 0 ) ) ( Identity ( LiteralBool True ) ) ) ) @@ -45,7 +45,7 @@ UberModule ) :| [ ( Identity - ( Name "no" ), Identity + ( Name "yes" ), Identity ( Abs ( Identity ( ParamNamed ( Name "v" ) ) ) ( Identity @@ -58,7 +58,7 @@ UberModule ) ( Identity ( App - ( Identity ( Ref ( Local ( Name "yes" ) ) 0 ) ) + ( Identity ( Ref ( Local ( Name "no" ) ) 0 ) ) ( Identity ( LiteralBool False ) ) ) ) @@ -72,7 +72,7 @@ UberModule ) ( Identity ( App - ( Identity ( Ref ( Local ( Name "yes" ) ) 0 ) ) + ( Identity ( Ref ( Local ( Name "no" ) ) 0 ) ) ( Identity ( LiteralBool True ) ) ) ) @@ -94,7 +94,7 @@ UberModule ( RecursiveGroup ( ( Identity - ( Name "yes" ), Identity + ( Name "no" ), Identity ( Abs ( Identity ( ParamNamed ( Name "v" ) ) ) ( Identity @@ -107,7 +107,7 @@ UberModule ) ( Identity ( App - ( Identity ( Ref ( Local ( Name "no" ) ) 0 ) ) + ( Identity ( Ref ( Local ( Name "yes" ) ) 0 ) ) ( Identity ( LiteralBool False ) ) ) ) @@ -121,7 +121,7 @@ UberModule ) ( Identity ( App - ( Identity ( Ref ( Local ( Name "no" ) ) 0 ) ) + ( Identity ( Ref ( Local ( Name "yes" ) ) 0 ) ) ( Identity ( LiteralBool True ) ) ) ) @@ -134,7 +134,7 @@ UberModule ) :| [ ( Identity - ( Name "no" ), Identity + ( Name "yes" ), Identity ( Abs ( Identity ( ParamNamed ( Name "v" ) ) ) ( Identity @@ -147,7 +147,7 @@ UberModule ) ( Identity ( App - ( Identity ( Ref ( Local ( Name "yes" ) ) 0 ) ) + ( Identity ( Ref ( Local ( Name "no" ) ) 0 ) ) ( Identity ( LiteralBool False ) ) ) ) @@ -161,7 +161,7 @@ UberModule ) ( Identity ( App - ( Identity ( Ref ( Local ( Name "yes" ) ) 0 ) ) + ( Identity ( Ref ( Local ( Name "no" ) ) 0 ) ) ( Identity ( LiteralBool True ) ) ) ) @@ -185,11 +185,11 @@ UberModule [ RecursiveGroup ( ( Identity - ( Name "b" ), Identity + ( Name "a" ), Identity ( Abs ( Identity ParamUnused ) ( Identity ( App - ( Identity ( Ref ( Local ( Name "a" ) ) 0 ) ) + ( Identity ( Ref ( Local ( Name "b" ) ) 0 ) ) ( Identity ( Ref ( Local ( Name "z" ) ) 0 ) ) ) ) @@ -197,11 +197,11 @@ UberModule ) :| [ ( Identity - ( Name "a" ), Identity + ( Name "b" ), Identity ( Abs ( Identity ParamUnused ) ( Identity ( App - ( Identity ( Ref ( Local ( Name "b" ) ) 0 ) ) + ( Identity ( Ref ( Local ( Name "a" ) ) 0 ) ) ( Identity ( Ref ( Local ( Name "z" ) ) 0 ) ) ) ) diff --git a/test/ps/output/Golden.TestRecursiveBindings/golden.lua b/test/ps/output/Golden.TestRecursiveBindings/golden.lua index be86e52..2df347d 100644 --- a/test/ps/output/Golden.TestRecursiveBindings/golden.lua +++ b/test/ps/output/Golden.TestRecursiveBindings/golden.lua @@ -1,27 +1,27 @@ return { letRec = (function() - local yes local no - yes = function(v) + local yes + no = function(v) if true == v then - return no(false) + return yes(false) else return (function() if false == v then - return no(true) + return yes(true) else return error("No patterns matched") end end)() end end - no = function(v) + yes = function(v) if true == v then - return yes(false) + return no(false) else return (function() if false == v then - return yes(true) + return no(true) else return error("No patterns matched") end @@ -31,28 +31,28 @@ return { return no(false) end)(), whereRec = (function() - local yes local no - yes = function(v) + local yes + no = function(v) if true == v then - return no(false) + return yes(false) else return (function() if false == v then - return no(true) + return yes(true) else return error("No patterns matched") end end)() end end - no = function(v) + yes = function(v) if true == v then - return yes(false) + return no(false) else return (function() if false == v then - return yes(true) + return no(true) else return error("No patterns matched") end @@ -63,10 +63,10 @@ return { end)(), letRecMixed = (function() local z = 1 - local b local a - b = function(unused0) return a(z) end - a = function(unused1) return b(z) end + local b + a = function(unused0) return b(z) end + b = function(unused1) return a(z) end local f = function(unused2) return function(k) return a(k) end end local y = f(z)(z) return f(f(y)(y))(f(y)(0)) diff --git a/test/ps/output/Golden.TestUnbinding/golden.lua b/test/ps/output/Golden.TestUnbinding/golden.lua index 17924d1..3f37867 100644 --- a/test/ps/output/Golden.TestUnbinding/golden.lua +++ b/test/ps/output/Golden.TestUnbinding/golden.lua @@ -1,8 +1,9 @@ +local Golden_TestUnbinding_I_f = function(unused1) + return function(unused0) return 3 end +end return { a = 1, b = 2, - f = function(unused1) return function(unused0) return 3 end end, - c = (function(unused1) - return function(unused0) return 3 end - end)(1)((function(unused1) return function(unused0) return 3 end end)(2)(1)) + f = Golden_TestUnbinding_I_f, + c = Golden_TestUnbinding_I_f(1)(Golden_TestUnbinding_I_f(2)(1)) } diff --git a/test/ps/packages.dhall b/test/ps/packages.dhall index 80d6676..a307bb6 100644 --- a/test/ps/packages.dhall +++ b/test/ps/packages.dhall @@ -1,5 +1,5 @@ let upstream = - https://github.com/Unisay/purescript-lua-package-sets/releases/download/psc-0.15.9-20230702/packages.dhall - sha256:c7a990e4a0100976f5d0b2e6dd2839391b5f960933bcfe72726f15923b2f9731 + https://github.com/Unisay/purescript-lua-package-sets/releases/download/psc-0.15.9-20230706/packages.dhall + sha256:de2604dd3797c479420a154955209e008fe2cd3fc8452a0bd4b32a2ca00a2ff6 in upstream diff --git a/treefmt.toml b/treefmt.toml index f983bf1..a4b1470 100644 --- a/treefmt.toml +++ b/treefmt.toml @@ -22,3 +22,7 @@ includes = ["*.cabal"] [formatter.nix] command = "nixfmt" includes = ["*.nix"] + +[formatter.yaml] +command = "yamlfmt" +includes = ["*.yaml", "*.yml" ]