-- SPDX-FileCopyrightText: 2021 Oxhead Alpha
-- SPDX-License-Identifier: LicenseRef-MIT-OA

-- | 'Instruction' datatype and its compilations.
--
-- The idea behind this module is to provide an intermediate representation that
-- can:
--
-- - be generated from the frontend freer monad
-- - be compiled to the backend 'IndigoState'
-- - be easy to analyze, manipulate and modify
--
-- This is meant to be the common ground for modular optimizations on the code
-- before this is handed off to the backend and eventually translated to
-- Michelson.

module Indigo.Compilation.Sequential
  ( Block
  , Instruction (..)

  , IndigoSeqCaseClause (..)
  , CaseBranch (..)

  -- * Translations
  , SequentialHooks (..)
  , stmtHookL
  , InstrCollector (..)
  , indigoMtoSequential
  , sequentialToLorentz

  -- * Case machinery
  , updateClauses
  , mapMClauses
  ) where

import Prelude

import Data.Vinyl.Core (RMap(..))

import Indigo.Backend
import Indigo.Common.SIS
import Indigo.Common.State hiding ((>>))
import Indigo.Common.State qualified as St
import Indigo.Common.Var
import Indigo.Compilation.Sequential.Types
import Indigo.Frontend.Internal.Statement qualified as S
import Indigo.Frontend.Program (IndigoM(..), interpretProgram)
import Indigo.Lorentz hiding (comment)
import Morley.Michelson.Typed qualified as MT

----------------------------------------------------------------------------
-- Translations
----------------------------------------------------------------------------

-- | Transformation from 'IndigoM' to a 'Block' of 'Instruction's.
--
-- Requires the first non-used 'RefId' and returns the next one.
indigoMtoSequential
  :: RefId
  -> SequentialHooks
  -> IndigoM a
  -> (Block, RefId)
indigoMtoSequential :: forall a. RefId -> SequentialHooks -> IndigoM a -> (Block, RefId)
indigoMtoSequential RefId
refId SequentialHooks
hook IndigoM a
code =
  let InstrCollector {Block
RefId
SequentialHooks
seqHooks :: InstrCollector -> SequentialHooks
instrList :: InstrCollector -> Block
nextRef :: InstrCollector -> RefId
seqHooks :: SequentialHooks
instrList :: Block
nextRef :: RefId
..} = (a, InstrCollector) -> InstrCollector
forall a b. (a, b) -> b
snd ((a, InstrCollector) -> InstrCollector)
-> (a, InstrCollector) -> InstrCollector
forall a b. (a -> b) -> a -> b
$ RefId -> SequentialHooks -> IndigoM a -> (a, InstrCollector)
forall a.
RefId -> SequentialHooks -> IndigoM a -> (a, InstrCollector)
instrCollect RefId
refId SequentialHooks
hook IndigoM a
code
  in (Block
instrList, RefId
nextRef)

-- | Collects instructions starting from an 'IndigoM'.
-- Returns an 'InstrCollector' as well as the return value for that 'IndigoM'.
instrCollect :: RefId -> SequentialHooks -> IndigoM a -> (a, InstrCollector)
instrCollect :: forall a.
RefId -> SequentialHooks -> IndigoM a -> (a, InstrCollector)
instrCollect RefId
ref SequentialHooks
hooks (IndigoM Program (StatementF IndigoM) a
imCode) =
  let instrColl :: InstrCollector
instrColl = RefId -> Block -> SequentialHooks -> InstrCollector
InstrCollector RefId
ref [] SequentialHooks
hooks
      (a
res, InstrCollector
resColl) = InstrCollector -> State InstrCollector a -> (a, InstrCollector)
forall s a. s -> State s a -> (a, s)
usingState InstrCollector
instrColl (State InstrCollector a -> (a, InstrCollector))
-> State InstrCollector a -> (a, InstrCollector)
forall a b. (a -> b) -> a -> b
$ (forall x.
 StatementF IndigoM x -> StateT InstrCollector Identity x)
-> Program (StatementF IndigoM) a -> State InstrCollector a
forall (m :: * -> *) (instr :: * -> *) a.
Monad m =>
(forall x. instr x -> m x) -> Program instr a -> m a
interpretProgram forall x. StatementF IndigoM x -> StateT InstrCollector Identity x
collectStatement Program (StatementF IndigoM) a
imCode
  in (a
res, RefId -> Block -> SequentialHooks -> InstrCollector
InstrCollector (InstrCollector -> RefId
nextRef InstrCollector
resColl) (Block -> Block
forall a. [a] -> [a]
reverse (Block -> Block) -> Block -> Block
forall a b. (a -> b) -> a -> b
$ InstrCollector -> Block
instrList InstrCollector
resColl) SequentialHooks
hooks)

-- | Collects instructions starting from 'S.StatementF'.
-- IMPORTANT: the instructions are collected in the opposite order (as a stack).
collectStatement :: S.StatementF IndigoM a -> State InstrCollector a
collectStatement :: forall x. StatementF IndigoM x -> StateT InstrCollector Identity x
collectStatement = \case
  S.LiftIndigoState forall (inp :: [*]). SomeIndigoState inp
is -> Instruction -> State InstrCollector ()
appendNewInstr (Instruction -> State InstrCollector ())
-> Instruction -> State InstrCollector ()
forall a b. (a -> b) -> a -> b
$ (forall (inp :: [*]). SomeIndigoState inp) -> Instruction
LiftIndigoState forall (inp :: [*]). SomeIndigoState inp
is
  S.CalledFrom CallStack
callStk IndigoM a
iM -> do
    InstrCollector RefId
nRef Block
_prevInstrs SequentialHooks
hooks <- StateT InstrCollector Identity InstrCollector
forall s (m :: * -> *). MonadState s m => m s
get
    let (a
res, InstrCollector
inner) = RefId -> SequentialHooks -> IndigoM a -> (a, InstrCollector)
forall a.
RefId -> SequentialHooks -> IndigoM a -> (a, InstrCollector)
instrCollect RefId
nRef SequentialHooks
hooks IndigoM a
iM
    (InstrCollector -> InstrCollector) -> State InstrCollector ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((InstrCollector -> InstrCollector) -> State InstrCollector ())
-> (InstrCollector -> InstrCollector) -> State InstrCollector ()
forall a b. (a -> b) -> a -> b
$ \InstrCollector
s -> InstrCollector
s {nextRef :: RefId
nextRef = InstrCollector -> RefId
nextRef InstrCollector
inner}
    a
res a -> State InstrCollector () -> State InstrCollector a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ SequentialHooks -> CallStack -> Block -> State InstrCollector ()
shStmtHook SequentialHooks
hooks CallStack
callStk (InstrCollector -> Block
instrList InstrCollector
inner)
  S.NewVar Expr x
ex -> do
    Var x
var <- State InstrCollector (Var x)
forall {k} (a :: k). State InstrCollector (Var a)
mkNextVar
    Instruction -> State InstrCollector ()
appendNewInstr (Instruction -> State InstrCollector ())
-> Instruction -> State InstrCollector ()
forall a b. (a -> b) -> a -> b
$ Var x -> Expr x -> Instruction
forall x. KnownValue x => Var x -> Expr x -> Instruction
AssignVar Var x
var Expr x
ex
    Var x -> State InstrCollector (Var x)
forall (m :: * -> *) a. Monad m => a -> m a
return Var x
var
  S.SetVar Var x
vx Expr x
ex -> Instruction -> State InstrCollector ()
appendNewInstr (Instruction -> State InstrCollector ())
-> Instruction -> State InstrCollector ()
forall a b. (a -> b) -> a -> b
$ Var x -> Expr x -> Instruction
forall x. KnownValue x => Var x -> Expr x -> Instruction
SetVar Var x
vx Expr x
ex
  S.VarModification '[y, x] :-> '[x]
upd Var x
vx Expr y
ey -> Instruction -> State InstrCollector ()
appendNewInstr (Instruction -> State InstrCollector ())
-> Instruction -> State InstrCollector ()
forall a b. (a -> b) -> a -> b
$ ('[y, x] :-> '[x]) -> Var x -> Expr y -> Instruction
forall x y.
(IsObject x, KnownValue y) =>
('[y, x] :-> '[x]) -> Var x -> Expr y -> Instruction
VarModification '[y, x] :-> '[x]
upd Var x
vx Expr y
ey
  S.SetField Var dt
vStore Label fname
fname Expr ftype
exF -> Instruction -> State InstrCollector ()
appendNewInstr (Instruction -> State InstrCollector ())
-> Instruction -> State InstrCollector ()
forall a b. (a -> b) -> a -> b
$ Var dt -> Label fname -> Expr ftype -> Instruction
forall store (fname :: Symbol) ftype.
(HasField store fname ftype, IsObject store, IsObject ftype) =>
Var store -> Label fname -> Expr ftype -> Instruction
SetField Var dt
vStore Label fname
fname Expr ftype
exF

  S.LambdaCall1 LambdaKind st arg res extra
lKind String
lName Var arg -> IndigoM res
vIm Expr arg
ex -> LambdaKind st arg res extra
-> ((ScopeCodeGen res, KnownValue arg, Typeable res,
     CreateLambda1CGeneric extra arg res) =>
    State InstrCollector a)
-> State InstrCollector a
forall st arg res (extra :: [*]) r.
LambdaKind st arg res extra
-> ((ScopeCodeGen res, KnownValue arg, Typeable res,
     CreateLambda1CGeneric extra arg res) =>
    r)
-> r
withLambdaKind LambdaKind st arg res extra
lKind (((ScopeCodeGen res, KnownValue arg, Typeable res,
   CreateLambda1CGeneric extra arg res) =>
  State InstrCollector a)
 -> State InstrCollector a)
-> ((ScopeCodeGen res, KnownValue arg, Typeable res,
     CreateLambda1CGeneric extra arg res) =>
    State InstrCollector a)
-> State InstrCollector a
forall a b. (a -> b) -> a -> b
$ do
    (Var arg
var, Block
block, res
ret, a
retVars) <- (Var arg -> IndigoM res)
-> State
     InstrCollector
     (Var arg, Block, res, RetVars' (ClassifyReturnValue res) res)
forall {k} ret (arg :: k).
ScopeCodeGen ret =>
(Var arg -> IndigoM ret)
-> State InstrCollector (Var arg, Block, ret, RetVars ret)
collectInLambda Var arg -> IndigoM res
vIm
    Instruction -> State InstrCollector ()
appendNewInstr (Instruction -> State InstrCollector ())
-> Instruction -> State InstrCollector ()
forall a b. (a -> b) -> a -> b
$ LambdaKind st arg res extra
-> String
-> Expr arg
-> Var arg
-> Block
-> res
-> RetVars' (ClassifyReturnValue res) res
-> Instruction
forall st arg ret (extra :: [*]).
LambdaKind st arg ret extra
-> String
-> Expr arg
-> Var arg
-> Block
-> ret
-> RetVars ret
-> Instruction
LambdaCall1 LambdaKind st arg res extra
lKind String
lName Expr arg
ex Var arg
var Block
block res
ret a
RetVars' (ClassifyReturnValue res) res
retVars
    a -> State InstrCollector a
forall (m :: * -> *) a. Monad m => a -> m a
return a
retVars

  S.Scope (IndigoM a1
iM :: IndigoM ret) -> do
    a
retVars <- forall ret (m :: * -> *).
(ReturnableValue ret, Monad m) =>
(forall x. m (Var x)) -> m (RetVars ret)
allocateVars @ret forall x. StateT InstrCollector Identity (Var x)
forall {k} (a :: k). State InstrCollector (Var a)
mkNextVar
    (a1
ret, Block
block) <- IndigoM a1 -> State InstrCollector (a1, Block)
forall ret. IndigoM ret -> State InstrCollector (ret, Block)
collectInner IndigoM a1
iM
    Instruction -> State InstrCollector ()
appendNewInstr (Instruction -> State InstrCollector ())
-> Instruction -> State InstrCollector ()
forall a b. (a -> b) -> a -> b
$ Block -> a1 -> RetVars' (ClassifyReturnValue a1) a1 -> Instruction
forall ret.
ScopeCodeGen ret =>
Block -> ret -> RetVars ret -> Instruction
Scope Block
block a1
ret a
RetVars' (ClassifyReturnValue a1) a1
retVars
    a -> State InstrCollector a
forall (m :: * -> *) a. Monad m => a -> m a
return a
retVars
  S.If Expr Bool
ex (IndigoM a1
iMa :: IndigoM ret) IndigoM b
iMb -> do
    a
retVars <- forall ret (m :: * -> *).
(ReturnableValue ret, Monad m) =>
(forall x. m (Var x)) -> m (RetVars ret)
allocateVars @ret forall x. StateT InstrCollector Identity (Var x)
forall {k} (a :: k). State InstrCollector (Var a)
mkNextVar
    (a1
retA, Block
blockA) <- IndigoM a1 -> State InstrCollector (a1, Block)
forall ret. IndigoM ret -> State InstrCollector (ret, Block)
collectInner IndigoM a1
iMa
    (b
retB, Block
blockB) <- IndigoM b -> State InstrCollector (b, Block)
forall ret. IndigoM ret -> State InstrCollector (ret, Block)
collectInner IndigoM b
iMb
    Instruction -> State InstrCollector ()
appendNewInstr (Instruction -> State InstrCollector ())
-> Instruction -> State InstrCollector ()
forall a b. (a -> b) -> a -> b
$ Expr Bool
-> Block
-> a1
-> Block
-> b
-> RetVars' (ClassifyReturnValue a1) a1
-> Instruction
forall a b.
IfConstraint a b =>
Expr Bool -> Block -> a -> Block -> b -> RetVars a -> Instruction
If Expr Bool
ex Block
blockA a1
retA Block
blockB b
retB a
RetVars' (ClassifyReturnValue a1) a1
retVars
    a -> State InstrCollector a
forall (m :: * -> *) a. Monad m => a -> m a
return a
retVars
  S.IfSome Expr (Maybe x)
ex (Var x -> IndigoM a1
vIMa :: Var x -> IndigoM ret) IndigoM b
iMb -> do
    a
retVars <- forall ret (m :: * -> *).
(ReturnableValue ret, Monad m) =>
(forall x. m (Var x)) -> m (RetVars ret)
allocateVars @ret forall x. StateT InstrCollector Identity (Var x)
forall {k} (a :: k). State InstrCollector (Var a)
mkNextVar
    Var x
varX <- State InstrCollector (Var x)
forall {k} (a :: k). State InstrCollector (Var a)
mkNextVar
    (a1
retA, Block
blockA) <- IndigoM a1 -> State InstrCollector (a1, Block)
forall ret. IndigoM ret -> State InstrCollector (ret, Block)
collectInner (IndigoM a1 -> State InstrCollector (a1, Block))
-> IndigoM a1 -> State InstrCollector (a1, Block)
forall a b. (a -> b) -> a -> b
$ Var x -> IndigoM a1
vIMa Var x
varX
    (b
retB, Block
blockB) <- IndigoM b -> State InstrCollector (b, Block)
forall ret. IndigoM ret -> State InstrCollector (ret, Block)
collectInner IndigoM b
iMb
    Instruction -> State InstrCollector ()
appendNewInstr (Instruction -> State InstrCollector ())
-> Instruction -> State InstrCollector ()
forall a b. (a -> b) -> a -> b
$ Expr (Maybe x)
-> Var x
-> Block
-> a1
-> Block
-> b
-> RetVars' (ClassifyReturnValue a1) a1
-> Instruction
forall a b x.
(IfConstraint a b, KnownValue x) =>
Expr (Maybe x)
-> Var x -> Block -> a -> Block -> b -> RetVars a -> Instruction
IfSome Expr (Maybe x)
ex Var x
varX Block
blockA a1
retA Block
blockB b
retB a
RetVars' (ClassifyReturnValue a1) a1
retVars
    a -> State InstrCollector a
forall (m :: * -> *) a. Monad m => a -> m a
return a
retVars
  S.IfRight Expr (Either y x)
ex (Var x -> IndigoM a1
vIMa :: Var x -> IndigoM ret) Var y -> IndigoM b
vIMb -> do
    a
retVars <- forall ret (m :: * -> *).
(ReturnableValue ret, Monad m) =>
(forall x. m (Var x)) -> m (RetVars ret)
allocateVars @ret forall x. StateT InstrCollector Identity (Var x)
forall {k} (a :: k). State InstrCollector (Var a)
mkNextVar
    Var x
varR <- State InstrCollector (Var x)
forall {k} (a :: k). State InstrCollector (Var a)
mkNextVar
    (a1
retA, Block
blockA) <- IndigoM a1 -> State InstrCollector (a1, Block)
forall ret. IndigoM ret -> State InstrCollector (ret, Block)
collectInner (IndigoM a1 -> State InstrCollector (a1, Block))
-> IndigoM a1 -> State InstrCollector (a1, Block)
forall a b. (a -> b) -> a -> b
$ Var x -> IndigoM a1
vIMa Var x
varR
    Var y
varL <- State InstrCollector (Var y)
forall {k} (a :: k). State InstrCollector (Var a)
mkNextVar
    (b
retB, Block
blockB) <- IndigoM b -> State InstrCollector (b, Block)
forall ret. IndigoM ret -> State InstrCollector (ret, Block)
collectInner (IndigoM b -> State InstrCollector (b, Block))
-> IndigoM b -> State InstrCollector (b, Block)
forall a b. (a -> b) -> a -> b
$ Var y -> IndigoM b
vIMb Var y
varL
    Instruction -> State InstrCollector ()
appendNewInstr (Instruction -> State InstrCollector ())
-> Instruction -> State InstrCollector ()
forall a b. (a -> b) -> a -> b
$ Expr (Either y x)
-> Var x
-> Block
-> a1
-> Var y
-> Block
-> b
-> RetVars' (ClassifyReturnValue a1) a1
-> Instruction
forall a b r l.
(IfConstraint a b, KnownValue r, KnownValue l) =>
Expr (Either l r)
-> Var r
-> Block
-> a
-> Var l
-> Block
-> b
-> RetVars a
-> Instruction
IfRight Expr (Either y x)
ex Var x
varR Block
blockA a1
retA Var y
varL Block
blockB b
retB a
RetVars' (ClassifyReturnValue a1) a1
retVars
    a -> State InstrCollector a
forall (m :: * -> *) a. Monad m => a -> m a
return a
retVars
  S.IfCons Expr (List x)
ex (Var x -> Var (List x) -> IndigoM a1
vvIMa :: Var x -> Var (List x) -> IndigoM ret) IndigoM b
iMb -> do
    a
retVars <- forall ret (m :: * -> *).
(ReturnableValue ret, Monad m) =>
(forall x. m (Var x)) -> m (RetVars ret)
allocateVars @ret forall x. StateT InstrCollector Identity (Var x)
forall {k} (a :: k). State InstrCollector (Var a)
mkNextVar
    Var x
varX <- State InstrCollector (Var x)
forall {k} (a :: k). State InstrCollector (Var a)
mkNextVar
    Var (List x)
varLX <- State InstrCollector (Var (List x))
forall {k} (a :: k). State InstrCollector (Var a)
mkNextVar
    (a1
retA, Block
blockA) <- IndigoM a1 -> State InstrCollector (a1, Block)
forall ret. IndigoM ret -> State InstrCollector (ret, Block)
collectInner (IndigoM a1 -> State InstrCollector (a1, Block))
-> IndigoM a1 -> State InstrCollector (a1, Block)
forall a b. (a -> b) -> a -> b
$ Var x -> Var (List x) -> IndigoM a1
vvIMa Var x
varX Var (List x)
varLX
    (b
retB, Block
blockB) <- IndigoM b -> State InstrCollector (b, Block)
forall ret. IndigoM ret -> State InstrCollector (ret, Block)
collectInner IndigoM b
iMb
    Instruction -> State InstrCollector ()
appendNewInstr (Instruction -> State InstrCollector ())
-> Instruction -> State InstrCollector ()
forall a b. (a -> b) -> a -> b
$ Expr (List x)
-> Var x
-> Var (List x)
-> Block
-> a1
-> Block
-> b
-> RetVars' (ClassifyReturnValue a1) a1
-> Instruction
forall a b x.
(IfConstraint a b, KnownValue x) =>
Expr (List x)
-> Var x
-> Var (List x)
-> Block
-> a
-> Block
-> b
-> RetVars a
-> Instruction
IfCons Expr (List x)
ex Var x
varX Var (List x)
varLX Block
blockA a1
retA Block
blockB b
retB a
RetVars' (ClassifyReturnValue a1) a1
retVars
    a -> State InstrCollector a
forall (m :: * -> *) a. Monad m => a -> m a
return a
retVars

  S.Case Expr dt
grd clauses
clauses -> do
    a
retVars <- Rec (IndigoMCaseClauseL IndigoM ret) (GCaseClauses (Rep dt) '[])
-> State InstrCollector (RetVars' (ClassifyReturnValue ret) ret)
forall ret (dt :: [CaseClauseParam]).
ReturnableValue ret =>
Rec (IndigoMCaseClauseL IndigoM ret) dt
-> State InstrCollector (RetVars ret)
allocateClausesVars clauses
Rec (IndigoMCaseClauseL IndigoM ret) (GCaseClauses (Rep dt) '[])
clauses
    Rec (IndigoSeqCaseClause ret) (GCaseClauses (Rep dt) '[])
blockClauses <- Rec (IndigoMCaseClauseL IndigoM ret) (GCaseClauses (Rep dt) '[])
-> State
     InstrCollector
     (Rec (IndigoSeqCaseClause ret) (GCaseClauses (Rep dt) '[]))
forall ret (dt :: [CaseClauseParam]).
Rec (IndigoMCaseClauseL IndigoM ret) dt
-> State InstrCollector (Rec (IndigoSeqCaseClause ret) dt)
collectClauses clauses
Rec (IndigoMCaseClauseL IndigoM ret) (GCaseClauses (Rep dt) '[])
clauses
    Instruction -> State InstrCollector ()
appendNewInstr (Instruction -> State InstrCollector ())
-> Instruction -> State InstrCollector ()
forall a b. (a -> b) -> a -> b
$ Expr dt
-> Rec (IndigoSeqCaseClause ret) (GCaseClauses (Rep dt) '[])
-> RetVars' (ClassifyReturnValue ret) ret
-> Instruction
forall dt ret clauses.
CaseCommon dt ret clauses =>
Expr dt -> clauses -> RetVars ret -> Instruction
Case Expr dt
grd Rec (IndigoSeqCaseClause ret) (GCaseClauses (Rep dt) '[])
blockClauses a
RetVars' (ClassifyReturnValue ret) ret
retVars
    a -> State InstrCollector a
forall (m :: * -> *) a. Monad m => a -> m a
return a
retVars
  S.EntryCase Proxy entrypointKind
proxy Expr dt
grd clauses
clauses -> do
    a
retVars <- Rec (IndigoMCaseClauseL IndigoM ret) (GCaseClauses (Rep dt) '[])
-> State InstrCollector (RetVars' (ClassifyReturnValue ret) ret)
forall ret (dt :: [CaseClauseParam]).
ReturnableValue ret =>
Rec (IndigoMCaseClauseL IndigoM ret) dt
-> State InstrCollector (RetVars ret)
allocateClausesVars clauses
Rec (IndigoMCaseClauseL IndigoM ret) (GCaseClauses (Rep dt) '[])
clauses
    Rec (IndigoSeqCaseClause ret) (GCaseClauses (Rep dt) '[])
blockClauses <- Rec (IndigoMCaseClauseL IndigoM ret) (GCaseClauses (Rep dt) '[])
-> State
     InstrCollector
     (Rec (IndigoSeqCaseClause ret) (GCaseClauses (Rep dt) '[]))
forall ret (dt :: [CaseClauseParam]).
Rec (IndigoMCaseClauseL IndigoM ret) dt
-> State InstrCollector (Rec (IndigoSeqCaseClause ret) dt)
collectClauses clauses
Rec (IndigoMCaseClauseL IndigoM ret) (GCaseClauses (Rep dt) '[])
clauses
    Instruction -> State InstrCollector ()
appendNewInstr (Instruction -> State InstrCollector ())
-> Instruction -> State InstrCollector ()
forall a b. (a -> b) -> a -> b
$ Proxy entrypointKind
-> Expr dt
-> Rec (IndigoSeqCaseClause ret) (GCaseClauses (Rep dt) '[])
-> RetVars' (ClassifyReturnValue ret) ret
-> Instruction
forall dt ret clauses entryPointKind.
(CaseCommon dt ret clauses,
 DocumentEntrypoints entryPointKind dt) =>
Proxy entryPointKind
-> Expr dt -> clauses -> RetVars ret -> Instruction
EntryCase Proxy entrypointKind
proxy Expr dt
grd Rec (IndigoSeqCaseClause ret) (GCaseClauses (Rep dt) '[])
blockClauses a
RetVars' (ClassifyReturnValue ret) ret
retVars
    a -> State InstrCollector a
forall (m :: * -> *) a. Monad m => a -> m a
return a
retVars
  S.EntryCaseSimple Expr cp
grd clauses
clauses -> do
    a
retVars <- Rec (IndigoMCaseClauseL IndigoM ret) (GCaseClauses (Rep cp) '[])
-> State InstrCollector (RetVars' (ClassifyReturnValue ret) ret)
forall ret (dt :: [CaseClauseParam]).
ReturnableValue ret =>
Rec (IndigoMCaseClauseL IndigoM ret) dt
-> State InstrCollector (RetVars ret)
allocateClausesVars clauses
Rec (IndigoMCaseClauseL IndigoM ret) (GCaseClauses (Rep cp) '[])
clauses
    Rec (IndigoSeqCaseClause ret) (GCaseClauses (Rep cp) '[])
blockClauses <- Rec (IndigoMCaseClauseL IndigoM ret) (GCaseClauses (Rep cp) '[])
-> State
     InstrCollector
     (Rec (IndigoSeqCaseClause ret) (GCaseClauses (Rep cp) '[]))
forall ret (dt :: [CaseClauseParam]).
Rec (IndigoMCaseClauseL IndigoM ret) dt
-> State InstrCollector (Rec (IndigoSeqCaseClause ret) dt)
collectClauses clauses
Rec (IndigoMCaseClauseL IndigoM ret) (GCaseClauses (Rep cp) '[])
clauses
    Instruction -> State InstrCollector ()
appendNewInstr (Instruction -> State InstrCollector ())
-> Instruction -> State InstrCollector ()
forall a b. (a -> b) -> a -> b
$ Expr cp
-> Rec (IndigoSeqCaseClause ret) (GCaseClauses (Rep cp) '[])
-> RetVars' (ClassifyReturnValue ret) ret
-> Instruction
forall dt ret clauses.
(CaseCommon dt ret clauses,
 DocumentEntrypoints PlainEntrypointsKind dt, NiceParameterFull dt,
 RequireFlatParamEps dt) =>
Expr dt -> clauses -> RetVars ret -> Instruction
EntryCaseSimple Expr cp
grd Rec (IndigoSeqCaseClause ret) (GCaseClauses (Rep cp) '[])
blockClauses a
RetVars' (ClassifyReturnValue ret) ret
retVars
    a -> State InstrCollector a
forall (m :: * -> *) a. Monad m => a -> m a
return a
retVars

  S.While Expr Bool
ex IndigoM ()
iM -> do
    ((), Block
block) <- IndigoM () -> State InstrCollector ((), Block)
forall ret. IndigoM ret -> State InstrCollector (ret, Block)
collectInner IndigoM ()
iM
    Instruction -> State InstrCollector ()
appendNewInstr (Instruction -> State InstrCollector ())
-> Instruction -> State InstrCollector ()
forall a b. (a -> b) -> a -> b
$ Expr Bool -> Block -> Instruction
While Expr Bool
ex Block
block
  S.WhileLeft Expr (Either y x)
ex Var y -> IndigoM ()
vIm -> do
    Var y
varL <- State InstrCollector (Var y)
forall {k} (a :: k). State InstrCollector (Var a)
mkNextVar
    Var x
varR <- State InstrCollector (Var x)
forall {k} (a :: k). State InstrCollector (Var a)
mkNextVar
    ((), Block
block) <- IndigoM () -> State InstrCollector ((), Block)
forall ret. IndigoM ret -> State InstrCollector (ret, Block)
collectInner (IndigoM () -> State InstrCollector ((), Block))
-> IndigoM () -> State InstrCollector ((), Block)
forall a b. (a -> b) -> a -> b
$ Var y -> IndigoM ()
vIm Var y
varL
    Instruction -> State InstrCollector ()
appendNewInstr (Instruction -> State InstrCollector ())
-> Instruction -> State InstrCollector ()
forall a b. (a -> b) -> a -> b
$ Expr (Either y x) -> Var y -> Block -> Var x -> Instruction
forall l r.
(KnownValue l, KnownValue r) =>
Expr (Either l r) -> Var l -> Block -> Var r -> Instruction
WhileLeft Expr (Either y x)
ex Var y
varL Block
block Var x
varR
    Var x -> State InstrCollector (Var x)
forall (m :: * -> *) a. Monad m => a -> m a
return Var x
varR
  S.ForEach Expr a1
ex Var (IterOpElHs a1) -> IndigoM ()
vIm -> do
    Var (IterOpElHs a1)
varIop <- State InstrCollector (Var (IterOpElHs a1))
forall {k} (a :: k). State InstrCollector (Var a)
mkNextVar
    ((), Block
block) <- IndigoM () -> State InstrCollector ((), Block)
forall ret. IndigoM ret -> State InstrCollector (ret, Block)
collectInner (IndigoM () -> State InstrCollector ((), Block))
-> IndigoM () -> State InstrCollector ((), Block)
forall a b. (a -> b) -> a -> b
$ Var (IterOpElHs a1) -> IndigoM ()
vIm Var (IterOpElHs a1)
varIop
    Instruction -> State InstrCollector ()
appendNewInstr (Instruction -> State InstrCollector ())
-> Instruction -> State InstrCollector ()
forall a b. (a -> b) -> a -> b
$ Expr a1 -> Var (IterOpElHs a1) -> Block -> Instruction
forall a.
(IterOpHs a, KnownValue (IterOpElHs a)) =>
Expr a -> Var (IterOpElHs a) -> Block -> Instruction
ForEach Expr a1
ex Var (IterOpElHs a1)
varIop Block
block

  S.ContractName Text
tx IndigoM ()
iM -> do
    ((), Block
block) <- IndigoM () -> State InstrCollector ((), Block)
forall ret. IndigoM ret -> State InstrCollector (ret, Block)
collectInner IndigoM ()
iM
    Instruction -> State InstrCollector ()
appendNewInstr (Instruction -> State InstrCollector ())
-> Instruction -> State InstrCollector ()
forall a b. (a -> b) -> a -> b
$ Text -> Block -> Instruction
ContractName Text
tx Block
block
  S.DocGroup SubDoc -> di
dg IndigoM ()
iM -> do
    ((), Block
block) <- IndigoM () -> State InstrCollector ((), Block)
forall ret. IndigoM ret -> State InstrCollector (ret, Block)
collectInner IndigoM ()
iM
    Instruction -> State InstrCollector ()
appendNewInstr (Instruction -> State InstrCollector ())
-> Instruction -> State InstrCollector ()
forall a b. (a -> b) -> a -> b
$ (SubDoc -> di) -> Block -> Instruction
forall di. DocItem di => (SubDoc -> di) -> Block -> Instruction
DocGroup SubDoc -> di
dg Block
block
  S.ContractGeneral IndigoM ()
iM -> do
    ((), Block
block) <- IndigoM () -> State InstrCollector ((), Block)
forall ret. IndigoM ret -> State InstrCollector (ret, Block)
collectInner IndigoM ()
iM
    Instruction -> State InstrCollector ()
appendNewInstr (Instruction -> State InstrCollector ())
-> Instruction -> State InstrCollector ()
forall a b. (a -> b) -> a -> b
$ Block -> Instruction
ContractGeneral Block
block
  S.FinalizeParamCallingDoc Var cp -> IndigoM ()
vIm Expr cp
param -> do
    Var cp
varCp <- State InstrCollector (Var cp)
forall {k} (a :: k). State InstrCollector (Var a)
mkNextVar
    ((), Block
block) <- IndigoM () -> State InstrCollector ((), Block)
forall ret. IndigoM ret -> State InstrCollector (ret, Block)
collectInner (IndigoM () -> State InstrCollector ((), Block))
-> IndigoM () -> State InstrCollector ((), Block)
forall a b. (a -> b) -> a -> b
$ Var cp -> IndigoM ()
vIm Var cp
varCp
    Instruction -> State InstrCollector ()
appendNewInstr (Instruction -> State InstrCollector ())
-> Instruction -> State InstrCollector ()
forall a b. (a -> b) -> a -> b
$ Var cp -> Block -> Expr cp -> Instruction
forall cp.
(NiceParameterFull cp, RequireSumType cp) =>
Var cp -> Block -> Expr cp -> Instruction
FinalizeParamCallingDoc Var cp
varCp Block
block Expr cp
param

  S.TransferTokens Expr p
ex Expr Mutez
exm Expr (ContractRef p)
exc ->
    Instruction -> State InstrCollector ()
appendNewInstr (Instruction -> State InstrCollector ())
-> Instruction -> State InstrCollector ()
forall a b. (a -> b) -> a -> b
$ Expr p -> Expr Mutez -> Expr (ContractRef p) -> Instruction
forall p.
(NiceParameter p, HasSideEffects, IsNotInView) =>
Expr p -> Expr Mutez -> Expr (ContractRef p) -> Instruction
TransferTokens Expr p
ex Expr Mutez
exm Expr (ContractRef p)
exc
  S.SetDelegate Expr (Maybe KeyHash)
ex ->
    Instruction -> State InstrCollector ()
appendNewInstr (Instruction -> State InstrCollector ())
-> Instruction -> State InstrCollector ()
forall a b. (a -> b) -> a -> b
$ (HasSideEffects, IsNotInView) =>
Expr (Maybe KeyHash) -> Instruction
Expr (Maybe KeyHash) -> Instruction
SetDelegate Expr (Maybe KeyHash)
ex
  S.CreateContract Contract param st vd
ctrc Expr (Maybe KeyHash)
exk Expr Mutez
exm Expr st
exs -> do
    Var Address
varAddr <- State InstrCollector (Var Address)
forall {k} (a :: k). State InstrCollector (Var a)
mkNextVar
    Instruction -> State InstrCollector ()
appendNewInstr (Instruction -> State InstrCollector ())
-> Instruction -> State InstrCollector ()
forall a b. (a -> b) -> a -> b
$ Contract param st vd
-> Expr (Maybe KeyHash)
-> Expr Mutez
-> Expr st
-> Var Address
-> Instruction
forall s p vd.
(HasSideEffects, NiceStorage s, NiceParameterFull p,
 NiceViewsDescriptor vd, Typeable vd, IsNotInView) =>
Contract p s vd
-> Expr (Maybe KeyHash)
-> Expr Mutez
-> Expr s
-> Var Address
-> Instruction
CreateContract Contract param st vd
ctrc Expr (Maybe KeyHash)
exk Expr Mutez
exm Expr st
exs Var Address
varAddr
    Var Address -> State InstrCollector (Var Address)
forall (m :: * -> *) a. Monad m => a -> m a
return Var Address
varAddr
  S.SelfCalling Proxy p
proxy EntrypointRef mname
ep -> do
    Var (ContractRef (GetEntrypointArgCustom p mname))
varCR <- State
  InstrCollector (Var (ContractRef (GetEntrypointArgCustom p mname)))
forall {k} (a :: k). State InstrCollector (Var a)
mkNextVar
    Instruction -> State InstrCollector ()
appendNewInstr (Instruction -> State InstrCollector ())
-> Instruction -> State InstrCollector ()
forall a b. (a -> b) -> a -> b
$ Proxy p
-> EntrypointRef mname
-> Var (ContractRef (GetEntrypointArgCustom p mname))
-> Instruction
forall p (mname :: Maybe Symbol).
(NiceParameterFull p, KnownValue (GetEntrypointArgCustom p mname),
 IsoValue (ContractRef (GetEntrypointArgCustom p mname)),
 IsNotInView) =>
Proxy p
-> EntrypointRef mname
-> Var (ContractRef (GetEntrypointArgCustom p mname))
-> Instruction
SelfCalling Proxy p
proxy EntrypointRef mname
ep Var (ContractRef (GetEntrypointArgCustom p mname))
varCR
    Var (ContractRef (GetEntrypointArgCustom p mname))
-> State
     InstrCollector (Var (ContractRef (GetEntrypointArgCustom p mname)))
forall (m :: * -> *) a. Monad m => a -> m a
return Var (ContractRef (GetEntrypointArgCustom p mname))
varCR
  S.ContractCalling Proxy (cp, vd)
proxy epRef
epRef Expr addr
exAddr -> do
    Var (Maybe (ContractRef epArg))
varMcr <- State InstrCollector (Var (Maybe (ContractRef epArg)))
forall {k} (a :: k). State InstrCollector (Var a)
mkNextVar
    Instruction -> State InstrCollector ()
appendNewInstr (Instruction -> State InstrCollector ())
-> Instruction -> State InstrCollector ()
forall a b. (a -> b) -> a -> b
$ Proxy (cp, vd)
-> epRef
-> Expr addr
-> Var (Maybe (ContractRef epArg))
-> Instruction
forall cp epRef epArg vd addr.
(HasEntrypointArg cp epRef epArg, ToTAddress cp vd addr,
 ToT addr ~ ToT Address, KnownValue epArg,
 IsoValue (ContractRef epArg)) =>
Proxy (cp, vd)
-> epRef
-> Expr addr
-> Var (Maybe (ContractRef epArg))
-> Instruction
ContractCalling Proxy (cp, vd)
proxy epRef
epRef Expr addr
exAddr Var (Maybe (ContractRef epArg))
varMcr
    Var (Maybe (ContractRef epArg))
-> State InstrCollector (Var (Maybe (ContractRef epArg)))
forall (m :: * -> *) a. Monad m => a -> m a
return Var (Maybe (ContractRef epArg))
varMcr
  S.Emit FieldAnn
tag Expr a1
ex ->
    Instruction -> State InstrCollector ()
appendNewInstr (Instruction -> State InstrCollector ())
-> Instruction -> State InstrCollector ()
forall a b. (a -> b) -> a -> b
$ FieldAnn -> Expr a1 -> Instruction
forall a.
(HasSideEffects, NicePackedValue a, HasAnnotation a) =>
FieldAnn -> Expr a -> Instruction
Emit FieldAnn
tag Expr a1
ex

  S.Fail (Proxy ret
_ :: Proxy ret) forall (inp :: [*]). SomeIndigoState inp
failure -> do
    Instruction -> State InstrCollector ()
appendNewInstr (Instruction -> State InstrCollector ())
-> Instruction -> State InstrCollector ()
forall a b. (a -> b) -> a -> b
$ (forall (inp :: [*]). SomeIndigoState inp) -> Instruction
Fail forall (inp :: [*]). SomeIndigoState inp
failure
    -- Note: because this is a failing instr, this vars are effectively never used
    forall ret (m :: * -> *).
(ReturnableValue ret, Monad m) =>
(forall x. m (Var x)) -> m (RetVars ret)
allocateVars @ret forall x. StateT InstrCollector Identity (Var x)
forall {k} (a :: k). State InstrCollector (Var a)
mkNextVar
  S.FailOver (Proxy ret
_ :: Proxy ret) forall (inp :: [*]). Expr a1 -> SomeIndigoState inp
failure Expr a1
ex -> do
    Instruction -> State InstrCollector ()
appendNewInstr (Instruction -> State InstrCollector ())
-> Instruction -> State InstrCollector ()
forall a b. (a -> b) -> a -> b
$ (forall (inp :: [*]). Expr a1 -> SomeIndigoState inp)
-> Expr a1 -> Instruction
forall a.
(forall (inp :: [*]). Expr a -> SomeIndigoState inp)
-> Expr a -> Instruction
FailOver forall (inp :: [*]). Expr a1 -> SomeIndigoState inp
failure Expr a1
ex
    -- Note: because this is a failing instr, this vars are effectively never used
    forall ret (m :: * -> *).
(ReturnableValue ret, Monad m) =>
(forall x. m (Var x)) -> m (RetVars ret)
allocateVars @ret forall x. StateT InstrCollector Identity (Var x)
forall {k} (a :: k). State InstrCollector (Var a)
mkNextVar

-- | Continues collecting 'Instruction's from an inner 'IndigoM' (e.g. scoped).
-- This keeps advancing the ref counter as well.
collectInner :: IndigoM ret -> State InstrCollector (ret, Block)
collectInner :: forall ret. IndigoM ret -> State InstrCollector (ret, Block)
collectInner IndigoM ret
iM = do
  InstrCollector
iColl <- StateT InstrCollector Identity InstrCollector
forall s (m :: * -> *). MonadState s m => m s
get
  let (ret
ret, InstrCollector RefId
newRef Block
block SequentialHooks
_) = RefId -> SequentialHooks -> IndigoM ret -> (ret, InstrCollector)
forall a.
RefId -> SequentialHooks -> IndigoM a -> (a, InstrCollector)
instrCollect (InstrCollector -> RefId
nextRef InstrCollector
iColl) (InstrCollector -> SequentialHooks
seqHooks InstrCollector
iColl) IndigoM ret
iM
  InstrCollector -> State InstrCollector ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put (InstrCollector -> State InstrCollector ())
-> InstrCollector -> State InstrCollector ()
forall a b. (a -> b) -> a -> b
$ InstrCollector
iColl {nextRef :: RefId
nextRef = RefId
newRef}
  (ret, Block) -> State InstrCollector (ret, Block)
forall (m :: * -> *) a. Monad m => a -> m a
return (ret
ret, Block
block)

-- | Just a common set of steps used by collection of single-arg lambda's values.
collectInLambda
  :: ScopeCodeGen ret
  => (Var arg -> IndigoM ret)
  -> State InstrCollector (Var arg, Block, ret, RetVars ret)
collectInLambda :: forall {k} ret (arg :: k).
ScopeCodeGen ret =>
(Var arg -> IndigoM ret)
-> State InstrCollector (Var arg, Block, ret, RetVars ret)
collectInLambda Var arg -> IndigoM ret
vIm = do
  Var arg
var <- State InstrCollector (Var arg)
forall {k} (a :: k). State InstrCollector (Var a)
mkNextVar
  (ret
ret :: ret, Block
block) <- IndigoM ret -> State InstrCollector (ret, Block)
forall ret. IndigoM ret -> State InstrCollector (ret, Block)
collectInner (IndigoM ret -> State InstrCollector (ret, Block))
-> IndigoM ret -> State InstrCollector (ret, Block)
forall a b. (a -> b) -> a -> b
$ Var arg -> IndigoM ret
vIm Var arg
var
  RetVars ret
retVars <- forall ret (m :: * -> *).
(ReturnableValue ret, Monad m) =>
(forall x. m (Var x)) -> m (RetVars ret)
allocateVars @ret forall x. StateT InstrCollector Identity (Var x)
forall {k} (a :: k). State InstrCollector (Var a)
mkNextVar
  (Var arg, Block, ret, RetVars ret)
-> State InstrCollector (Var arg, Block, ret, RetVars ret)
forall (m :: * -> *) a. Monad m => a -> m a
return (Var arg
var, Block
block, ret
ret, RetVars ret
retVars)

-- | Append a new 'Instruction' to the head of the list in the state.
appendNewInstr :: Instruction -> State InstrCollector ()
appendNewInstr :: Instruction -> State InstrCollector ()
appendNewInstr Instruction
is = (InstrCollector -> InstrCollector) -> State InstrCollector ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((InstrCollector -> InstrCollector) -> State InstrCollector ())
-> (InstrCollector -> InstrCollector) -> State InstrCollector ()
forall a b. (a -> b) -> a -> b
$ \InstrCollector
iColl -> InstrCollector
iColl {instrList :: Block
instrList = Instruction
is Instruction -> Block -> Block
forall a. a -> [a] -> [a]
: InstrCollector -> Block
instrList InstrCollector
iColl}

-- | Creates a new var. This simply advances the ref counter and updates it.
mkNextVar :: State InstrCollector (Var a)
mkNextVar :: forall {k} (a :: k). State InstrCollector (Var a)
mkNextVar = do
  InstrCollector
iColl <- StateT InstrCollector Identity InstrCollector
forall s (m :: * -> *). MonadState s m => m s
get
  let ref :: RefId
ref = InstrCollector -> RefId
nextRef InstrCollector
iColl
  InstrCollector -> State InstrCollector ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put (InstrCollector -> State InstrCollector ())
-> InstrCollector -> State InstrCollector ()
forall a b. (a -> b) -> a -> b
$ InstrCollector
iColl {nextRef :: RefId
nextRef = RefId
ref RefId -> RefId -> RefId
forall a. Num a => a -> a -> a
+ RefId
1}
  Var a -> State InstrCollector (Var a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Var a -> State InstrCollector (Var a))
-> Var a -> State InstrCollector (Var a)
forall a b. (a -> b) -> a -> b
$ RefId -> Var a
forall {k} (a :: k). RefId -> Var a
Var RefId
ref

-- | Translation from a 'Block' and an initial 'MetaData' to Lorentz.
sequentialToLorentz
  :: MetaData inp
  -> (Block, RefId)
  -> inp :-> inp
sequentialToLorentz :: forall (inp :: [*]). MetaData inp -> (Block, RefId) -> inp :-> inp
sequentialToLorentz MetaData inp
md (Block, RefId)
block =
  SomeIndigoState inp
-> MetaData inp
-> (forall (out :: [*]). GenCode inp out -> inp :-> inp)
-> inp :-> inp
forall (inp :: [*]) r.
SomeIndigoState inp
-> MetaData inp -> (forall (out :: [*]). GenCode inp out -> r) -> r
runSIS ((Block, RefId) -> SomeIndigoState inp
forall (inp :: [*]). (Block, RefId) -> SomeIndigoState inp
sequentialToSIS (Block, RefId)
block) MetaData inp
md forall (out :: [*]). GenCode inp out -> inp :-> inp
forall (inp :: [*]) (out :: [*]). GenCode inp out -> inp :-> inp
St.cleanGenCode

-- | Translation from a 'Block' to a 'SomeIndigoState'.
sequentialToSIS :: (Block, RefId) -> SomeIndigoState inp
sequentialToSIS :: forall (inp :: [*]). (Block, RefId) -> SomeIndigoState inp
sequentialToSIS ([], RefId
_) = IndigoState inp inp -> SomeIndigoState inp
forall (inp :: [*]) (out :: [*]).
IndigoState inp out -> SomeIndigoState inp
toSIS IndigoState inp inp
forall (inp :: [*]). IndigoState inp inp
St.nopState
sequentialToSIS (Instruction
x : Block
xs, RefId
refId) = RefId -> Instruction -> SomeIndigoState inp
forall (inp :: [*]). RefId -> Instruction -> SomeIndigoState inp
instrToSIS RefId
refId Instruction
x SomeIndigoState inp
-> (forall (inp :: [*]). SomeIndigoState inp)
-> SomeIndigoState inp
forall (inp :: [*]).
SomeIndigoState inp
-> (forall (inp :: [*]). SomeIndigoState inp)
-> SomeIndigoState inp
`thenSIS` (Block, RefId) -> SomeIndigoState out
forall (inp :: [*]). (Block, RefId) -> SomeIndigoState inp
sequentialToSIS (Block
xs, RefId
refId)

-- | Translation from a single 'Instruction' to a 'SomeIndigoState'.
instrToSIS :: RefId -> Instruction -> SomeIndigoState inp
instrToSIS :: forall (inp :: [*]). RefId -> Instruction -> SomeIndigoState inp
instrToSIS RefId
nextRef = \case
  LiftIndigoState forall (inp :: [*]). SomeIndigoState inp
sis -> SomeIndigoState inp
forall (inp :: [*]). SomeIndigoState inp
sis
  Comment Text
txt -> IndigoState inp inp -> SomeIndigoState inp
forall (inp :: [*]) (out :: [*]).
IndigoState inp out -> SomeIndigoState inp
toSIS (IndigoState inp inp -> SomeIndigoState inp)
-> IndigoState inp inp -> SomeIndigoState inp
forall a b. (a -> b) -> a -> b
$ CommentType -> IndigoState inp inp
forall (i :: [*]). CommentType -> IndigoState i i
comment (CommentType -> IndigoState inp inp)
-> CommentType -> IndigoState inp inp
forall a b. (a -> b) -> a -> b
$ Text -> CommentType
MT.JustComment Text
txt
  AssignVar Var x
vx Expr x
ex -> IndigoState inp (x : inp) -> SomeIndigoState inp
forall (inp :: [*]) (out :: [*]).
IndigoState inp out -> SomeIndigoState inp
toSIS (IndigoState inp (x : inp) -> SomeIndigoState inp)
-> IndigoState inp (x : inp) -> SomeIndigoState inp
forall a b. (a -> b) -> a -> b
$ Var x -> Expr x -> IndigoState inp (x : inp)
forall x (inp :: [*]).
KnownValue x =>
Var x -> Expr x -> IndigoState inp (x : inp)
assignVar Var x
vx Expr x
ex
  SetVar Var x
vx Expr x
ex -> IndigoState inp inp -> SomeIndigoState inp
forall (inp :: [*]) (out :: [*]).
IndigoState inp out -> SomeIndigoState inp
toSIS (IndigoState inp inp -> SomeIndigoState inp)
-> IndigoState inp inp -> SomeIndigoState inp
forall a b. (a -> b) -> a -> b
$ RefId -> Var x -> Expr x -> IndigoState inp inp
forall a (inp :: [*]).
KnownValue a =>
RefId -> Var a -> Expr a -> IndigoState inp inp
setVar RefId
nextRef Var x
vx Expr x
ex
  VarModification '[y, x] :-> '[x]
upd Var x
vx Expr y
ey -> IndigoState inp inp -> SomeIndigoState inp
forall (inp :: [*]) (out :: [*]).
IndigoState inp out -> SomeIndigoState inp
toSIS (IndigoState inp inp -> SomeIndigoState inp)
-> IndigoState inp inp -> SomeIndigoState inp
forall a b. (a -> b) -> a -> b
$ RefId
-> ('[y, x] :-> '[x]) -> Var x -> Expr y -> IndigoState inp inp
forall x y (inp :: [*]).
(IsObject x, KnownValue y) =>
RefId
-> ('[y, x] :-> '[x]) -> Var x -> Expr y -> IndigoState inp inp
updateVar RefId
nextRef '[y, x] :-> '[x]
upd Var x
vx Expr y
ey
  SetField Var store
vSt Label fname
lName Expr ftype
ex -> IndigoState inp inp -> SomeIndigoState inp
forall (inp :: [*]) (out :: [*]).
IndigoState inp out -> SomeIndigoState inp
toSIS (IndigoState inp inp -> SomeIndigoState inp)
-> IndigoState inp inp -> SomeIndigoState inp
forall a b. (a -> b) -> a -> b
$ RefId
-> Var store -> Label fname -> Expr ftype -> IndigoState inp inp
forall dt (fname :: Symbol) ftype (inp :: [*]).
(IsObject dt, IsObject ftype, HasField dt fname ftype) =>
RefId -> Var dt -> Label fname -> Expr ftype -> IndigoState inp inp
setField RefId
nextRef Var store
vSt Label fname
lName Expr ftype
ex

  LambdaCall1 LambdaKind st arg ret extra
lKind String
_lName Expr arg
ex Var arg
var Block
block ret
ret RetVars ret
retVars ->
    LambdaKind st arg ret extra
-> ((ScopeCodeGen ret, KnownValue arg, Typeable ret,
     CreateLambda1CGeneric extra arg ret) =>
    SomeIndigoState inp)
-> SomeIndigoState inp
forall st arg res (extra :: [*]) r.
LambdaKind st arg res extra
-> ((ScopeCodeGen res, KnownValue arg, Typeable res,
     CreateLambda1CGeneric extra arg res) =>
    r)
-> r
withLambdaKind LambdaKind st arg ret extra
lKind (((ScopeCodeGen ret, KnownValue arg, Typeable ret,
   CreateLambda1CGeneric extra arg ret) =>
  SomeIndigoState inp)
 -> SomeIndigoState inp)
-> ((ScopeCodeGen ret, KnownValue arg, Typeable ret,
     CreateLambda1CGeneric extra arg ret) =>
    SomeIndigoState inp)
-> SomeIndigoState inp
forall a b. (a -> b) -> a -> b
$
      IndigoState inp (RetOutStack' (ClassifyReturnValue ret) ret ++ inp)
-> SomeIndigoState inp
forall (inp :: [*]) (out :: [*]).
IndigoState inp out -> SomeIndigoState inp
toSIS (IndigoState
   inp (RetOutStack' (ClassifyReturnValue ret) ret ++ inp)
 -> SomeIndigoState inp)
-> IndigoState
     inp (RetOutStack' (ClassifyReturnValue ret) ret ++ inp)
-> SomeIndigoState inp
forall a b. (a -> b) -> a -> b
$ SomeIndigoState inp
-> ret
-> RetVars ret
-> IndigoState
     inp (RetOutStack' (ClassifyReturnValue ret) ret ++ inp)
forall ret (inp :: [*]).
ScopeCodeGen ret =>
SomeIndigoState inp
-> ret -> RetVars ret -> IndigoState inp (RetOutStack ret ++ inp)
scope ((Block, RefId) -> SomeIndigoState inp
forall (inp :: [*]). (Block, RefId) -> SomeIndigoState inp
sequentialToSIS (Var arg -> Expr arg -> Instruction
forall x. KnownValue x => Var x -> Expr x -> Instruction
AssignVar Var arg
var Expr arg
ex Instruction -> Block -> Block
forall a. a -> [a] -> [a]
: Block
block, RefId
nextRef)) ret
ret RetVars ret
retVars
  CreateLambda1 StackVars (arg : extra)
lamMd Var arg
_var Block
body ret
ret Var (Lambda1Generic extra arg ret)
varLam ->
    IndigoState inp (Lambda1Generic extra arg ret : inp)
-> SomeIndigoState inp
forall (inp :: [*]) (out :: [*]).
IndigoState inp out -> SomeIndigoState inp
toSIS (IndigoState inp (Lambda1Generic extra arg ret : inp)
 -> SomeIndigoState inp)
-> IndigoState inp (Lambda1Generic extra arg ret : inp)
-> SomeIndigoState inp
forall a b. (a -> b) -> a -> b
$ Var (Lambda1Generic extra arg ret)
-> ret
-> StackVars (arg : extra)
-> SomeIndigoState (arg : extra)
-> IndigoState inp (Lambda1Generic extra arg ret : inp)
forall arg res (extra :: [*]) (inp :: [*]).
CreateLambda1CGeneric extra arg res =>
Var (Lambda1Generic extra arg res)
-> res
-> StackVars (arg : extra)
-> SomeIndigoState (arg : extra)
-> IndigoState inp (Lambda1Generic extra arg res : inp)
createLambda1Generic Var (Lambda1Generic extra arg ret)
varLam ret
ret StackVars (arg : extra)
lamMd ((Block, RefId) -> SomeIndigoState (arg : extra)
forall (inp :: [*]). (Block, RefId) -> SomeIndigoState inp
sequentialToSIS (Block
body, RefId
nextRef))
  ExecLambda1 LambdaKind st arg ret extra
lKind (Proxy ret
Proxy :: Proxy ret) Expr arg
ex Var (Lambda1Generic extra arg ret)
varLam RetVars ret
retVars ->
    IndigoState inp (RetOutStack' (ClassifyReturnValue ret) ret ++ inp)
-> SomeIndigoState inp
forall (inp :: [*]) (out :: [*]).
IndigoState inp out -> SomeIndigoState inp
toSIS (IndigoState
   inp (RetOutStack' (ClassifyReturnValue ret) ret ++ inp)
 -> SomeIndigoState inp)
-> IndigoState
     inp (RetOutStack' (ClassifyReturnValue ret) ret ++ inp)
-> SomeIndigoState inp
forall a b. (a -> b) -> a -> b
$ forall res st arg (extra :: [*]) (inp :: [*]).
LambdaKind st arg res extra
-> RefId -> RetVars res -> LambdaExecutor extra arg res inp
executeLambda1 @ret LambdaKind st arg ret extra
lKind RefId
nextRef RetVars ret
retVars Var (Lambda1Generic extra arg ret)
varLam Expr arg
ex

  Scope Block
block ret
ret RetVars ret
retVars ->
    IndigoState inp (RetOutStack' (ClassifyReturnValue ret) ret ++ inp)
-> SomeIndigoState inp
forall (inp :: [*]) (out :: [*]).
IndigoState inp out -> SomeIndigoState inp
toSIS (IndigoState
   inp (RetOutStack' (ClassifyReturnValue ret) ret ++ inp)
 -> SomeIndigoState inp)
-> IndigoState
     inp (RetOutStack' (ClassifyReturnValue ret) ret ++ inp)
-> SomeIndigoState inp
forall a b. (a -> b) -> a -> b
$ SomeIndigoState inp
-> ret
-> RetVars ret
-> IndigoState
     inp (RetOutStack' (ClassifyReturnValue ret) ret ++ inp)
forall ret (inp :: [*]).
ScopeCodeGen ret =>
SomeIndigoState inp
-> ret -> RetVars ret -> IndigoState inp (RetOutStack ret ++ inp)
scope ((Block, RefId) -> SomeIndigoState inp
forall (inp :: [*]). (Block, RefId) -> SomeIndigoState inp
sequentialToSIS (Block
block, RefId
nextRef)) ret
ret RetVars ret
retVars
  If Expr Bool
ex Block
blockA a
retA Block
blockB b
retB RetVars a
retVars ->
    IndigoState inp (RetOutStack b ++ inp) -> SomeIndigoState inp
forall (inp :: [*]) (out :: [*]).
IndigoState inp out -> SomeIndigoState inp
toSIS (IndigoState inp (RetOutStack b ++ inp) -> SomeIndigoState inp)
-> IndigoState inp (RetOutStack b ++ inp) -> SomeIndigoState inp
forall a b. (a -> b) -> a -> b
$ Expr Bool
-> SomeIndigoState inp
-> a
-> SomeIndigoState inp
-> b
-> RetVars a
-> IndigoState inp (RetOutStack a ++ inp)
forall (inp :: [*]) a b.
IfConstraint a b =>
Expr Bool
-> SomeIndigoState inp
-> a
-> SomeIndigoState inp
-> b
-> RetVars a
-> IndigoState inp (RetOutStack a ++ inp)
if_ Expr Bool
ex ((Block, RefId) -> SomeIndigoState inp
forall (inp :: [*]). (Block, RefId) -> SomeIndigoState inp
sequentialToSIS (Block
blockA, RefId
nextRef)) a
retA ((Block, RefId) -> SomeIndigoState inp
forall (inp :: [*]). (Block, RefId) -> SomeIndigoState inp
sequentialToSIS (Block
blockB, RefId
nextRef)) b
retB RetVars a
retVars
  IfSome Expr (Maybe x)
ex Var x
varX Block
blockA a
retA Block
blockB b
retB RetVars a
retVars ->
    IndigoState inp (RetOutStack b ++ inp) -> SomeIndigoState inp
forall (inp :: [*]) (out :: [*]).
IndigoState inp out -> SomeIndigoState inp
toSIS (IndigoState inp (RetOutStack b ++ inp) -> SomeIndigoState inp)
-> IndigoState inp (RetOutStack b ++ inp) -> SomeIndigoState inp
forall a b. (a -> b) -> a -> b
$ Expr (Maybe x)
-> Var x
-> SomeIndigoState (x : inp)
-> a
-> SomeIndigoState inp
-> b
-> RetVars a
-> IndigoState inp (RetOutStack a ++ inp)
forall (inp :: [*]) x a b.
(IfConstraint a b, KnownValue x) =>
Expr (Maybe x)
-> Var x
-> SomeIndigoState (x : inp)
-> a
-> SomeIndigoState inp
-> b
-> RetVars a
-> IndigoState inp (RetOutStack a ++ inp)
ifSome Expr (Maybe x)
ex Var x
varX ((Block, RefId) -> SomeIndigoState (x : inp)
forall (inp :: [*]). (Block, RefId) -> SomeIndigoState inp
sequentialToSIS (Block
blockA, RefId
nextRef)) a
retA ((Block, RefId) -> SomeIndigoState inp
forall (inp :: [*]). (Block, RefId) -> SomeIndigoState inp
sequentialToSIS (Block
blockB, RefId
nextRef)) b
retB RetVars a
retVars
  IfRight Expr (Either l r)
ex Var r
varR Block
blockA a
retA Var l
varL Block
blockB b
retB RetVars a
retVars ->
    IndigoState inp (RetOutStack b ++ inp) -> SomeIndigoState inp
forall (inp :: [*]) (out :: [*]).
IndigoState inp out -> SomeIndigoState inp
toSIS (IndigoState inp (RetOutStack b ++ inp) -> SomeIndigoState inp)
-> IndigoState inp (RetOutStack b ++ inp) -> SomeIndigoState inp
forall a b. (a -> b) -> a -> b
$ Expr (Either l r)
-> Var r
-> SomeIndigoState (r : inp)
-> a
-> Var l
-> SomeIndigoState (l : inp)
-> b
-> RetVars a
-> IndigoState inp (RetOutStack a ++ inp)
forall (inp :: [*]) r l a b.
(IfConstraint a b, KnownValue r, KnownValue l) =>
Expr (Either l r)
-> Var r
-> SomeIndigoState (r : inp)
-> a
-> Var l
-> SomeIndigoState (l : inp)
-> b
-> RetVars a
-> IndigoState inp (RetOutStack a ++ inp)
ifRight Expr (Either l r)
ex Var r
varR ((Block, RefId) -> SomeIndigoState (r : inp)
forall (inp :: [*]). (Block, RefId) -> SomeIndigoState inp
sequentialToSIS (Block
blockA, RefId
nextRef)) a
retA Var l
varL ((Block, RefId) -> SomeIndigoState (l : inp)
forall (inp :: [*]). (Block, RefId) -> SomeIndigoState inp
sequentialToSIS (Block
blockB, RefId
nextRef)) b
retB RetVars a
retVars
  IfCons Expr (List x)
ex Var x
varX Var (List x)
varLX Block
blockA a
retA Block
blockB b
retB RetVars a
retVars ->
    IndigoState inp (RetOutStack b ++ inp) -> SomeIndigoState inp
forall (inp :: [*]) (out :: [*]).
IndigoState inp out -> SomeIndigoState inp
toSIS (IndigoState inp (RetOutStack b ++ inp) -> SomeIndigoState inp)
-> IndigoState inp (RetOutStack b ++ inp) -> SomeIndigoState inp
forall a b. (a -> b) -> a -> b
$ Expr (List x)
-> Var x
-> Var (List x)
-> SomeIndigoState (x : List x : inp)
-> a
-> SomeIndigoState inp
-> b
-> RetVars a
-> IndigoState inp (RetOutStack a ++ inp)
forall (inp :: [*]) x a b.
(IfConstraint a b, KnownValue x) =>
Expr (List x)
-> Var x
-> Var (List x)
-> SomeIndigoState (x : List x : inp)
-> a
-> SomeIndigoState inp
-> b
-> RetVars a
-> IndigoState inp (RetOutStack a ++ inp)
ifCons Expr (List x)
ex Var x
varX Var (List x)
varLX ((Block, RefId) -> SomeIndigoState (x : List x : inp)
forall (inp :: [*]). (Block, RefId) -> SomeIndigoState inp
sequentialToSIS (Block
blockA, RefId
nextRef)) a
retA ((Block, RefId) -> SomeIndigoState inp
forall (inp :: [*]). (Block, RefId) -> SomeIndigoState inp
sequentialToSIS (Block
blockB, RefId
nextRef)) b
retB RetVars a
retVars

  Case Expr dt
grd clauses
blockClauses RetVars ret
retVars ->
    IndigoState inp (RetOutStack' (ClassifyReturnValue ret) ret ++ inp)
-> SomeIndigoState inp
forall (inp :: [*]) (out :: [*]).
IndigoState inp out -> SomeIndigoState inp
toSIS (IndigoState
   inp (RetOutStack' (ClassifyReturnValue ret) ret ++ inp)
 -> SomeIndigoState inp)
-> IndigoState
     inp (RetOutStack' (ClassifyReturnValue ret) ret ++ inp)
-> SomeIndigoState inp
forall a b. (a -> b) -> a -> b
$ Expr dt
-> Rec (IndigoCaseClauseL ret) (GCaseClauses (Rep dt) '[])
-> RetVars ret
-> IndigoState
     inp (RetOutStack' (ClassifyReturnValue ret) ret ++ inp)
forall dt (inp :: [*]) ret clauses.
CaseCommon dt ret clauses =>
Expr dt
-> clauses
-> RetVars ret
-> IndigoState inp (RetOutStack ret ++ inp)
caseRec Expr dt
grd (RefId
-> Rec (IndigoSeqCaseClause ret) (GCaseClauses (Rep dt) '[])
-> Rec (IndigoCaseClauseL ret) (GCaseClauses (Rep dt) '[])
forall ret (dt :: [CaseClauseParam]).
RMap dt =>
RefId
-> Rec (IndigoSeqCaseClause ret) dt
-> Rec (IndigoCaseClauseL ret) dt
clausesToBackend RefId
nextRef clauses
Rec (IndigoSeqCaseClause ret) (GCaseClauses (Rep dt) '[])
blockClauses) RetVars ret
retVars
  EntryCase Proxy entryPointKind
proxy Expr dt
grd clauses
blockClauses RetVars ret
retVars ->
    IndigoState inp (RetOutStack' (ClassifyReturnValue ret) ret ++ inp)
-> SomeIndigoState inp
forall (inp :: [*]) (out :: [*]).
IndigoState inp out -> SomeIndigoState inp
toSIS (IndigoState
   inp (RetOutStack' (ClassifyReturnValue ret) ret ++ inp)
 -> SomeIndigoState inp)
-> IndigoState
     inp (RetOutStack' (ClassifyReturnValue ret) ret ++ inp)
-> SomeIndigoState inp
forall a b. (a -> b) -> a -> b
$ Proxy entryPointKind
-> Expr dt
-> Rec (IndigoCaseClauseL ret) (GCaseClauses (Rep dt) '[])
-> RetVars ret
-> IndigoState
     inp (RetOutStack' (ClassifyReturnValue ret) ret ++ inp)
forall dt entrypointKind (inp :: [*]) ret clauses.
(CaseCommon dt ret clauses,
 DocumentEntrypoints entrypointKind dt) =>
Proxy entrypointKind
-> Expr dt
-> clauses
-> RetVars ret
-> IndigoState inp (RetOutStack ret ++ inp)
entryCaseRec Proxy entryPointKind
proxy Expr dt
grd (RefId
-> Rec (IndigoSeqCaseClause ret) (GCaseClauses (Rep dt) '[])
-> Rec (IndigoCaseClauseL ret) (GCaseClauses (Rep dt) '[])
forall ret (dt :: [CaseClauseParam]).
RMap dt =>
RefId
-> Rec (IndigoSeqCaseClause ret) dt
-> Rec (IndigoCaseClauseL ret) dt
clausesToBackend RefId
nextRef clauses
Rec (IndigoSeqCaseClause ret) (GCaseClauses (Rep dt) '[])
blockClauses) RetVars ret
retVars
  EntryCaseSimple Expr dt
grd clauses
blockClauses RetVars ret
retVars ->
    IndigoState inp (RetOutStack' (ClassifyReturnValue ret) ret ++ inp)
-> SomeIndigoState inp
forall (inp :: [*]) (out :: [*]).
IndigoState inp out -> SomeIndigoState inp
toSIS (IndigoState
   inp (RetOutStack' (ClassifyReturnValue ret) ret ++ inp)
 -> SomeIndigoState inp)
-> IndigoState
     inp (RetOutStack' (ClassifyReturnValue ret) ret ++ inp)
-> SomeIndigoState inp
forall a b. (a -> b) -> a -> b
$ Expr dt
-> Rec (IndigoCaseClauseL ret) (GCaseClauses (Rep dt) '[])
-> RetVars ret
-> IndigoState
     inp (RetOutStack' (ClassifyReturnValue ret) ret ++ inp)
forall dt (inp :: [*]) ret clauses.
(CaseCommon dt ret clauses,
 DocumentEntrypoints PlainEntrypointsKind dt, NiceParameterFull dt,
 RequireFlatParamEps dt) =>
Expr dt
-> clauses
-> RetVars ret
-> IndigoState inp (RetOutStack ret ++ inp)
entryCaseSimpleRec Expr dt
grd (RefId
-> Rec (IndigoSeqCaseClause ret) (GCaseClauses (Rep dt) '[])
-> Rec (IndigoCaseClauseL ret) (GCaseClauses (Rep dt) '[])
forall ret (dt :: [CaseClauseParam]).
RMap dt =>
RefId
-> Rec (IndigoSeqCaseClause ret) dt
-> Rec (IndigoCaseClauseL ret) dt
clausesToBackend RefId
nextRef clauses
Rec (IndigoSeqCaseClause ret) (GCaseClauses (Rep dt) '[])
blockClauses) RetVars ret
retVars

  While Expr Bool
ex Block
block ->
    IndigoState inp inp -> SomeIndigoState inp
forall (inp :: [*]) (out :: [*]).
IndigoState inp out -> SomeIndigoState inp
toSIS (IndigoState inp inp -> SomeIndigoState inp)
-> IndigoState inp inp -> SomeIndigoState inp
forall a b. (a -> b) -> a -> b
$ Expr Bool -> SomeIndigoState inp -> IndigoState inp inp
forall (inp :: [*]).
Expr Bool -> SomeIndigoState inp -> IndigoState inp inp
while Expr Bool
ex ((Block, RefId) -> SomeIndigoState inp
forall (inp :: [*]). (Block, RefId) -> SomeIndigoState inp
sequentialToSIS (Block
block, RefId
nextRef))
  WhileLeft Expr (Either l r)
ex Var l
varL Block
block Var r
varR ->
    IndigoState inp (r : inp) -> SomeIndigoState inp
forall (inp :: [*]) (out :: [*]).
IndigoState inp out -> SomeIndigoState inp
toSIS (IndigoState inp (r : inp) -> SomeIndigoState inp)
-> IndigoState inp (r : inp) -> SomeIndigoState inp
forall a b. (a -> b) -> a -> b
$ Expr (Either l r)
-> Var l
-> SomeIndigoState (l : inp)
-> Var r
-> IndigoState inp (r : inp)
forall l r (inp :: [*]).
(KnownValue l, KnownValue r) =>
Expr (Either l r)
-> Var l
-> SomeIndigoState (l : inp)
-> Var r
-> IndigoState inp (r : inp)
whileLeft Expr (Either l r)
ex Var l
varL ((Block, RefId) -> SomeIndigoState (l : inp)
forall (inp :: [*]). (Block, RefId) -> SomeIndigoState inp
sequentialToSIS (Block
block, RefId
nextRef)) Var r
varR
  ForEach Expr a
ex Var (IterOpElHs a)
varIop Block
block ->
    IndigoState inp inp -> SomeIndigoState inp
forall (inp :: [*]) (out :: [*]).
IndigoState inp out -> SomeIndigoState inp
toSIS (IndigoState inp inp -> SomeIndigoState inp)
-> IndigoState inp inp -> SomeIndigoState inp
forall a b. (a -> b) -> a -> b
$ Expr a
-> Var (IterOpElHs a)
-> SomeIndigoState (IterOpElHs a : inp)
-> IndigoState inp inp
forall a (inp :: [*]).
(IterOpHs a, KnownValue (IterOpElHs a)) =>
Expr a
-> Var (IterOpElHs a)
-> SomeIndigoState (IterOpElHs a : inp)
-> IndigoState inp inp
forEach Expr a
ex Var (IterOpElHs a)
varIop ((Block, RefId) -> SomeIndigoState (IterOpElHs a : inp)
forall (inp :: [*]). (Block, RefId) -> SomeIndigoState inp
sequentialToSIS (Block
block, RefId
nextRef))

  ContractName Text
tx Block
block ->
    (SubDoc -> DName) -> SomeIndigoState inp -> SomeIndigoState inp
forall di (i :: [*]).
DocItem di =>
(SubDoc -> di) -> SomeIndigoState i -> SomeIndigoState i
docGroup (Text -> SubDoc -> DName
DName Text
tx) ((Block, RefId) -> SomeIndigoState inp
forall (inp :: [*]). (Block, RefId) -> SomeIndigoState inp
sequentialToSIS (Block
block, RefId
nextRef))
  DocGroup SubDoc -> di
dg Block
block ->
    (SubDoc -> di) -> SomeIndigoState inp -> SomeIndigoState inp
forall di (i :: [*]).
DocItem di =>
(SubDoc -> di) -> SomeIndigoState i -> SomeIndigoState i
docGroup SubDoc -> di
dg ((Block, RefId) -> SomeIndigoState inp
forall (inp :: [*]). (Block, RefId) -> SomeIndigoState inp
sequentialToSIS (Block
block, RefId
nextRef))
  ContractGeneral Block
block ->
    (SubDoc -> DGeneralInfoSection)
-> SomeIndigoState inp -> SomeIndigoState inp
forall di (i :: [*]).
DocItem di =>
(SubDoc -> di) -> SomeIndigoState i -> SomeIndigoState i
docGroup SubDoc -> DGeneralInfoSection
DGeneralInfoSection ((Block, RefId) -> SomeIndigoState inp
forall (inp :: [*]). (Block, RefId) -> SomeIndigoState inp
sequentialToSIS (Block
block, RefId
nextRef))
  FinalizeParamCallingDoc Var cp
varCp Block
block Expr cp
param ->
    Var cp
-> SomeIndigoState (cp : inp) -> Expr cp -> SomeIndigoState inp
forall cp (inp :: [*]).
(NiceParameterFull cp, RequireSumType cp, HasCallStack) =>
Var cp
-> SomeIndigoState (cp : inp) -> Expr cp -> SomeIndigoState inp
finalizeParamCallingDoc Var cp
varCp ((Block, RefId) -> SomeIndigoState (cp : inp)
forall (inp :: [*]). (Block, RefId) -> SomeIndigoState inp
sequentialToSIS (Block
block, RefId
nextRef)) Expr cp
param

  TransferTokens Expr p
ex Expr Mutez
exm Expr (ContractRef p)
exc ->
    IndigoState inp inp -> SomeIndigoState inp
forall (inp :: [*]) (out :: [*]).
IndigoState inp out -> SomeIndigoState inp
toSIS (IndigoState inp inp -> SomeIndigoState inp)
-> IndigoState inp inp -> SomeIndigoState inp
forall a b. (a -> b) -> a -> b
$ Expr p -> Expr Mutez -> Expr (ContractRef p) -> IndigoState inp inp
forall p (inp :: [*]).
(NiceParameter p, HasSideEffects, IsNotInView) =>
Expr p -> Expr Mutez -> Expr (ContractRef p) -> IndigoState inp inp
transferTokens Expr p
ex Expr Mutez
exm Expr (ContractRef p)
exc
  SetDelegate Expr (Maybe KeyHash)
ex ->
    IndigoState inp inp -> SomeIndigoState inp
forall (inp :: [*]) (out :: [*]).
IndigoState inp out -> SomeIndigoState inp
toSIS (IndigoState inp inp -> SomeIndigoState inp)
-> IndigoState inp inp -> SomeIndigoState inp
forall a b. (a -> b) -> a -> b
$ Expr (Maybe KeyHash) -> IndigoState inp inp
forall (inp :: [*]).
(HasSideEffects, IsNotInView) =>
Expr (Maybe KeyHash) -> IndigoState inp inp
setDelegate Expr (Maybe KeyHash)
ex
  CreateContract Contract p s vd
ctrc Expr (Maybe KeyHash)
exk Expr Mutez
exm Expr s
exs Var Address
varAddr ->
    IndigoState inp (Address : inp) -> SomeIndigoState inp
forall (inp :: [*]) (out :: [*]).
IndigoState inp out -> SomeIndigoState inp
toSIS (IndigoState inp (Address : inp) -> SomeIndigoState inp)
-> IndigoState inp (Address : inp) -> SomeIndigoState inp
forall a b. (a -> b) -> a -> b
$ Contract p s vd
-> Expr (Maybe KeyHash)
-> Expr Mutez
-> Expr s
-> Var Address
-> IndigoState inp (Address : inp)
forall s p vd (inp :: [*]).
(HasSideEffects, NiceStorage s, NiceParameterFull p,
 NiceViewsDescriptor vd, Typeable vd, IsNotInView) =>
Contract p s vd
-> Expr (Maybe KeyHash)
-> Expr Mutez
-> Expr s
-> Var Address
-> IndigoState inp (Address : inp)
createContract Contract p s vd
ctrc Expr (Maybe KeyHash)
exk Expr Mutez
exm Expr s
exs Var Address
varAddr
  SelfCalling (Proxy p
Proxy :: Proxy p) EntrypointRef mname
ep Var (ContractRef (GetEntrypointArgCustom p mname))
varCR ->
    IndigoState
  inp (ContractRef (GetEntrypointArgCustom p mname) : inp)
-> SomeIndigoState inp
forall (inp :: [*]) (out :: [*]).
IndigoState inp out -> SomeIndigoState inp
toSIS (IndigoState
   inp (ContractRef (GetEntrypointArgCustom p mname) : inp)
 -> SomeIndigoState inp)
-> IndigoState
     inp (ContractRef (GetEntrypointArgCustom p mname) : inp)
-> SomeIndigoState inp
forall a b. (a -> b) -> a -> b
$ forall p (inp :: [*]) (mname :: Maybe Symbol).
(NiceParameterFull p, KnownValue (GetEntrypointArgCustom p mname),
 IsoValue (ContractRef (GetEntrypointArgCustom p mname)),
 IsNotInView) =>
EntrypointRef mname
-> Var (ContractRef (GetEntrypointArgCustom p mname))
-> IndigoState
     inp (ContractRef (GetEntrypointArgCustom p mname) : inp)
selfCalling @p EntrypointRef mname
ep Var (ContractRef (GetEntrypointArgCustom p mname))
varCR
  ContractCalling (Proxy (cp, vd)
Proxy :: Proxy (cp, vd)) epRef
epRef Expr addr
exAddr Var (Maybe (ContractRef epArg))
varMcr ->
    IndigoState inp (Maybe (ContractRef epArg) : inp)
-> SomeIndigoState inp
forall (inp :: [*]) (out :: [*]).
IndigoState inp out -> SomeIndigoState inp
toSIS (IndigoState inp (Maybe (ContractRef epArg) : inp)
 -> SomeIndigoState inp)
-> IndigoState inp (Maybe (ContractRef epArg) : inp)
-> SomeIndigoState inp
forall a b. (a -> b) -> a -> b
$ forall cp vd (inp :: [*]) epRef epArg addr.
(HasEntrypointArg cp epRef epArg, ToTAddress cp vd addr,
 ToT addr ~ ToT Address, HasNoOp (ToT epArg),
 HasNoNestedBigMaps (ToT epArg), KnownValue epArg) =>
epRef
-> Expr addr
-> Var (Maybe (ContractRef epArg))
-> IndigoState inp (Maybe (ContractRef epArg) : inp)
contractCalling @cp @vd epRef
epRef Expr addr
exAddr Var (Maybe (ContractRef epArg))
varMcr
  Emit FieldAnn
tag Expr a
ex ->
    IndigoState inp inp -> SomeIndigoState inp
forall (inp :: [*]) (out :: [*]).
IndigoState inp out -> SomeIndigoState inp
toSIS (IndigoState inp inp -> SomeIndigoState inp)
-> IndigoState inp inp -> SomeIndigoState inp
forall a b. (a -> b) -> a -> b
$ FieldAnn -> Expr a -> IndigoState inp inp
forall a (inp :: [*]).
(HasSideEffects, NicePackedValue a, HasAnnotation a) =>
FieldAnn -> Expr a -> IndigoState inp inp
emit FieldAnn
tag Expr a
ex

  Fail forall (inp :: [*]). SomeIndigoState inp
failure -> SomeIndigoState inp
forall (inp :: [*]). SomeIndigoState inp
failure
  FailOver forall (inp :: [*]). Expr a -> SomeIndigoState inp
failure Expr a
ex -> Expr a -> SomeIndigoState inp
forall (inp :: [*]). Expr a -> SomeIndigoState inp
failure Expr a
ex

----------------------------------------------------------------------------
-- Case machinery
----------------------------------------------------------------------------

-- | Convert clauses from their "sequential" representation to the "backend" one.
clausesToBackend
  :: forall ret dt . RMap dt
  => RefId
  -> Rec (IndigoSeqCaseClause ret) dt
  -> Rec (IndigoCaseClauseL ret) dt
clausesToBackend :: forall ret (dt :: [CaseClauseParam]).
RMap dt =>
RefId
-> Rec (IndigoSeqCaseClause ret) dt
-> Rec (IndigoCaseClauseL ret) dt
clausesToBackend RefId
nextRef = (forall (x :: CaseClauseParam).
 IndigoSeqCaseClause ret x -> IndigoCaseClauseL ret x)
-> Rec (IndigoSeqCaseClause ret) dt
-> Rec (IndigoCaseClauseL ret) dt
forall {u} (rs :: [u]) (f :: u -> *) (g :: u -> *).
RMap rs =>
(forall (x :: u). f x -> g x) -> Rec f rs -> Rec g rs
rmap ((forall (x :: CaseClauseParam).
  IndigoSeqCaseClause ret x -> IndigoCaseClauseL ret x)
 -> Rec (IndigoSeqCaseClause ret) dt
 -> Rec (IndigoCaseClauseL ret) dt)
-> (forall (x :: CaseClauseParam).
    IndigoSeqCaseClause ret x -> IndigoCaseClauseL ret x)
-> Rec (IndigoSeqCaseClause ret) dt
-> Rec (IndigoCaseClauseL ret) dt
forall a b. (a -> b) -> a -> b
$
  \(OneFieldIndigoSeqCaseClause Label name
cName (CaseBranch Var x
vx Block
block retBr
ret)) ->
    Label name
cName Label name -> IndigoClause x ret -> IndigoCaseClauseL ret x
forall (name :: Symbol) body clause.
CaseArrow name body clause =>
Label name -> body -> clause
/-> (Var x
-> (forall (inp :: [*]). SomeIndigoState (x : inp))
-> retBr
-> IndigoClause x ret
forall x retBr ret.
(KnownValue x, ScopeCodeGen retBr, ret ~ RetExprs retBr,
 RetOutStack ret ~ RetOutStack retBr) =>
Var x
-> (forall (inp :: [*]). SomeIndigoState (x : inp))
-> retBr
-> IndigoClause x ret
IndigoClause Var x
vx ((Block, RefId) -> SomeIndigoState (x : inp)
forall (inp :: [*]). (Block, RefId) -> SomeIndigoState inp
sequentialToSIS (Block
block, RefId
nextRef)) retBr
ret)

-- | Allocate vars for the return value(s) of a clause-like 'Instruction'.
allocateClausesVars
  :: forall ret dt. ReturnableValue ret
  => Rec (S.IndigoMCaseClauseL IndigoM ret) dt
  -> State InstrCollector (RetVars ret)
allocateClausesVars :: forall ret (dt :: [CaseClauseParam]).
ReturnableValue ret =>
Rec (IndigoMCaseClauseL IndigoM ret) dt
-> State InstrCollector (RetVars ret)
allocateClausesVars Rec (IndigoMCaseClauseL IndigoM ret) dt
_ = forall ret (m :: * -> *).
(ReturnableValue ret, Monad m) =>
(forall x. m (Var x)) -> m (RetVars ret)
allocateVars @ret forall x. StateT InstrCollector Identity (Var x)
forall {k} (a :: k). State InstrCollector (Var a)
mkNextVar

-- | Collects clauses of a case-like statement.
collectClauses
  :: Rec (S.IndigoMCaseClauseL IndigoM ret) dt
  -> State InstrCollector (Rec (IndigoSeqCaseClause ret) dt)
collectClauses :: forall ret (dt :: [CaseClauseParam]).
Rec (IndigoMCaseClauseL IndigoM ret) dt
-> State InstrCollector (Rec (IndigoSeqCaseClause ret) dt)
collectClauses Rec (IndigoMCaseClauseL IndigoM ret) dt
RNil = Rec (IndigoSeqCaseClause ret) '[]
-> StateT
     InstrCollector Identity (Rec (IndigoSeqCaseClause ret) '[])
forall (m :: * -> *) a. Monad m => a -> m a
return Rec (IndigoSeqCaseClause ret) '[]
forall {u} (a :: u -> *). Rec a '[]
RNil
collectClauses ((S.OneFieldIndigoMCaseClauseL Label name
cName Var x -> IndigoM retBr
clause) :& Rec (IndigoMCaseClauseL IndigoM ret) rs
xs) = do
  Var x
varX <- State InstrCollector (Var x)
forall {k} (a :: k). State InstrCollector (Var a)
mkNextVar
  (retBr
ret, Block
block) <- IndigoM retBr -> State InstrCollector (retBr, Block)
forall ret. IndigoM ret -> State InstrCollector (ret, Block)
collectInner (IndigoM retBr -> State InstrCollector (retBr, Block))
-> IndigoM retBr -> State InstrCollector (retBr, Block)
forall a b. (a -> b) -> a -> b
$ Var x -> IndigoM retBr
clause Var x
varX
  let clauseX :: IndigoSeqCaseClause ret ('CaseClauseParam ctor ('OneField x))
clauseX = Label name
-> CaseBranch x ret
-> IndigoSeqCaseClause ret ('CaseClauseParam ctor ('OneField x))
forall (ctor :: Symbol) (name :: Symbol) x ret.
(AppendSymbol "c" ctor ~ name) =>
Label name
-> CaseBranch x ret
-> IndigoSeqCaseClause ret ('CaseClauseParam ctor ('OneField x))
OneFieldIndigoSeqCaseClause Label name
cName (Var x -> Block -> retBr -> CaseBranch x ret
forall x retBr ret.
(KnownValue x, ScopeCodeGen retBr, ret ~ RetExprs retBr,
 RetOutStack ret ~ RetOutStack retBr) =>
Var x -> Block -> retBr -> CaseBranch x ret
CaseBranch Var x
varX Block
block retBr
ret)
  Rec (IndigoSeqCaseClause ret) rs
clauseXs <- Rec (IndigoMCaseClauseL IndigoM ret) rs
-> State InstrCollector (Rec (IndigoSeqCaseClause ret) rs)
forall ret (dt :: [CaseClauseParam]).
Rec (IndigoMCaseClauseL IndigoM ret) dt
-> State InstrCollector (Rec (IndigoSeqCaseClause ret) dt)
collectClauses Rec (IndigoMCaseClauseL IndigoM ret) rs
xs
  Rec
  (IndigoSeqCaseClause ret)
  ('CaseClauseParam ctor ('OneField x) : rs)
-> StateT
     InstrCollector
     Identity
     (Rec
        (IndigoSeqCaseClause ret)
        ('CaseClauseParam ctor ('OneField x) : rs))
forall (m :: * -> *) a. Monad m => a -> m a
return (Rec
   (IndigoSeqCaseClause ret)
   ('CaseClauseParam ctor ('OneField x) : rs)
 -> StateT
      InstrCollector
      Identity
      (Rec
         (IndigoSeqCaseClause ret)
         ('CaseClauseParam ctor ('OneField x) : rs)))
-> Rec
     (IndigoSeqCaseClause ret)
     ('CaseClauseParam ctor ('OneField x) : rs)
-> StateT
     InstrCollector
     Identity
     (Rec
        (IndigoSeqCaseClause ret)
        ('CaseClauseParam ctor ('OneField x) : rs))
forall a b. (a -> b) -> a -> b
$ IndigoSeqCaseClause ret ('CaseClauseParam ctor ('OneField x))
clauseX IndigoSeqCaseClause ret ('CaseClauseParam ctor ('OneField x))
-> Rec (IndigoSeqCaseClause ret) rs
-> Rec
     (IndigoSeqCaseClause ret)
     ('CaseClauseParam ctor ('OneField x) : rs)
forall {u} (a :: u -> *) (r :: u) (rs :: [u]).
a r -> Rec a rs -> Rec a (r : rs)
:& Rec (IndigoSeqCaseClause ret) rs
clauseXs

-- | Applies the given 'Block' to 'Block' transformation to the inner code block
-- of every case clause.
updateClauses
  :: (Block -> Block)
  -> Rec (IndigoSeqCaseClause ret) dt
  -> Rec (IndigoSeqCaseClause ret) dt
updateClauses :: forall ret (dt :: [CaseClauseParam]).
(Block -> Block)
-> Rec (IndigoSeqCaseClause ret) dt
-> Rec (IndigoSeqCaseClause ret) dt
updateClauses Block -> Block
_ Rec (IndigoSeqCaseClause ret) dt
RNil = Rec (IndigoSeqCaseClause ret) dt
forall {u} (a :: u -> *). Rec a '[]
RNil
updateClauses Block -> Block
f (IndigoSeqCaseClause ret r
x :& Rec (IndigoSeqCaseClause ret) rs
xs) = case IndigoSeqCaseClause ret r
x of
  OneFieldIndigoSeqCaseClause Label name
cName (CaseBranch Var x
vx Block
block retBr
ret) ->
    Label name
-> CaseBranch x ret
-> IndigoSeqCaseClause ret ('CaseClauseParam ctor ('OneField x))
forall (ctor :: Symbol) (name :: Symbol) x ret.
(AppendSymbol "c" ctor ~ name) =>
Label name
-> CaseBranch x ret
-> IndigoSeqCaseClause ret ('CaseClauseParam ctor ('OneField x))
OneFieldIndigoSeqCaseClause Label name
cName (Var x -> Block -> retBr -> CaseBranch x ret
forall x retBr ret.
(KnownValue x, ScopeCodeGen retBr, ret ~ RetExprs retBr,
 RetOutStack ret ~ RetOutStack retBr) =>
Var x -> Block -> retBr -> CaseBranch x ret
CaseBranch Var x
vx (Block -> Block
f Block
block) retBr
ret)
      IndigoSeqCaseClause ret ('CaseClauseParam ctor ('OneField x))
-> Rec (IndigoSeqCaseClause ret) rs
-> Rec
     (IndigoSeqCaseClause ret)
     ('CaseClauseParam ctor ('OneField x) : rs)
forall {u} (a :: u -> *) (r :: u) (rs :: [u]).
a r -> Rec a rs -> Rec a (r : rs)
:& (Block -> Block)
-> Rec (IndigoSeqCaseClause ret) rs
-> Rec (IndigoSeqCaseClause ret) rs
forall ret (dt :: [CaseClauseParam]).
(Block -> Block)
-> Rec (IndigoSeqCaseClause ret) dt
-> Rec (IndigoSeqCaseClause ret) dt
updateClauses Block -> Block
f Rec (IndigoSeqCaseClause ret) rs
xs

-- | Applies the given monadic function giving it the inner code block of each
-- case clause, in order.
mapMClauses :: Monad m => (Block -> m ()) -> Rec (IndigoSeqCaseClause ret) dt -> m ()
mapMClauses :: forall (m :: * -> *) ret (dt :: [CaseClauseParam]).
Monad m =>
(Block -> m ()) -> Rec (IndigoSeqCaseClause ret) dt -> m ()
mapMClauses Block -> m ()
_ Rec (IndigoSeqCaseClause ret) dt
RNil = () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
mapMClauses Block -> m ()
f (IndigoSeqCaseClause ret r
x :& Rec (IndigoSeqCaseClause ret) rs
xs) = case IndigoSeqCaseClause ret r
x of
  OneFieldIndigoSeqCaseClause Label name
_cName (CaseBranch Var x
_ Block
block retBr
_) ->
    Block -> m ()
f Block
block m () -> m () -> m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Block -> m ()) -> Rec (IndigoSeqCaseClause ret) rs -> m ()
forall (m :: * -> *) ret (dt :: [CaseClauseParam]).
Monad m =>
(Block -> m ()) -> Rec (IndigoSeqCaseClause ret) dt -> m ()
mapMClauses Block -> m ()
f Rec (IndigoSeqCaseClause ret) rs
xs