-- SPDX-FileCopyrightText: 2020 Tocqueville Group
--
-- SPDX-License-Identifier: LicenseRef-MIT-TQ

-- | Frontend statements's functions of the Indigo Language.

module Indigo.Frontend.Language
  ( -- * Assignment and modifications
    new
  , setVar
  , setField
  , (+=)
  , (-=)
  , (*=)
  , (<<<=)
  , (>>>=)
  , (&&=)
  , (||=)
  , (^=)
  , (=:)

  -- * Storage Fields
  , getStorageField
  , setStorageField
  , updateStorageField

  -- * Conditional
  , if_
  , when
  , unless
  , ifSome
  , ifNone
  , whenSome
  , whenNone
  , ifRight
  , ifLeft
  , whenRight
  , whenLeft
  , ifCons

  -- * Case
  , case_
  , caseRec
  , entryCase
  , entryCaseRec
  , entryCaseSimple
  , (//->)
  , (#=)

  -- * Scope
  , scope
  , defFunction
  , defContract
  , defNamedPureLambda1
  , defNamedLambda1
  , defNamedLambda0
  , defNamedEffLambda1

  -- * Loop
  , while
  , whileLeft
  , forEach

  -- * Contract call
  , selfCalling
  , contractCalling

  -- * Documentation
  , doc
  , docGroup
  , docStorage
  , contractName
  , contractGeneral
  , contractGeneralDefault
  , finalizeParamCallingDoc

  -- * Short-handed doc item
  , anchor
  , description
  , example

  -- * Side-effects operations
  , transferTokens
  , setDelegate
  , createContract
  , createLorentzContract

  -- * Failures
  , failWith
  , assert
  , failCustom
  , failCustom_
  , failUnexpected_
  , assertCustom
  , assertCustom_
  , assertSome
  , assertNone
  , assertRight
  , assertLeft
  -- * Re-exports
  , ReturnableValue
  , RetVars

  -- * Comments
  , comment
  , justComment
  , commentAroundFun
  , commentAroundStmt

  -- * Blocks
  , IndigoFunction
  , IndigoProcedure
  , IndigoEntrypoint

  -- * Helpers
  , liftIndigoState
  ) where

import Fmt (Buildable)
import GHC.Stack (popCallStack)
import GHC.Stack.Types (SrcLoc(..))

import Prelude ((==))
import qualified Indigo.Backend as B
import Indigo.Backend.Case hiding (caseRec, entryCaseRec)
import Indigo.Backend.Lambda
import Indigo.Backend.Scope
import Indigo.Compilation (compileIndigoContract)
import Indigo.Frontend.Program
import Indigo.Frontend.Statement
import Indigo.Internal hiding (SetField, (>>), (==))
import Indigo.Lorentz
import Indigo.Prelude
import Lorentz.Entrypoints.Helpers (RequireSumType)
import qualified Lorentz.Instr as L
import qualified Lorentz.Run as L
import qualified Michelson.Typed as MT
import qualified Michelson.Typed.Arith as M
import Michelson.Typed.Haskell.Instr.Sum (CaseClauseParam(..), CtorField(..))
import Util.Markdown (toAnchor)
import Util.TypeLits (AppendSymbol)
import Util.TypeTuple.Class

oneIndigoM :: StatementF IndigoM a -> IndigoM a
oneIndigoM :: StatementF IndigoM a -> IndigoM a
oneIndigoM st :: StatementF IndigoM a
st = Program (StatementF IndigoM) a -> IndigoM a
forall a. Program (StatementF IndigoM) a -> IndigoM a
IndigoM (StatementF IndigoM a -> Program (StatementF IndigoM) a
forall (instr :: * -> *) a. instr a -> Program instr a
Instr StatementF IndigoM a
st)

calledFrom :: HasCallStack => IndigoM a -> IndigoM a
calledFrom :: IndigoM a -> IndigoM a
calledFrom iM :: IndigoM a
iM = case CallStack -> [([Char], SrcLoc)]
getCallStack CallStack
HasCallStack => CallStack
callStack of
  [] -> Text -> IndigoM a
forall a. HasCallStack => Text -> a
error "impossible: calledFrom has HasCallStack constraint, so at least one element has to be at the callStack"
  ((_, loc :: SrcLoc
loc):_)
    | SrcLoc -> [Char]
srcLocModule SrcLoc
loc [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
== "Indigo.Frontend.Language" ->
        Program (StatementF IndigoM) a -> IndigoM a
forall a. Program (StatementF IndigoM) a -> IndigoM a
IndigoM (Program (StatementF IndigoM) a -> IndigoM a)
-> (IndigoM a -> Program (StatementF IndigoM) a)
-> IndigoM a
-> IndigoM a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StatementF IndigoM a -> Program (StatementF IndigoM) a
forall (instr :: * -> *) a. instr a -> Program instr a
Instr (StatementF IndigoM a -> Program (StatementF IndigoM) a)
-> (IndigoM a -> StatementF IndigoM a)
-> IndigoM a
-> Program (StatementF IndigoM) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CallStack -> IndigoM a -> StatementF IndigoM a
forall (freer :: * -> *) a.
CallStack -> freer a -> StatementF freer a
CalledFrom (CallStack -> CallStack
popCallStack CallStack
HasCallStack => CallStack
callStack) (IndigoM a -> IndigoM a) -> IndigoM a -> IndigoM a
forall a b. (a -> b) -> a -> b
$ IndigoM a
iM
    | Bool
otherwise -> Text -> IndigoM a
forall a. HasCallStack => Text -> a
error (Text -> IndigoM a) -> Text -> IndigoM a
forall a b. (a -> b) -> a -> b
$ [Char] -> Text
forall a. IsString a => [Char] -> a
fromString ([Char] -> Text) -> [Char] -> Text
forall a b. (a -> b) -> a -> b
$
                    "Misuse of calledFrom: the call made from " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ SrcLoc -> [Char]
srcLocModule SrcLoc
loc [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ ". " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
                    "You've either forgotten to specify HasCallStack constraint for exported Indigo frontend function or " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
                    "exported calledFrom and called outside of Indigo.Frontend.Language module. " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
                    "Please, report this issue to Indigo developers."

liftIndigoState :: (forall inp. SomeIndigoState inp) -> IndigoM ()
liftIndigoState :: (forall (inp :: [*]). SomeIndigoState inp) -> IndigoM ()
liftIndigoState code :: forall (inp :: [*]). SomeIndigoState inp
code = Program (StatementF IndigoM) () -> IndigoM ()
forall a. Program (StatementF IndigoM) a -> IndigoM a
IndigoM (StatementF IndigoM () -> Program (StatementF IndigoM) ()
forall (instr :: * -> *) a. instr a -> Program instr a
Instr (StatementF IndigoM () -> Program (StatementF IndigoM) ())
-> StatementF IndigoM () -> Program (StatementF IndigoM) ()
forall a b. (a -> b) -> a -> b
$ (forall (inp :: [*]). SomeIndigoState inp) -> StatementF IndigoM ()
forall (freer :: * -> *).
(forall (inp :: [*]). SomeIndigoState inp) -> StatementF freer ()
LiftIndigoState forall (inp :: [*]). SomeIndigoState inp
code)

varModification
  :: (IsExpr ey y, IsObject x)
  => ([y, x] :-> '[x]) -> Var x -> ey -> IndigoM ()
varModification :: ('[y, x] :-> '[x]) -> Var x -> ey -> IndigoM ()
varModification act :: '[y, x] :-> '[x]
act v :: Var x
v = StatementF IndigoM () -> IndigoM ()
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF IndigoM () -> IndigoM ())
-> (ey -> StatementF IndigoM ()) -> ey -> IndigoM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ('[y, x] :-> '[x]) -> Var x -> Expr y -> StatementF IndigoM ()
forall x y (freer :: * -> *).
(IsObject x, KnownValue y) =>
('[y, x] :-> '[x]) -> Var x -> Expr y -> StatementF freer ()
VarModification '[y, x] :-> '[x]
act Var x
v (Expr y -> StatementF IndigoM ())
-> (ey -> Expr y) -> ey -> StatementF IndigoM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ey -> Expr y
forall a. ToExpr a => a -> Expr (ExprType a)
toExpr

----------------------------------------------------------------------------
-- Var creation and assignment
----------------------------------------------------------------------------

-- | Create a new variable with the result of the given expression as its initial value.
new :: (IsExpr ex x, HasCallStack) => ex -> IndigoM (Var x)
new :: ex -> IndigoM (Var x)
new = IndigoM (Var x) -> IndigoM (Var x)
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM (Var x) -> IndigoM (Var x))
-> (ex -> IndigoM (Var x)) -> ex -> IndigoM (Var x)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StatementF IndigoM (Var x) -> IndigoM (Var x)
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF IndigoM (Var x) -> IndigoM (Var x))
-> (ex -> StatementF IndigoM (Var x)) -> ex -> IndigoM (Var x)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr x -> StatementF IndigoM (Var x)
forall x (freer :: * -> *).
KnownValue x =>
Expr x -> StatementF freer (Var x)
NewVar (Expr x -> StatementF IndigoM (Var x))
-> (ex -> Expr x) -> ex -> StatementF IndigoM (Var x)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ex -> Expr x
forall a. ToExpr a => a -> Expr (ExprType a)
toExpr

-- | Set the given variable to the result of the given expression.
setVar :: (IsExpr ex x, HasCallStack) => Var x -> ex -> IndigoM ()
setVar :: Var x -> ex -> IndigoM ()
setVar v :: Var x
v = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ())
-> (ex -> IndigoM ()) -> ex -> IndigoM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StatementF IndigoM () -> IndigoM ()
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF IndigoM () -> IndigoM ())
-> (ex -> StatementF IndigoM ()) -> ex -> IndigoM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Var x -> Expr x -> StatementF IndigoM ()
forall x (freer :: * -> *).
KnownValue x =>
Var x -> Expr x -> StatementF freer ()
SetVar Var x
v (Expr x -> StatementF IndigoM ())
-> (ex -> Expr x) -> ex -> StatementF IndigoM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ex -> Expr x
forall a. ToExpr a => a -> Expr (ExprType a)
toExpr

infixr 0 =:
(=:) :: (IsExpr ex x, HasCallStack) => Var x -> ex -> IndigoM ()
v :: Var x
v =: :: Var x -> ex -> IndigoM ()
=: e :: ex
e = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ()) -> IndigoM () -> IndigoM ()
forall a b. (a -> b) -> a -> b
$ Var x -> ex -> IndigoM ()
forall ex x.
(IsExpr ex x, HasCallStack) =>
Var x -> ex -> IndigoM ()
setVar Var x
v ex
e

setField
  :: ( ex :~> ftype
     , IsObject dt
     , IsObject ftype
     , HasField dt fname ftype
     , HasCallStack
     )
  => Var dt -> Label fname -> ex -> IndigoM ()
setField :: Var dt -> Label fname -> ex -> IndigoM ()
setField v :: Var dt
v fName :: Label fname
fName = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ())
-> (ex -> IndigoM ()) -> ex -> IndigoM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StatementF IndigoM () -> IndigoM ()
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF IndigoM () -> IndigoM ())
-> (ex -> StatementF IndigoM ()) -> ex -> IndigoM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Var dt -> Label fname -> Expr ftype -> StatementF IndigoM ()
forall dt ftype (st :: Symbol) (cont :: * -> *).
(IsObject dt, IsObject ftype, HasField dt st ftype) =>
Var dt -> Label st -> Expr ftype -> StatementF cont ()
SetField Var dt
v Label fname
fName (Expr ftype -> StatementF IndigoM ())
-> (ex -> Expr ftype) -> ex -> StatementF IndigoM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ex -> Expr ftype
forall a. ToExpr a => a -> Expr (ExprType a)
toExpr

(+=)
  :: ( IsExpr ex1 n, IsObject m
     , ArithOpHs M.Add n m, ArithResHs M.Add n m ~ m
     , HasCallStack
     ) => Var m -> ex1 -> IndigoM ()
+= :: Var m -> ex1 -> IndigoM ()
(+=) = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ())
-> (Var m -> ex1 -> IndigoM ()) -> Var m -> ex1 -> IndigoM ()
forall a b c. SuperComposition a b c => a -> b -> c
... ('[n, m] :-> '[m]) -> Var m -> ex1 -> IndigoM ()
forall ey y x.
(IsExpr ey y, IsObject x) =>
('[y, x] :-> '[x]) -> Var x -> ey -> IndigoM ()
varModification '[n, m] :-> '[m]
forall n m (s :: [*]).
ArithOpHs Add n m =>
(n : m : s) :-> (ArithResHs Add n m : s)
L.add

(-=)
  :: ( IsExpr ex1 n, IsObject m
     , ArithOpHs M.Sub n m, ArithResHs M.Sub n m ~ m
     , HasCallStack
     ) => Var m -> ex1 -> IndigoM ()
-= :: Var m -> ex1 -> IndigoM ()
(-=) = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ())
-> (Var m -> ex1 -> IndigoM ()) -> Var m -> ex1 -> IndigoM ()
forall a b c. SuperComposition a b c => a -> b -> c
... ('[n, m] :-> '[m]) -> Var m -> ex1 -> IndigoM ()
forall ey y x.
(IsExpr ey y, IsObject x) =>
('[y, x] :-> '[x]) -> Var x -> ey -> IndigoM ()
varModification '[n, m] :-> '[m]
forall n m (s :: [*]).
ArithOpHs Sub n m =>
(n : m : s) :-> (ArithResHs Sub n m : s)
L.sub

(*=)
  :: ( IsExpr ex1 n, IsObject m
     , ArithOpHs M.Mul n m, ArithResHs M.Mul n m ~ m
     , HasCallStack
     ) => Var m -> ex1 -> IndigoM ()
*= :: Var m -> ex1 -> IndigoM ()
(*=) = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ())
-> (Var m -> ex1 -> IndigoM ()) -> Var m -> ex1 -> IndigoM ()
forall a b c. SuperComposition a b c => a -> b -> c
... ('[n, m] :-> '[m]) -> Var m -> ex1 -> IndigoM ()
forall ey y x.
(IsExpr ey y, IsObject x) =>
('[y, x] :-> '[x]) -> Var x -> ey -> IndigoM ()
varModification '[n, m] :-> '[m]
forall n m (s :: [*]).
ArithOpHs Mul n m =>
(n : m : s) :-> (ArithResHs Mul n m : s)
L.mul

(||=)
  :: ( IsExpr ex1 n, IsObject m
     , ArithOpHs M.Or n m, ArithResHs M.Or n m ~ m
     , HasCallStack
     ) => Var m -> ex1 -> IndigoM ()
||= :: Var m -> ex1 -> IndigoM ()
(||=) = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ())
-> (Var m -> ex1 -> IndigoM ()) -> Var m -> ex1 -> IndigoM ()
forall a b c. SuperComposition a b c => a -> b -> c
... ('[n, m] :-> '[m]) -> Var m -> ex1 -> IndigoM ()
forall ey y x.
(IsExpr ey y, IsObject x) =>
('[y, x] :-> '[x]) -> Var x -> ey -> IndigoM ()
varModification '[n, m] :-> '[m]
forall n m (s :: [*]).
ArithOpHs Or n m =>
(n : m : s) :-> (ArithResHs Or n m : s)
L.or

(&&=)
  :: ( IsExpr ex1 n, IsObject m
     , ArithOpHs M.And n m, ArithResHs M.And n m ~ m
     , HasCallStack
     ) => Var m -> ex1 -> IndigoM ()
&&= :: Var m -> ex1 -> IndigoM ()
(&&=) = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ())
-> (Var m -> ex1 -> IndigoM ()) -> Var m -> ex1 -> IndigoM ()
forall a b c. SuperComposition a b c => a -> b -> c
... ('[n, m] :-> '[m]) -> Var m -> ex1 -> IndigoM ()
forall ey y x.
(IsExpr ey y, IsObject x) =>
('[y, x] :-> '[x]) -> Var x -> ey -> IndigoM ()
varModification '[n, m] :-> '[m]
forall n m (s :: [*]).
ArithOpHs And n m =>
(n : m : s) :-> (ArithResHs And n m : s)
L.and

(^=)
  :: ( IsExpr ex1 n, IsObject m
     , ArithOpHs M.Xor n m, ArithResHs M.Xor n m ~ m
     , HasCallStack
     ) => Var m -> ex1 -> IndigoM ()
^= :: Var m -> ex1 -> IndigoM ()
(^=) = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ())
-> (Var m -> ex1 -> IndigoM ()) -> Var m -> ex1 -> IndigoM ()
forall a b c. SuperComposition a b c => a -> b -> c
... ('[n, m] :-> '[m]) -> Var m -> ex1 -> IndigoM ()
forall ey y x.
(IsExpr ey y, IsObject x) =>
('[y, x] :-> '[x]) -> Var x -> ey -> IndigoM ()
varModification '[n, m] :-> '[m]
forall n m (s :: [*]).
ArithOpHs Xor n m =>
(n : m : s) :-> (ArithResHs Xor n m : s)
L.xor

(<<<=)
  :: ( IsExpr ex1 n, IsObject m
     , ArithOpHs M.Lsl n m, ArithResHs M.Lsl n m ~ m
     , HasCallStack
     ) => Var m -> ex1 -> IndigoM ()
<<<= :: Var m -> ex1 -> IndigoM ()
(<<<=) = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ())
-> (Var m -> ex1 -> IndigoM ()) -> Var m -> ex1 -> IndigoM ()
forall a b c. SuperComposition a b c => a -> b -> c
... ('[n, m] :-> '[m]) -> Var m -> ex1 -> IndigoM ()
forall ey y x.
(IsExpr ey y, IsObject x) =>
('[y, x] :-> '[x]) -> Var x -> ey -> IndigoM ()
varModification '[n, m] :-> '[m]
forall n m (s :: [*]).
ArithOpHs Lsl n m =>
(n : m : s) :-> (ArithResHs Lsl n m : s)
L.lsl

(>>>=)
  :: ( IsExpr ex1 n, IsObject m
     , ArithOpHs M.Lsr n m, ArithResHs M.Lsr n m ~ m
     , HasCallStack
     ) => Var m -> ex1 -> IndigoM ()
>>>= :: Var m -> ex1 -> IndigoM ()
(>>>=) = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ())
-> (Var m -> ex1 -> IndigoM ()) -> Var m -> ex1 -> IndigoM ()
forall a b c. SuperComposition a b c => a -> b -> c
... ('[n, m] :-> '[m]) -> Var m -> ex1 -> IndigoM ()
forall ey y x.
(IsExpr ey y, IsObject x) =>
('[y, x] :-> '[x]) -> Var x -> ey -> IndigoM ()
varModification '[n, m] :-> '[m]
forall n m (s :: [*]).
ArithOpHs Lsr n m =>
(n : m : s) :-> (ArithResHs Lsr n m : s)
L.lsr

----------------------------------------------------------------------------
-- Storage Fields
----------------------------------------------------------------------------

-- | Sets a storage field to a new value.
setStorageField
  :: forall store name ftype ex.
     ( HasStorage store
     , ex :~> ftype
     , IsObject store
     , IsObject ftype
     , HasField store name ftype
     , HasCallStack
     )
  => Label name -> ex -> IndigoM ()
setStorageField :: Label name -> ex -> IndigoM ()
setStorageField field :: Label name
field expr :: ex
expr = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ()) -> IndigoM () -> IndigoM ()
forall a b. (a -> b) -> a -> b
$ Var store -> Label name -> ex -> IndigoM ()
forall ex ftype dt (fname :: Symbol).
(ex :~> ftype, IsObject dt, IsObject ftype,
 HasField dt fname ftype, HasCallStack) =>
Var dt -> Label fname -> ex -> IndigoM ()
setField (HasStorage store => Var store
forall st. HasStorage st => Var st
storageVar @store) Label name
field ex
expr

-- | Updates a storage field by using an updating 'IndigoM'.
updateStorageField
  :: forall store ftype fname fex.
     ( HasStorage store
     , fex :~> ftype
     , HasField store fname ftype
     , IsObject store
     , IsObject ftype
     , HasCallStack
     )
  => Label fname
  -> (Var ftype -> IndigoM fex)
  -> IndigoM ()
updateStorageField :: Label fname -> (Var ftype -> IndigoM fex) -> IndigoM ()
updateStorageField field :: Label fname
field upd :: Var ftype -> IndigoM fex
upd = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ()) -> IndigoM () -> IndigoM ()
forall a b. (a -> b) -> a -> b
$ IndigoM () -> IndigoM ()
forall a.
(ScopeCodeGen a, HasCallStack) =>
IndigoM a -> IndigoFunction a
scope (IndigoM () -> IndigoM ()) -> IndigoM () -> IndigoM ()
forall a b. (a -> b) -> a -> b
$ do
  let storage :: Var store
storage = HasStorage store => Var store
forall st. HasStorage st => Var st
storageVar @store
  Var ftype
fieldVar <- Expr ftype -> IndigoM (Var ftype)
forall ex x. (IsExpr ex x, HasCallStack) => ex -> IndigoM (Var x)
new(Expr ftype -> IndigoM (Var ftype))
-> Expr ftype -> IndigoM (Var ftype)
forall a b. (a -> b) -> a -> b
$ Var store
storage Var store -> Label fname -> Expr ftype
forall dt (name :: Symbol) ftype exDt.
(HasField dt name ftype, exDt :~> dt) =>
exDt -> Label name -> Expr ftype
#! Label fname
field
  fex
expr <- Var ftype -> IndigoM fex
upd Var ftype
fieldVar
  Var store -> Label fname -> fex -> IndigoM ()
forall ex ftype dt (fname :: Symbol).
(ex :~> ftype, IsObject dt, IsObject ftype,
 HasField dt fname ftype, HasCallStack) =>
Var dt -> Label fname -> ex -> IndigoM ()
setField Var store
storage Label fname
field fex
expr

-- | Get a field from the storage, returns a variable.
--
-- Note that the storage type almost always needs to be specified.
getStorageField
  :: forall store ftype fname .
     ( HasStorage store
     , HasField store fname ftype
     , HasCallStack
     )
  => Label fname -> IndigoM (Var ftype)
getStorageField :: Label fname -> IndigoM (Var ftype)
getStorageField field :: Label fname
field = IndigoM (Var ftype) -> IndigoM (Var ftype)
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM (Var ftype) -> IndigoM (Var ftype))
-> IndigoM (Var ftype) -> IndigoM (Var ftype)
forall a b. (a -> b) -> a -> b
$ Expr ftype -> IndigoM (Var ftype)
forall ex x. (IsExpr ex x, HasCallStack) => ex -> IndigoM (Var x)
new(Expr ftype -> IndigoM (Var ftype))
-> Expr ftype -> IndigoM (Var ftype)
forall a b. (a -> b) -> a -> b
$ HasStorage store => Var store
forall st. HasStorage st => Var st
storageVar @store Var store -> Label fname -> Expr ftype
forall dt (name :: Symbol) ftype exDt.
(HasField dt name ftype, exDt :~> dt) =>
exDt -> Label name -> Expr ftype
#! Label fname
field

----------------------------------------------------------------------------
-- Conditional
----------------------------------------------------------------------------

if_
  :: forall a b ex . (IfConstraint a b, ex :~> Bool, HasCallStack)
  => ex
  -> IndigoM a
  -> IndigoM b
  -> IndigoM (RetVars a)
if_ :: ex -> IndigoM a -> IndigoM b -> IndigoM (RetVars a)
if_ ex :: ex
ex tb :: IndigoM a
tb fb :: IndigoM b
fb = IndigoM (RetVars' (ClassifyReturnValue b) b) -> IndigoM (RetVars a)
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM (RetVars' (ClassifyReturnValue b) b)
 -> IndigoM (RetVars a))
-> IndigoM (RetVars' (ClassifyReturnValue b) b)
-> IndigoM (RetVars a)
forall a b. (a -> b) -> a -> b
$ StatementF IndigoM (RetVars' (ClassifyReturnValue b) b)
-> IndigoM (RetVars' (ClassifyReturnValue b) b)
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF IndigoM (RetVars' (ClassifyReturnValue b) b)
 -> IndigoM (RetVars' (ClassifyReturnValue b) b))
-> StatementF IndigoM (RetVars' (ClassifyReturnValue b) b)
-> IndigoM (RetVars' (ClassifyReturnValue b) b)
forall a b. (a -> b) -> a -> b
$ Expr Bool
-> IndigoM a -> IndigoM b -> StatementF IndigoM (RetVars a)
forall a b (freer :: * -> *).
IfConstraint a b =>
Expr Bool -> freer a -> freer b -> StatementF freer (RetVars a)
If (ex -> Expr (ExprType ex)
forall a. ToExpr a => a -> Expr (ExprType a)
toExpr ex
ex) IndigoM a
tb IndigoM b
fb

-- | Run the instruction when the condition is met, do nothing otherwise.
when :: (exc :~> Bool, HasCallStack) => exc -> IndigoM () -> IndigoM ()
when :: exc -> IndigoM () -> IndigoM ()
when cond :: exc
cond expr :: IndigoM ()
expr = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ()) -> IndigoM () -> IndigoM ()
forall a b. (a -> b) -> a -> b
$ exc -> IndigoM () -> IndigoM () -> IndigoM (RetVars ())
forall a b ex.
(IfConstraint a b, ex :~> Bool, HasCallStack) =>
ex -> IndigoM a -> IndigoM b -> IndigoM (RetVars a)
if_ exc
cond IndigoM ()
expr (() -> IndigoM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ())

-- | Reverse of 'when'.
unless :: (exc :~> Bool, HasCallStack) => exc -> IndigoM () -> IndigoM ()
unless :: exc -> IndigoM () -> IndigoM ()
unless cond :: exc
cond expr :: IndigoM ()
expr = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ()) -> IndigoM () -> IndigoM ()
forall a b. (a -> b) -> a -> b
$ exc -> IndigoM () -> IndigoM () -> IndigoM (RetVars ())
forall a b ex.
(IfConstraint a b, ex :~> Bool, HasCallStack) =>
ex -> IndigoM a -> IndigoM b -> IndigoM (RetVars a)
if_ exc
cond (() -> IndigoM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()) IndigoM ()
expr

ifSome
  :: forall x a b ex . (KnownValue x, ex :~> Maybe x, IfConstraint a b, HasCallStack)
  => ex
  -> (Var x -> IndigoM a)
  -> IndigoM b
  -> IndigoM (RetVars a)
ifSome :: ex -> (Var x -> IndigoM a) -> IndigoM b -> IndigoM (RetVars a)
ifSome ex :: ex
ex tb :: Var x -> IndigoM a
tb fb :: IndigoM b
fb = IndigoM (RetVars' (ClassifyReturnValue b) b) -> IndigoM (RetVars a)
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM (RetVars' (ClassifyReturnValue b) b)
 -> IndigoM (RetVars a))
-> IndigoM (RetVars' (ClassifyReturnValue b) b)
-> IndigoM (RetVars a)
forall a b. (a -> b) -> a -> b
$ StatementF IndigoM (RetVars' (ClassifyReturnValue b) b)
-> IndigoM (RetVars' (ClassifyReturnValue b) b)
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF IndigoM (RetVars' (ClassifyReturnValue b) b)
 -> IndigoM (RetVars' (ClassifyReturnValue b) b))
-> StatementF IndigoM (RetVars' (ClassifyReturnValue b) b)
-> IndigoM (RetVars' (ClassifyReturnValue b) b)
forall a b. (a -> b) -> a -> b
$ Expr (Maybe x)
-> (Var x -> IndigoM a)
-> IndigoM b
-> StatementF IndigoM (RetVars a)
forall a b a (freer :: * -> *).
(IfConstraint a b, KnownValue a) =>
Expr (Maybe a)
-> (Var a -> freer a) -> freer b -> StatementF freer (RetVars a)
IfSome (ex -> Expr (ExprType ex)
forall a. ToExpr a => a -> Expr (ExprType a)
toExpr ex
ex) Var x -> IndigoM a
tb IndigoM b
fb

ifNone
  :: forall x a b ex . (KnownValue x, ex :~> Maybe x, IfConstraint a b, HasCallStack)
  => ex
  -> IndigoM b
  -> (Var x -> IndigoM a)
  -> IndigoM (RetVars a)
ifNone :: ex -> IndigoM b -> (Var x -> IndigoM a) -> IndigoM (RetVars a)
ifNone ex :: ex
ex fb :: IndigoM b
fb tb :: Var x -> IndigoM a
tb = IndigoM (RetVars' (ClassifyReturnValue b) b) -> IndigoM (RetVars a)
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM (RetVars' (ClassifyReturnValue b) b)
 -> IndigoM (RetVars a))
-> IndigoM (RetVars' (ClassifyReturnValue b) b)
-> IndigoM (RetVars a)
forall a b. (a -> b) -> a -> b
$ Expr (Maybe x)
-> (Var x -> IndigoM a) -> IndigoM b -> IndigoM (RetVars a)
forall x a b ex.
(KnownValue x, ex :~> Maybe x, IfConstraint a b, HasCallStack) =>
ex -> (Var x -> IndigoM a) -> IndigoM b -> IndigoM (RetVars a)
ifSome (ex -> Expr (ExprType ex)
forall a. ToExpr a => a -> Expr (ExprType a)
toExpr ex
ex) Var x -> IndigoM a
tb IndigoM b
fb

-- | Run the instruction when the given expression returns 'Just' a value,
-- do nothing otherwise.
whenSome
  :: forall x exa .
     ( KnownValue x
     , exa :~> Maybe x
     , HasCallStack
     )
  => exa
  -> (Var x -> IndigoM ())
  -> IndigoM ()
whenSome :: exa -> (Var x -> IndigoM ()) -> IndigoM ()
whenSome c :: exa
c f :: Var x -> IndigoM ()
f = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ()) -> IndigoM () -> IndigoM ()
forall a b. (a -> b) -> a -> b
$ exa -> (Var x -> IndigoM ()) -> IndigoM () -> IndigoM (RetVars ())
forall x a b ex.
(KnownValue x, ex :~> Maybe x, IfConstraint a b, HasCallStack) =>
ex -> (Var x -> IndigoM a) -> IndigoM b -> IndigoM (RetVars a)
ifSome exa
c Var x -> IndigoM ()
f (() -> IndigoM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ())

-- | Run the instruction when the given expression returns 'Nothing',
-- do nothing otherwise.
whenNone
  :: forall x exa .
     ( KnownValue x
     , exa :~> Maybe x
     , HasCallStack
     )
  => exa
  -> IndigoM ()
  -> IndigoM ()
whenNone :: exa -> IndigoM () -> IndigoM ()
whenNone c :: exa
c f :: IndigoM ()
f = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ()) -> IndigoM () -> IndigoM ()
forall a b. (a -> b) -> a -> b
$ exa -> (Var x -> IndigoM ()) -> IndigoM () -> IndigoM (RetVars ())
forall x a b ex.
(KnownValue x, ex :~> Maybe x, IfConstraint a b, HasCallStack) =>
ex -> (Var x -> IndigoM a) -> IndigoM b -> IndigoM (RetVars a)
ifSome exa
c (\_ -> () -> IndigoM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()) IndigoM ()
f

ifRight
  :: forall x y a b ex .
     ( KnownValue x
     , KnownValue y
     , ex :~> Either y x
     , IfConstraint a b
     , HasCallStack
     )
  => ex
  -> (Var x -> IndigoM a)
  -> (Var y -> IndigoM b)
  -> IndigoM (RetVars a)
ifRight :: ex
-> (Var x -> IndigoM a)
-> (Var y -> IndigoM b)
-> IndigoM (RetVars a)
ifRight ex :: ex
ex rb :: Var x -> IndigoM a
rb lb :: Var y -> IndigoM b
lb = IndigoM (RetVars' (ClassifyReturnValue b) b) -> IndigoM (RetVars a)
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM (RetVars' (ClassifyReturnValue b) b)
 -> IndigoM (RetVars a))
-> IndigoM (RetVars' (ClassifyReturnValue b) b)
-> IndigoM (RetVars a)
forall a b. (a -> b) -> a -> b
$ StatementF IndigoM (RetVars' (ClassifyReturnValue b) b)
-> IndigoM (RetVars' (ClassifyReturnValue b) b)
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF IndigoM (RetVars' (ClassifyReturnValue b) b)
 -> IndigoM (RetVars' (ClassifyReturnValue b) b))
-> StatementF IndigoM (RetVars' (ClassifyReturnValue b) b)
-> IndigoM (RetVars' (ClassifyReturnValue b) b)
forall a b. (a -> b) -> a -> b
$ Expr (Either y x)
-> (Var x -> IndigoM a)
-> (Var y -> IndigoM b)
-> StatementF IndigoM (RetVars a)
forall a b x y (freer :: * -> *).
(IfConstraint a b, KnownValue x, KnownValue y) =>
Expr (Either y x)
-> (Var x -> freer a)
-> (Var y -> freer b)
-> StatementF freer (RetVars a)
IfRight (ex -> Expr (ExprType ex)
forall a. ToExpr a => a -> Expr (ExprType a)
toExpr ex
ex) Var x -> IndigoM a
rb Var y -> IndigoM b
lb

ifLeft
  :: forall x y a b ex .
     ( KnownValue x
     , KnownValue y
     , ex :~> Either y x
     , IfConstraint a b
     , HasCallStack
     )
  => ex
  -> (Var y -> IndigoM b)
  -> (Var x -> IndigoM a)
  -> IndigoM (RetVars a)
ifLeft :: ex
-> (Var y -> IndigoM b)
-> (Var x -> IndigoM a)
-> IndigoM (RetVars a)
ifLeft ex :: ex
ex lb :: Var y -> IndigoM b
lb rb :: Var x -> IndigoM a
rb = IndigoM (RetVars' (ClassifyReturnValue b) b) -> IndigoM (RetVars a)
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM (RetVars' (ClassifyReturnValue b) b)
 -> IndigoM (RetVars a))
-> IndigoM (RetVars' (ClassifyReturnValue b) b)
-> IndigoM (RetVars a)
forall a b. (a -> b) -> a -> b
$ ex
-> (Var x -> IndigoM a)
-> (Var y -> IndigoM b)
-> IndigoM (RetVars a)
forall x y a b ex.
(KnownValue x, KnownValue y, ex :~> Either y x, IfConstraint a b,
 HasCallStack) =>
ex
-> (Var x -> IndigoM a)
-> (Var y -> IndigoM b)
-> IndigoM (RetVars a)
ifRight ex
ex Var x -> IndigoM a
rb Var y -> IndigoM b
lb

whenRight
  :: forall x y ex .
     ( KnownValue x
     , KnownValue y
     , ex :~> Either y x
     , HasCallStack
     )
  => ex
  -> (Var x -> IndigoM ())
  -> IndigoM ()
whenRight :: ex -> (Var x -> IndigoM ()) -> IndigoM ()
whenRight c :: ex
c f :: Var x -> IndigoM ()
f = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ()) -> IndigoM () -> IndigoM ()
forall a b. (a -> b) -> a -> b
$ ex
-> (Var x -> IndigoM ())
-> (Var y -> IndigoM ())
-> IndigoM (RetVars ())
forall x y a b ex.
(KnownValue x, KnownValue y, ex :~> Either y x, IfConstraint a b,
 HasCallStack) =>
ex
-> (Var x -> IndigoM a)
-> (Var y -> IndigoM b)
-> IndigoM (RetVars a)
ifRight ex
c Var x -> IndigoM ()
f (\_ -> () -> IndigoM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ())

whenLeft
  :: forall x y ex .
     ( KnownValue x
     , KnownValue y
     , ex :~> Either y x
     , HasCallStack
     )
  => ex
  -> (Var y -> IndigoM ())
  -> IndigoM ()
whenLeft :: ex -> (Var y -> IndigoM ()) -> IndigoM ()
whenLeft c :: ex
c f :: Var y -> IndigoM ()
f = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ()) -> IndigoM () -> IndigoM ()
forall a b. (a -> b) -> a -> b
$ ex
-> (Var x -> IndigoM ())
-> (Var y -> IndigoM ())
-> IndigoM (RetVars ())
forall x y a b ex.
(KnownValue x, KnownValue y, ex :~> Either y x, IfConstraint a b,
 HasCallStack) =>
ex
-> (Var x -> IndigoM a)
-> (Var y -> IndigoM b)
-> IndigoM (RetVars a)
ifRight ex
c (\_ -> () -> IndigoM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()) Var y -> IndigoM ()
f

ifCons
  :: forall x a b ex . (KnownValue x, ex :~> List x, IfConstraint a b, HasCallStack)
  => ex
  -> (Var x -> Var (List x) -> IndigoM a)
  -> IndigoM b
  -> IndigoM (RetVars a)
ifCons :: ex
-> (Var x -> Var (List x) -> IndigoM a)
-> IndigoM b
-> IndigoM (RetVars a)
ifCons ex :: ex
ex tb :: Var x -> Var (List x) -> IndigoM a
tb fb :: IndigoM b
fb = IndigoM (RetVars' (ClassifyReturnValue b) b) -> IndigoM (RetVars a)
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM (RetVars' (ClassifyReturnValue b) b)
 -> IndigoM (RetVars a))
-> IndigoM (RetVars' (ClassifyReturnValue b) b)
-> IndigoM (RetVars a)
forall a b. (a -> b) -> a -> b
$ StatementF IndigoM (RetVars' (ClassifyReturnValue b) b)
-> IndigoM (RetVars' (ClassifyReturnValue b) b)
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF IndigoM (RetVars' (ClassifyReturnValue b) b)
 -> IndigoM (RetVars' (ClassifyReturnValue b) b))
-> StatementF IndigoM (RetVars' (ClassifyReturnValue b) b)
-> IndigoM (RetVars' (ClassifyReturnValue b) b)
forall a b. (a -> b) -> a -> b
$ Expr (List x)
-> (Var x -> Var (List x) -> IndigoM a)
-> IndigoM b
-> StatementF IndigoM (RetVars a)
forall a b x (freer :: * -> *).
(IfConstraint a b, KnownValue x) =>
Expr (List x)
-> (Var x -> Var (List x) -> freer a)
-> freer b
-> StatementF freer (RetVars a)
IfCons (ex -> Expr (ExprType ex)
forall a. ToExpr a => a -> Expr (ExprType a)
toExpr ex
ex) Var x -> Var (List x) -> IndigoM a
tb IndigoM b
fb

----------------------------------------------------------------------------
-- Case
----------------------------------------------------------------------------

-- | A case statement for indigo. See examples for a sample usage.
caseRec
  :: forall dt guard ret clauses .
     ( CaseCommonF (IndigoMCaseClauseL IndigoM) dt ret clauses
     , guard :~> dt
     , HasCallStack
     )
  => guard
  -> clauses
  -> IndigoM (RetVars ret)
caseRec :: guard -> clauses -> IndigoM (RetVars ret)
caseRec g :: guard
g = IndigoM (RetVars ret) -> IndigoM (RetVars ret)
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM (RetVars ret) -> IndigoM (RetVars ret))
-> (clauses -> IndigoM (RetVars ret))
-> clauses
-> IndigoM (RetVars ret)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StatementF IndigoM (RetVars ret) -> IndigoM (RetVars ret)
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF IndigoM (RetVars ret) -> IndigoM (RetVars ret))
-> (clauses -> StatementF IndigoM (RetVars ret))
-> clauses
-> IndigoM (RetVars ret)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr dt -> clauses -> StatementF IndigoM (RetVars ret)
forall (freer :: * -> *) dt ret dt.
CaseCommonF (IndigoMCaseClauseL freer) dt ret dt =>
Expr dt -> dt -> StatementF freer (RetVars ret)
Case (guard -> Expr (ExprType guard)
forall a. ToExpr a => a -> Expr (ExprType a)
toExpr guard
g)

-- | 'caseRec' for tuples.
case_
  :: forall dt guard ret clauses.
     ( CaseCommonF (IndigoMCaseClauseL IndigoM) dt ret clauses
     , RecFromTuple clauses
     , guard :~> dt
     , HasCallStack
     )
  => guard
  -> IsoRecTuple clauses
  -> IndigoM (RetVars ret)
case_ :: guard -> IsoRecTuple clauses -> IndigoM (RetVars ret)
case_ g :: guard
g = IndigoM (RetVars ret) -> IndigoM (RetVars ret)
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM (RetVars ret) -> IndigoM (RetVars ret))
-> (IsoRecTuple
      (Rec (IndigoMCaseClauseL IndigoM ret) (GCaseClauses (Rep dt)))
    -> IndigoM (RetVars ret))
-> IsoRecTuple
     (Rec (IndigoMCaseClauseL IndigoM ret) (GCaseClauses (Rep dt)))
-> IndigoM (RetVars ret)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr dt -> clauses -> IndigoM (RetVars ret)
forall dt guard ret clauses.
(CaseCommonF (IndigoMCaseClauseL IndigoM) dt ret clauses,
 guard :~> dt, HasCallStack) =>
guard -> clauses -> IndigoM (RetVars ret)
caseRec (guard -> Expr (ExprType guard)
forall a. ToExpr a => a -> Expr (ExprType a)
toExpr guard
g) (clauses -> IndigoM (RetVars ret))
-> (IsoRecTuple
      (Rec (IndigoMCaseClauseL IndigoM ret) (GCaseClauses (Rep dt)))
    -> clauses)
-> IsoRecTuple
     (Rec (IndigoMCaseClauseL IndigoM ret) (GCaseClauses (Rep dt)))
-> IndigoM (RetVars ret)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RecFromTuple clauses => IsoRecTuple clauses -> clauses
forall r. RecFromTuple r => IsoRecTuple r -> r
recFromTuple @clauses


-- | 'caseRec' for pattern-matching on parameter.
entryCaseRec
  :: forall dt entrypointKind guard ret clauses .
     ( CaseCommonF (IndigoMCaseClauseL IndigoM) dt ret clauses
     , DocumentEntrypoints entrypointKind dt
     , guard :~> dt
     , HasCallStack
     )
  => Proxy entrypointKind
  -> guard
  -> clauses
  -> IndigoM (RetVars ret)
entryCaseRec :: Proxy entrypointKind -> guard -> clauses -> IndigoM (RetVars ret)
entryCaseRec proxy :: Proxy entrypointKind
proxy g :: guard
g cls :: clauses
cls = IndigoM (RetVars ret) -> IndigoM (RetVars ret)
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM (RetVars ret) -> IndigoM (RetVars ret))
-> (StatementF IndigoM (RetVars ret) -> IndigoM (RetVars ret))
-> StatementF IndigoM (RetVars ret)
-> IndigoM (RetVars ret)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StatementF IndigoM (RetVars ret) -> IndigoM (RetVars ret)
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF IndigoM (RetVars ret) -> IndigoM (RetVars ret))
-> StatementF IndigoM (RetVars ret) -> IndigoM (RetVars ret)
forall a b. (a -> b) -> a -> b
$ Proxy entrypointKind
-> Expr dt -> clauses -> StatementF IndigoM (RetVars ret)
forall (freer :: * -> *) dt ret clauses entrypointKind.
(CaseCommonF (IndigoMCaseClauseL freer) dt ret clauses,
 DocumentEntrypoints entrypointKind dt) =>
Proxy entrypointKind
-> Expr dt -> clauses -> StatementF freer (RetVars ret)
EntryCase Proxy entrypointKind
proxy (guard -> Expr (ExprType guard)
forall a. ToExpr a => a -> Expr (ExprType a)
toExpr guard
g) clauses
cls

-- | 'entryCaseRec' for tuples.
entryCase
  :: forall dt entrypointKind guard ret clauses .
     ( CaseCommonF (IndigoMCaseClauseL IndigoM) dt ret clauses
     , RecFromTuple clauses
     , DocumentEntrypoints entrypointKind dt
     , guard :~> dt
     , HasCallStack
     )
  => Proxy entrypointKind
  -> guard
  -> IsoRecTuple clauses
  -> IndigoM (RetVars ret)
entryCase :: Proxy entrypointKind
-> guard -> IsoRecTuple clauses -> IndigoM (RetVars ret)
entryCase proxy :: Proxy entrypointKind
proxy g :: guard
g = IndigoM (RetVars ret) -> IndigoM (RetVars ret)
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM (RetVars ret) -> IndigoM (RetVars ret))
-> (IsoRecTuple
      (Rec (IndigoMCaseClauseL IndigoM ret) (GCaseClauses (Rep dt)))
    -> IndigoM (RetVars ret))
-> IsoRecTuple
     (Rec (IndigoMCaseClauseL IndigoM ret) (GCaseClauses (Rep dt)))
-> IndigoM (RetVars ret)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy entrypointKind -> guard -> clauses -> IndigoM (RetVars ret)
forall dt entrypointKind guard ret clauses.
(CaseCommonF (IndigoMCaseClauseL IndigoM) dt ret clauses,
 DocumentEntrypoints entrypointKind dt, guard :~> dt,
 HasCallStack) =>
Proxy entrypointKind -> guard -> clauses -> IndigoM (RetVars ret)
entryCaseRec Proxy entrypointKind
proxy guard
g (clauses -> IndigoM (RetVars ret))
-> (IsoRecTuple
      (Rec (IndigoMCaseClauseL IndigoM ret) (GCaseClauses (Rep dt)))
    -> clauses)
-> IsoRecTuple
     (Rec (IndigoMCaseClauseL IndigoM ret) (GCaseClauses (Rep dt)))
-> IndigoM (RetVars ret)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RecFromTuple clauses => IsoRecTuple clauses -> clauses
forall r. RecFromTuple r => IsoRecTuple r -> r
recFromTuple @clauses

entryCaseSimple
  :: forall cp guard ret clauses .
     ( CaseCommonF (IndigoMCaseClauseL IndigoM) cp ret clauses
     , RecFromTuple clauses
     , DocumentEntrypoints PlainEntrypointsKind cp
     , NiceParameterFull cp
     , RequireFlatParamEps cp
     , guard :~> cp
     , HasCallStack
     )
  => guard
  -> IsoRecTuple clauses
  -> IndigoM (RetVars ret)
entryCaseSimple :: guard -> IsoRecTuple clauses -> IndigoM (RetVars ret)
entryCaseSimple g :: guard
g = IndigoM (RetVars ret) -> IndigoM (RetVars ret)
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM (RetVars ret) -> IndigoM (RetVars ret))
-> (IsoRecTuple
      (Rec (IndigoMCaseClauseL IndigoM ret) (GCaseClauses (Rep cp)))
    -> IndigoM (RetVars ret))
-> IsoRecTuple
     (Rec (IndigoMCaseClauseL IndigoM ret) (GCaseClauses (Rep cp)))
-> IndigoM (RetVars ret)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StatementF IndigoM (RetVars ret) -> IndigoM (RetVars ret)
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF IndigoM (RetVars ret) -> IndigoM (RetVars ret))
-> (IsoRecTuple
      (Rec (IndigoMCaseClauseL IndigoM ret) (GCaseClauses (Rep cp)))
    -> StatementF IndigoM (RetVars ret))
-> IsoRecTuple
     (Rec (IndigoMCaseClauseL IndigoM ret) (GCaseClauses (Rep cp)))
-> IndigoM (RetVars ret)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr cp -> clauses -> StatementF IndigoM (RetVars ret)
forall (freer :: * -> *) cp ret x.
(CaseCommonF (IndigoMCaseClauseL freer) cp ret x,
 DocumentEntrypoints PlainEntrypointsKind cp, NiceParameterFull cp,
 RequireFlatParamEps cp) =>
Expr cp -> x -> StatementF freer (RetVars ret)
EntryCaseSimple (guard -> Expr (ExprType guard)
forall a. ToExpr a => a -> Expr (ExprType a)
toExpr guard
g) (clauses -> StatementF IndigoM (RetVars ret))
-> (IsoRecTuple
      (Rec (IndigoMCaseClauseL IndigoM ret) (GCaseClauses (Rep cp)))
    -> clauses)
-> IsoRecTuple
     (Rec (IndigoMCaseClauseL IndigoM ret) (GCaseClauses (Rep cp)))
-> StatementF IndigoM (RetVars ret)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RecFromTuple clauses => IsoRecTuple clauses -> clauses
forall r. RecFromTuple r => IsoRecTuple r -> r
recFromTuple @clauses

{-# DEPRECATED (//->) "use '#=' instead" #-}
-- | An alias for '#=' kept only for backward compatibility.
(//->)
  :: ( name ~ (AppendSymbol "c" ctor)
     , KnownValue x
     , ScopeCodeGen retBr
     , ret ~ RetExprs retBr
     , RetOutStack ret ~ RetOutStack retBr
     )
  => Label name
  -> (Var x -> IndigoM retBr)
  -> IndigoMCaseClauseL IndigoM ret ('CaseClauseParam ctor ('OneField x))
//-> :: Label name
-> (Var x -> IndigoM retBr)
-> IndigoMCaseClauseL
     IndigoM ret ('CaseClauseParam ctor ('OneField x))
(//->) cName :: Label name
cName b :: Var x -> IndigoM retBr
b = Label name
-> (Var x -> IndigoM retBr)
-> IndigoMCaseClauseL
     IndigoM ret ('CaseClauseParam ctor ('OneField x))
forall (name :: Symbol) (ctor :: Symbol) x retBr ret
       (freer :: * -> *).
(name ~ AppendSymbol "c" ctor, KnownValue x, ScopeCodeGen retBr,
 ret ~ RetExprs retBr, RetOutStack ret ~ RetOutStack retBr) =>
Label name
-> (Var x -> freer retBr)
-> IndigoMCaseClauseL
     freer ret ('CaseClauseParam ctor ('OneField x))
OneFieldIndigoMCaseClauseL Label name
cName Var x -> IndigoM retBr
b
infixr 0 //->

-- | Use this instead of '/->'.
--
-- This operator is like '/->' but wraps a body into 'IndigoAnyOut',
-- which is needed for two reasons: to allow having any output stack
-- and to allow returning not exactly the same values.
--
-- It has the added benefit of not being an arrow, so in case the body of the
-- clause is a lambda there won't be several.
(#=)
  :: ( name ~ (AppendSymbol "c" ctor)
     , KnownValue x
     , ScopeCodeGen retBr
     , ret ~ RetExprs retBr
     , RetOutStack ret ~ RetOutStack retBr
     )
  => Label name
  -> (Var x -> IndigoM retBr)
  -> IndigoMCaseClauseL IndigoM ret ('CaseClauseParam ctor ('OneField x))
#= :: Label name
-> (Var x -> IndigoM retBr)
-> IndigoMCaseClauseL
     IndigoM ret ('CaseClauseParam ctor ('OneField x))
(#=) cName :: Label name
cName b :: Var x -> IndigoM retBr
b = Label name
-> (Var x -> IndigoM retBr)
-> IndigoMCaseClauseL
     IndigoM ret ('CaseClauseParam ctor ('OneField x))
forall (name :: Symbol) (ctor :: Symbol) x retBr ret
       (freer :: * -> *).
(name ~ AppendSymbol "c" ctor, KnownValue x, ScopeCodeGen retBr,
 ret ~ RetExprs retBr, RetOutStack ret ~ RetOutStack retBr) =>
Label name
-> (Var x -> freer retBr)
-> IndigoMCaseClauseL
     freer ret ('CaseClauseParam ctor ('OneField x))
OneFieldIndigoMCaseClauseL Label name
cName Var x -> IndigoM retBr
b
infixr 0 #=

----------------------------------------------------------------------------
-- Scope & Functions
----------------------------------------------------------------------------

-- | Utility type for an 'IndigoM' that adds one element to the stack and returns
-- a variable pointing at it.
type IndigoFunction ret = IndigoM (RetVars ret)

-- | Utility type for an 'IndigoM' that does not modify the stack (only the
-- values in it) and returns nothing.
type IndigoProcedure = IndigoM ()

type IndigoEntrypoint param = param -> IndigoProcedure

scope
  :: forall a . (ScopeCodeGen a, HasCallStack)
  => IndigoM a
  -> IndigoFunction a
scope :: IndigoM a -> IndigoFunction a
scope = IndigoFunction a -> IndigoFunction a
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoFunction a -> IndigoFunction a)
-> (IndigoM a -> IndigoFunction a) -> IndigoM a -> IndigoFunction a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StatementF IndigoM (RetVars' (ClassifyReturnValue a) a)
-> IndigoFunction a
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF IndigoM (RetVars' (ClassifyReturnValue a) a)
 -> IndigoFunction a)
-> (IndigoM a
    -> StatementF IndigoM (RetVars' (ClassifyReturnValue a) a))
-> IndigoM a
-> IndigoFunction a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IndigoM a
-> StatementF IndigoM (RetVars' (ClassifyReturnValue a) a)
forall a (freer :: * -> *).
ScopeCodeGen a =>
freer a -> StatementF freer (RetVars a)
Scope

-- | Alias for 'scope' we use in the tutorial.
defFunction
  :: forall a . (ScopeCodeGen a, HasCallStack)
  => IndigoM a
  -> IndigoFunction a
defFunction :: IndigoM a -> IndigoFunction a
defFunction = IndigoFunction a -> IndigoFunction a
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoFunction a -> IndigoFunction a)
-> (IndigoM a -> IndigoFunction a) -> IndigoM a -> IndigoFunction a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IndigoM a -> IndigoFunction a
forall a.
(ScopeCodeGen a, HasCallStack) =>
IndigoM a -> IndigoFunction a
scope

-- | A more specific version of 'defFunction' meant to more easily create
-- 'IndigoContract's.
--
-- Used in the tutorial. The 'HasSideEffects' constraint is
-- specified to avoid the warning for redundant constraints.
defContract
  :: HasCallStack
  => (HasSideEffects => IndigoM ())
  -> (HasSideEffects => IndigoProcedure)
defContract :: (HasSideEffects => IndigoM ()) -> HasSideEffects => IndigoM ()
defContract = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ())
-> (IndigoM () -> IndigoM ()) -> IndigoM () -> IndigoM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IndigoM () -> IndigoM ()
forall a.
(ScopeCodeGen a, HasCallStack) =>
IndigoM a -> IndigoFunction a
scope

-- | Family of @defNamed*LambdaN@ functions put an Indigo computation
-- on the stack to later call it avoiding code duplication.
-- @defNamed*LambdaN@ takes a computation with N arguments.
-- This family of functions add some overhead to contract byte size
-- for every call of the function,
-- therefore, DON'T use @defNamed*LambdaN@ if:
-- * Your computation is pretty small.
--   It would be cheaper just to inline it, so use 'defFunction'.
-- * Your computation is called only once, in this case also use 'defFunction'.
--
-- Also, pay attention that @defNamed*LambdaN@ accepts a string that is
-- a name of the passed computation. Be careful and make sure that all
-- declared computations have different names.
-- Later the name will be removed.
--
-- Pay attention, that lambda argument will be evaluated
-- to variable before lambda calling.
--
-- TODO Approach with lambda names has critical pitfall:
-- in case if a function takes @Label name@, lambda body
-- won't be regenerated for every different label.
-- So be carefully, this will be fixed in a following issue.
defNamedEffLambda1
  :: forall st argExpr res .
  ( ToExpr argExpr
  , Typeable res
  , ExecuteLambdaEff1C st (ExprType argExpr) res
  , CreateLambdaEff1C st (ExprType argExpr) res
  , HasCallStack
  )
  => String
  -> (Var (ExprType argExpr) -> IndigoM res)
  -> (argExpr -> IndigoM (RetVars res))
defNamedEffLambda1 :: [Char]
-> (Var (ExprType argExpr) -> IndigoM res)
-> argExpr
-> IndigoM (RetVars res)
defNamedEffLambda1 lName :: [Char]
lName body :: Var (ExprType argExpr) -> IndigoM res
body = \ex :: argExpr
ex ->
  IndigoM (RetVars res) -> IndigoM (RetVars res)
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM (RetVars res) -> IndigoM (RetVars res))
-> IndigoM (RetVars res) -> IndigoM (RetVars res)
forall a b. (a -> b) -> a -> b
$ StatementF IndigoM (RetVars res) -> IndigoM (RetVars res)
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF IndigoM (RetVars res) -> IndigoM (RetVars res))
-> StatementF IndigoM (RetVars res) -> IndigoM (RetVars res)
forall a b. (a -> b) -> a -> b
$ LambdaKind st (ExprType argExpr) res '[st, Ops]
-> [Char]
-> (Var (ExprType argExpr) -> IndigoM res)
-> Expr (ExprType argExpr)
-> StatementF IndigoM (RetVars res)
forall st arg res (extra :: [*]) (freer :: * -> *).
LambdaKind st arg res extra
-> [Char]
-> (Var arg -> freer res)
-> Expr arg
-> StatementF freer (RetVars res)
LambdaCall1 (Proxy st -> LambdaKind st (ExprType argExpr) res '[st, Ops]
forall st arg res.
(ExecuteLambdaEff1C st arg res,
 CreateLambda1CGeneric '[st, Ops] arg res, Typeable res) =>
Proxy st -> LambdaKind st arg res '[st, Ops]
EffLambda (Proxy st
forall k (t :: k). Proxy t
Proxy @st)) [Char]
lName Var (ExprType argExpr) -> IndigoM res
body (argExpr -> Expr (ExprType argExpr)
forall a. ToExpr a => a -> Expr (ExprType a)
toExpr argExpr
ex)

-- | Like defNamedEffLambda1 but doesn't make side effects.
defNamedLambda1
  :: forall st argExpr res .
  ( ToExpr argExpr
  , Typeable res
  , ExecuteLambda1C st (ExprType argExpr) res
  , CreateLambda1C st (ExprType argExpr) res
  , HasCallStack
  )
  => String
  -> (Var (ExprType argExpr) -> IndigoM res)
  -> (argExpr -> IndigoM (RetVars res))
defNamedLambda1 :: [Char]
-> (Var (ExprType argExpr) -> IndigoM res)
-> argExpr
-> IndigoM (RetVars res)
defNamedLambda1 lName :: [Char]
lName body :: Var (ExprType argExpr) -> IndigoM res
body = \ex :: argExpr
ex ->
  IndigoM (RetVars res) -> IndigoM (RetVars res)
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM (RetVars res) -> IndigoM (RetVars res))
-> IndigoM (RetVars res) -> IndigoM (RetVars res)
forall a b. (a -> b) -> a -> b
$ StatementF IndigoM (RetVars res) -> IndigoM (RetVars res)
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF IndigoM (RetVars res) -> IndigoM (RetVars res))
-> StatementF IndigoM (RetVars res) -> IndigoM (RetVars res)
forall a b. (a -> b) -> a -> b
$ LambdaKind st (ExprType argExpr) res '[st]
-> [Char]
-> (Var (ExprType argExpr) -> IndigoM res)
-> Expr (ExprType argExpr)
-> StatementF IndigoM (RetVars res)
forall st arg res (extra :: [*]) (freer :: * -> *).
LambdaKind st arg res extra
-> [Char]
-> (Var arg -> freer res)
-> Expr arg
-> StatementF freer (RetVars res)
LambdaCall1 (Proxy st -> LambdaKind st (ExprType argExpr) res '[st]
forall st arg res.
(ExecuteLambda1C st arg res, CreateLambda1CGeneric '[st] arg res,
 Typeable res) =>
Proxy st -> LambdaKind st arg res '[st]
StorageLambda (Proxy st
forall k (t :: k). Proxy t
Proxy @st)) [Char]
lName Var (ExprType argExpr) -> IndigoM res
body (argExpr -> Expr (ExprType argExpr)
forall a. ToExpr a => a -> Expr (ExprType a)
toExpr argExpr
ex)

-- | Like defNamedLambda1 but doesn't take an argument.
defNamedLambda0
  :: forall st res .
  ( Typeable res
  , ExecuteLambda1C st () res
  , CreateLambda1C st () res
  , HasCallStack
  )
  => String
  -> IndigoM res
  -> IndigoM (RetVars res)
defNamedLambda0 :: [Char] -> IndigoM res -> IndigoM (RetVars res)
defNamedLambda0 lName :: [Char]
lName body :: IndigoM res
body =
  IndigoM (RetVars res) -> IndigoM (RetVars res)
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM (RetVars res) -> IndigoM (RetVars res))
-> IndigoM (RetVars res) -> IndigoM (RetVars res)
forall a b. (a -> b) -> a -> b
$ StatementF IndigoM (RetVars res) -> IndigoM (RetVars res)
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF IndigoM (RetVars res) -> IndigoM (RetVars res))
-> StatementF IndigoM (RetVars res) -> IndigoM (RetVars res)
forall a b. (a -> b) -> a -> b
$ LambdaKind st () res '[st]
-> [Char]
-> (Var () -> IndigoM res)
-> Expr ()
-> StatementF IndigoM (RetVars res)
forall st arg res (extra :: [*]) (freer :: * -> *).
LambdaKind st arg res extra
-> [Char]
-> (Var arg -> freer res)
-> Expr arg
-> StatementF freer (RetVars res)
LambdaCall1 (Proxy st -> LambdaKind st () res '[st]
forall st arg res.
(ExecuteLambda1C st arg res, CreateLambda1CGeneric '[st] arg res,
 Typeable res) =>
Proxy st -> LambdaKind st arg res '[st]
StorageLambda (Proxy st
forall k (t :: k). Proxy t
Proxy @st)) [Char]
lName (\(Var ()
_ :: Var ()) -> IndigoM res
body) (() -> Expr ()
forall a. NiceConstant a => a -> Expr a
C ())

-- | Like defNamedEffLambda1 but doesn't modify storage and doesn't make side effects.
defNamedPureLambda1
  :: forall argExpr res .
  ( ToExpr argExpr
  , Typeable res
  , ExecuteLambdaPure1C (ExprType argExpr) res
  , CreateLambdaPure1C (ExprType argExpr) res
  , HasCallStack
  )
  => String
  -> (Var (ExprType argExpr) -> IndigoM res)
  -> (argExpr -> IndigoM (RetVars res))
defNamedPureLambda1 :: [Char]
-> (Var (ExprType argExpr) -> IndigoM res)
-> argExpr
-> IndigoM (RetVars res)
defNamedPureLambda1 lName :: [Char]
lName body :: Var (ExprType argExpr) -> IndigoM res
body = \ex :: argExpr
ex ->
  IndigoM (RetVars res) -> IndigoM (RetVars res)
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM (RetVars res) -> IndigoM (RetVars res))
-> IndigoM (RetVars res) -> IndigoM (RetVars res)
forall a b. (a -> b) -> a -> b
$ StatementF IndigoM (RetVars res) -> IndigoM (RetVars res)
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF IndigoM (RetVars res) -> IndigoM (RetVars res))
-> StatementF IndigoM (RetVars res) -> IndigoM (RetVars res)
forall a b. (a -> b) -> a -> b
$ LambdaKind Any (ExprType argExpr) res '[]
-> [Char]
-> (Var (ExprType argExpr) -> IndigoM res)
-> Expr (ExprType argExpr)
-> StatementF IndigoM (RetVars res)
forall st arg res (extra :: [*]) (freer :: * -> *).
LambdaKind st arg res extra
-> [Char]
-> (Var arg -> freer res)
-> Expr arg
-> StatementF freer (RetVars res)
LambdaCall1 LambdaKind Any (ExprType argExpr) res '[]
forall arg res st.
(ExecuteLambdaPure1C arg res, CreateLambda1CGeneric '[] arg res,
 Typeable res) =>
LambdaKind st arg res '[]
PureLambda [Char]
lName Var (ExprType argExpr) -> IndigoM res
body (argExpr -> Expr (ExprType argExpr)
forall a. ToExpr a => a -> Expr (ExprType a)
toExpr argExpr
ex)

----------------------------------------------------------------------------
-- Loop
----------------------------------------------------------------------------

-- | While statement.
while :: forall ex . (ex :~> Bool, HasCallStack) => ex -> IndigoM () -> IndigoM ()
while :: ex -> IndigoM () -> IndigoM ()
while e :: ex
e body :: IndigoM ()
body = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ()) -> IndigoM () -> IndigoM ()
forall a b. (a -> b) -> a -> b
$ StatementF IndigoM () -> IndigoM ()
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF IndigoM () -> IndigoM ())
-> StatementF IndigoM () -> IndigoM ()
forall a b. (a -> b) -> a -> b
$ Expr Bool -> IndigoM () -> StatementF IndigoM ()
forall (freer :: * -> *).
Expr Bool -> freer () -> StatementF freer ()
While (ex -> Expr (ExprType ex)
forall a. ToExpr a => a -> Expr (ExprType a)
toExpr ex
e) IndigoM ()
body

whileLeft
  :: forall x y ex .
     ( ex :~> Either y x
     , KnownValue y
     , KnownValue x
     , HasCallStack
     )
  => ex
  -> (Var y -> IndigoM ())
  -> IndigoM (Var x)
whileLeft :: ex -> (Var y -> IndigoM ()) -> IndigoM (Var x)
whileLeft e :: ex
e body :: Var y -> IndigoM ()
body = IndigoM (Var x) -> IndigoM (Var x)
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM (Var x) -> IndigoM (Var x))
-> IndigoM (Var x) -> IndigoM (Var x)
forall a b. (a -> b) -> a -> b
$ StatementF IndigoM (Var x) -> IndigoM (Var x)
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF IndigoM (Var x) -> IndigoM (Var x))
-> StatementF IndigoM (Var x) -> IndigoM (Var x)
forall a b. (a -> b) -> a -> b
$ Expr (Either y x)
-> (Var y -> IndigoM ()) -> StatementF IndigoM (Var x)
forall x y (freer :: * -> *).
(KnownValue x, KnownValue y) =>
Expr (Either y x)
-> (Var y -> freer ()) -> StatementF freer (Var x)
WhileLeft (ex -> Expr (ExprType ex)
forall a. ToExpr a => a -> Expr (ExprType a)
toExpr ex
e) Var y -> IndigoM ()
body

-- | For statements to iterate over a container.
forEach
  :: forall a e . (IterOpHs a, KnownValue (IterOpElHs a), e :~> a, HasCallStack)
  => e -> (Var (IterOpElHs a) -> IndigoM ())
  -> IndigoM ()
forEach :: e -> (Var (IterOpElHs a) -> IndigoM ()) -> IndigoM ()
forEach container :: e
container body :: Var (IterOpElHs a) -> IndigoM ()
body = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ()) -> IndigoM () -> IndigoM ()
forall a b. (a -> b) -> a -> b
$ StatementF IndigoM () -> IndigoM ()
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF IndigoM () -> IndigoM ())
-> StatementF IndigoM () -> IndigoM ()
forall a b. (a -> b) -> a -> b
$ Expr a
-> (Var (IterOpElHs a) -> IndigoM ()) -> StatementF IndigoM ()
forall a (freer :: * -> *).
(IterOpHs a, KnownValue (IterOpElHs a)) =>
Expr a -> (Var (IterOpElHs a) -> freer ()) -> StatementF freer ()
ForEach (e -> Expr (ExprType e)
forall a. ToExpr a => a -> Expr (ExprType a)
toExpr e
container) Var (IterOpElHs a) -> IndigoM ()
body

----------------------------------------------------------------------------
-- Documentation
----------------------------------------------------------------------------

-- | Put a document item.
doc :: (DocItem di, HasCallStack) => di -> IndigoM ()
doc :: di -> IndigoM ()
doc di :: di
di = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ()) -> IndigoM () -> IndigoM ()
forall a b. (a -> b) -> a -> b
$ (forall (inp :: [*]). SomeIndigoState inp) -> IndigoM ()
liftIndigoState ((forall (inp :: [*]). SomeIndigoState inp) -> IndigoM ())
-> (forall (inp :: [*]). SomeIndigoState inp) -> IndigoM ()
forall a b. (a -> b) -> a -> b
$ 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
$ di -> IndigoState inp inp
forall di (s :: [*]). DocItem di => di -> IndigoState s s
B.doc di
di

-- | Group documentation built in the given piece of code
-- into a block dedicated to one thing, e.g. to one entrypoint.
docGroup :: HasCallStack => DocGrouping -> IndigoM () -> IndigoM ()
docGroup :: DocGrouping -> IndigoM () -> IndigoM ()
docGroup = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ())
-> (StatementF IndigoM () -> IndigoM ())
-> StatementF IndigoM ()
-> IndigoM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StatementF IndigoM () -> IndigoM ()
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF IndigoM () -> IndigoM ())
-> (DocGrouping -> IndigoM () -> StatementF IndigoM ())
-> DocGrouping
-> IndigoM ()
-> IndigoM ()
forall a b c. SuperComposition a b c => a -> b -> c
... DocGrouping -> IndigoM () -> StatementF IndigoM ()
forall (freer :: * -> *).
DocGrouping -> freer () -> StatementF freer ()
DocGroup

-- | Insert documentation of the contract's storage type. The type
-- should be passed using type applications.
docStorage :: forall storage. (TypeHasDoc storage, HasCallStack) => IndigoM ()
docStorage :: IndigoM ()
docStorage = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ()) -> IndigoM () -> IndigoM ()
forall a b. (a -> b) -> a -> b
$ (forall (inp :: [*]). SomeIndigoState inp) -> IndigoM ()
liftIndigoState ((forall (inp :: [*]). SomeIndigoState inp) -> IndigoM ())
-> (forall (inp :: [*]). SomeIndigoState inp) -> IndigoM ()
forall a b. (a -> b) -> a -> b
$ 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
$ forall (s :: [*]). TypeHasDoc storage => IndigoState s s
forall storage (s :: [*]). TypeHasDoc storage => IndigoState s s
B.docStorage @storage

-- | Give a name to the given contract. Apply it to the whole contract code.
contractName :: HasCallStack => Text -> IndigoM () -> IndigoM ()
contractName :: Text -> IndigoM () -> IndigoM ()
contractName = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ())
-> (StatementF IndigoM () -> IndigoM ())
-> StatementF IndigoM ()
-> IndigoM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StatementF IndigoM () -> IndigoM ()
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF IndigoM () -> IndigoM ())
-> (Text -> IndigoM () -> StatementF IndigoM ())
-> Text
-> IndigoM ()
-> IndigoM ()
forall a b c. SuperComposition a b c => a -> b -> c
... Text -> IndigoM () -> StatementF IndigoM ()
forall (freer :: * -> *). Text -> freer () -> StatementF freer ()
ContractName

-- | Attach general info to the given contract.
contractGeneral :: HasCallStack => IndigoM () -> IndigoM ()
contractGeneral :: IndigoM () -> IndigoM ()
contractGeneral = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ())
-> (IndigoM () -> IndigoM ()) -> IndigoM () -> IndigoM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StatementF IndigoM () -> IndigoM ()
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF IndigoM () -> IndigoM ())
-> (IndigoM () -> StatementF IndigoM ())
-> IndigoM ()
-> IndigoM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IndigoM () -> StatementF IndigoM ()
forall (freer :: * -> *). freer () -> StatementF freer ()
ContractGeneral

-- | Attach default general info to the contract documentation.
contractGeneralDefault :: HasCallStack => IndigoM ()
contractGeneralDefault :: IndigoM ()
contractGeneralDefault = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ()) -> IndigoM () -> IndigoM ()
forall a b. (a -> b) -> a -> b
$ (forall (inp :: [*]). SomeIndigoState inp) -> IndigoM ()
liftIndigoState ((forall (inp :: [*]). SomeIndigoState inp) -> IndigoM ())
-> (forall (inp :: [*]). SomeIndigoState inp) -> IndigoM ()
forall a b. (a -> b) -> a -> b
$ 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
$ IndigoState inp inp
forall (s :: [*]). IndigoState s s
B.contractGeneralDefault

-- | Indigo version for the homonym Lorentz function.
finalizeParamCallingDoc
  :: forall param.
     ( ToExpr param
     , NiceParameterFull (ExprType param)
     , RequireSumType (ExprType param)
     , HasCallStack
     )
  => (Var (ExprType param) -> IndigoM ()) -> param -> IndigoM ()
finalizeParamCallingDoc :: (Var (ExprType param) -> IndigoM ()) -> param -> IndigoM ()
finalizeParamCallingDoc i :: Var (ExprType param) -> IndigoM ()
i = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ())
-> (param -> IndigoM ()) -> param -> IndigoM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StatementF IndigoM () -> IndigoM ()
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF IndigoM () -> IndigoM ())
-> (param -> StatementF IndigoM ()) -> param -> IndigoM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Var (ExprType param) -> IndigoM ())
-> Expr (ExprType param) -> StatementF IndigoM ()
forall cp (freer :: * -> *).
(NiceParameterFull cp, RequireSumType cp, HasCallStack) =>
(Var cp -> freer ()) -> Expr cp -> StatementF freer ()
FinalizeParamCallingDoc Var (ExprType param) -> IndigoM ()
i (Expr (ExprType param) -> StatementF IndigoM ())
-> (param -> Expr (ExprType param))
-> param
-> StatementF IndigoM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. param -> Expr (ExprType param)
forall a. ToExpr a => a -> Expr (ExprType a)
toExpr

-- | Put a 'DDescription' doc item.
description :: HasCallStack => Markdown -> IndigoM ()
description :: Markdown -> IndigoM ()
description = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ())
-> (Markdown -> IndigoM ()) -> Markdown -> IndigoM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DDescription -> IndigoM ()
forall di. (DocItem di, HasCallStack) => di -> IndigoM ()
doc (DDescription -> IndigoM ())
-> (Markdown -> DDescription) -> Markdown -> IndigoM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Markdown -> DDescription
DDescription

-- | Put a 'DAnchor' doc item.
anchor :: HasCallStack => Text -> IndigoM ()
anchor :: Text -> IndigoM ()
anchor = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ())
-> (Text -> IndigoM ()) -> Text -> IndigoM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DAnchor -> IndigoM ()
forall di. (DocItem di, HasCallStack) => di -> IndigoM ()
doc (DAnchor -> IndigoM ()) -> (Text -> DAnchor) -> Text -> IndigoM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Anchor -> DAnchor
DAnchor (Anchor -> DAnchor) -> (Text -> Anchor) -> Text -> DAnchor
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Anchor
forall anchor. ToAnchor anchor => anchor -> Anchor
toAnchor

-- | Put a 'DEntrypointExample' doc item.
example :: forall a. (NiceParameter a, HasCallStack) => a -> IndigoM ()
example :: a -> IndigoM ()
example = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ()) -> (a -> IndigoM ()) -> a -> IndigoM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DEntrypointExample -> IndigoM ()
forall di. (DocItem di, HasCallStack) => di -> IndigoM ()
doc (DEntrypointExample -> IndigoM ())
-> (a -> DEntrypointExample) -> a -> IndigoM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> DEntrypointExample
forall a. NiceParameter a => a -> DEntrypointExample
mkDEntrypointExample

----------------------------------------------------------------------------
-- Contract call
----------------------------------------------------------------------------

selfCalling
  :: forall p mname.
     ( NiceParameterFull p
     , KnownValue (GetEntrypointArgCustom p mname)
     , HasCallStack
     )
  => EntrypointRef mname
  -> IndigoM (Var (ContractRef (GetEntrypointArgCustom p mname)))
selfCalling :: EntrypointRef mname
-> IndigoM (Var (ContractRef (GetEntrypointArgCustom p mname)))
selfCalling = IndigoM (Var (ContractRef (GetEntrypointArgCustom p mname)))
-> IndigoM (Var (ContractRef (GetEntrypointArgCustom p mname)))
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM (Var (ContractRef (GetEntrypointArgCustom p mname)))
 -> IndigoM (Var (ContractRef (GetEntrypointArgCustom p mname))))
-> (StatementF
      IndigoM (Var (ContractRef (GetEntrypointArgCustom p mname)))
    -> IndigoM (Var (ContractRef (GetEntrypointArgCustom p mname))))
-> StatementF
     IndigoM (Var (ContractRef (GetEntrypointArgCustom p mname)))
-> IndigoM (Var (ContractRef (GetEntrypointArgCustom p mname)))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StatementF
  IndigoM (Var (ContractRef (GetEntrypointArgCustom p mname)))
-> IndigoM (Var (ContractRef (GetEntrypointArgCustom p mname)))
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF
   IndigoM (Var (ContractRef (GetEntrypointArgCustom p mname)))
 -> IndigoM (Var (ContractRef (GetEntrypointArgCustom p mname))))
-> (EntrypointRef mname
    -> StatementF
         IndigoM (Var (ContractRef (GetEntrypointArgCustom p mname))))
-> EntrypointRef mname
-> IndigoM (Var (ContractRef (GetEntrypointArgCustom p mname)))
forall a b c. SuperComposition a b c => a -> b -> c
... Proxy p
-> EntrypointRef mname
-> StatementF
     IndigoM (Var (ContractRef (GetEntrypointArgCustom p mname)))
forall p (mname :: Maybe Symbol) (freer :: * -> *).
(NiceParameterFull p,
 KnownValue (GetEntrypointArgCustom p mname)) =>
Proxy p
-> EntrypointRef mname
-> StatementF
     freer (Var (ContractRef (GetEntrypointArgCustom p mname)))
SelfCalling (Proxy p
forall k (t :: k). Proxy t
Proxy @p)

contractCalling
  :: forall cp epRef epArg addr exAddr.
     ( HasEntrypointArg cp epRef epArg
     , ToTAddress cp addr
     , ToT addr ~ ToT Address
     , exAddr :~> addr
     , KnownValue epArg
     , HasCallStack
     )
  => epRef -> exAddr -> IndigoM (Var (Maybe (ContractRef epArg)))
contractCalling :: epRef -> exAddr -> IndigoM (Var (Maybe (ContractRef epArg)))
contractCalling epRef :: epRef
epRef = IndigoM (Var (Maybe (ContractRef epArg)))
-> IndigoM (Var (Maybe (ContractRef epArg)))
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM (Var (Maybe (ContractRef epArg)))
 -> IndigoM (Var (Maybe (ContractRef epArg))))
-> (exAddr -> IndigoM (Var (Maybe (ContractRef epArg))))
-> exAddr
-> IndigoM (Var (Maybe (ContractRef epArg)))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StatementF IndigoM (Var (Maybe (ContractRef epArg)))
-> IndigoM (Var (Maybe (ContractRef epArg)))
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF IndigoM (Var (Maybe (ContractRef epArg)))
 -> IndigoM (Var (Maybe (ContractRef epArg))))
-> (exAddr -> StatementF IndigoM (Var (Maybe (ContractRef epArg))))
-> exAddr
-> IndigoM (Var (Maybe (ContractRef epArg)))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy cp
-> epRef
-> Expr addr
-> StatementF IndigoM (Var (Maybe (ContractRef epArg)))
forall cp epRef epArg addr (freer :: * -> *).
(HasEntrypointArg cp epRef epArg, ToTAddress cp addr,
 ToT addr ~ ToT Address, KnownValue epArg) =>
Proxy cp
-> epRef
-> Expr addr
-> StatementF freer (Var (Maybe (ContractRef epArg)))
ContractCalling (Proxy cp
forall k (t :: k). Proxy t
Proxy @cp) epRef
epRef (Expr addr -> StatementF IndigoM (Var (Maybe (ContractRef epArg))))
-> (exAddr -> Expr addr)
-> exAddr
-> StatementF IndigoM (Var (Maybe (ContractRef epArg)))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. exAddr -> Expr addr
forall a. ToExpr a => a -> Expr (ExprType a)
toExpr

----------------------------------------------------------------------------
-- Side-effects operations
----------------------------------------------------------------------------

transferTokens
  :: ( IsExpr exp p
     , IsExpr exm Mutez
     , IsExpr exc (ContractRef p)
     , NiceParameter p
     , HasSideEffects
     , HasCallStack
     )
  => exp -> exm -> exc -> IndigoM ()
transferTokens :: exp -> exm -> exc -> IndigoM ()
transferTokens ep :: exp
ep em :: exm
em ec :: exc
ec = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ()) -> IndigoM () -> IndigoM ()
forall a b. (a -> b) -> a -> b
$ StatementF IndigoM () -> IndigoM ()
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF IndigoM () -> IndigoM ())
-> StatementF IndigoM () -> IndigoM ()
forall a b. (a -> b) -> a -> b
$
  Expr p
-> Expr Mutez -> Expr (ContractRef p) -> StatementF IndigoM ()
forall p (freer :: * -> *).
(NiceParameter p, HasSideEffects) =>
Expr p -> Expr Mutez -> Expr (ContractRef p) -> StatementF freer ()
TransferTokens (exp -> Expr (ExprType exp)
forall a. ToExpr a => a -> Expr (ExprType a)
toExpr exp
ep) (exm -> Expr (ExprType exm)
forall a. ToExpr a => a -> Expr (ExprType a)
toExpr exm
em) (exc -> Expr (ExprType exc)
forall a. ToExpr a => a -> Expr (ExprType a)
toExpr exc
ec)

setDelegate :: (HasSideEffects, IsExpr ex (Maybe KeyHash), HasCallStack) => ex -> IndigoM ()
setDelegate :: ex -> IndigoM ()
setDelegate = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ())
-> (ex -> IndigoM ()) -> ex -> IndigoM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StatementF IndigoM () -> IndigoM ()
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF IndigoM () -> IndigoM ())
-> (ex -> StatementF IndigoM ()) -> ex -> IndigoM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr (Maybe KeyHash) -> StatementF IndigoM ()
forall (freer :: * -> *).
HasSideEffects =>
Expr (Maybe KeyHash) -> StatementF freer ()
SetDelegate (Expr (Maybe KeyHash) -> StatementF IndigoM ())
-> (ex -> Expr (Maybe KeyHash)) -> ex -> StatementF IndigoM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ex -> Expr (Maybe KeyHash)
forall a. ToExpr a => a -> Expr (ExprType a)
toExpr

-- | Create contract using default compilation options for Lorentz compiler.
--
-- See "Lorentz.Run".
createContract
  :: ( IsObject st
     , IsExpr exk (Maybe KeyHash), IsExpr exm Mutez, IsExpr exs st
     , NiceStorage st, NiceParameterFull param
     , HasSideEffects
     , HasCallStack
     )
  => (HasStorage st => Var param -> IndigoM ())
  -> exk
  -> exm
  -> exs
  -> IndigoM (Var Address)
createContract :: (HasStorage st => Var param -> IndigoM ())
-> exk -> exm -> exs -> IndigoM (Var Address)
createContract iCtr :: HasStorage st => Var param -> IndigoM ()
iCtr ek :: exk
ek em :: exm
em es :: exs
es = IndigoM (Var Address) -> IndigoM (Var Address)
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM (Var Address) -> IndigoM (Var Address))
-> IndigoM (Var Address) -> IndigoM (Var Address)
forall a b. (a -> b) -> a -> b
$ StatementF IndigoM (Var Address) -> IndigoM (Var Address)
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF IndigoM (Var Address) -> IndigoM (Var Address))
-> StatementF IndigoM (Var Address) -> IndigoM (Var Address)
forall a b. (a -> b) -> a -> b
$
  -- pva701: we don't have GenCodeHooks at this point so we just pass empty ones
  -- Maybe we should pass this hooks via 'given'
  Contract param st
-> Expr (Maybe KeyHash)
-> Expr Mutez
-> Expr st
-> StatementF IndigoM (Var Address)
forall st param (freer :: * -> *).
(IsObject st, NiceStorage st, NiceParameterFull param,
 HasSideEffects) =>
Contract param st
-> Expr (Maybe KeyHash)
-> Expr Mutez
-> Expr st
-> StatementF freer (Var Address)
CreateContract (ContractCode param st -> Contract param st
forall cp st. ContractCode cp st -> Contract cp st
defaultContract (ContractCode param st -> Contract param st)
-> ContractCode param st -> Contract param st
forall a b. (a -> b) -> a -> b
$ IndigoContract param st -> ContractCode param st
forall param st.
(KnownValue param, IsObject st) =>
IndigoContract param st -> ContractCode param st
compileIndigoContract IndigoContract param st
HasStorage st => Var param -> IndigoM ()
iCtr) (exk -> Expr (ExprType exk)
forall a. ToExpr a => a -> Expr (ExprType a)
toExpr exk
ek) (exm -> Expr (ExprType exm)
forall a. ToExpr a => a -> Expr (ExprType a)
toExpr exm
em) (exs -> Expr (ExprType exs)
forall a. ToExpr a => a -> Expr (ExprType a)
toExpr exs
es)

-- | Create contract from raw Lorentz 'L.Contract'.
createLorentzContract
  :: ( IsObject st
     , IsExpr exk (Maybe KeyHash), IsExpr exm Mutez, IsExpr exs st
     , NiceStorage st, NiceParameterFull param
     , HasSideEffects
     , HasCallStack
     )
  => L.Contract param st
  -> exk
  -> exm
  -> exs
  -> IndigoM (Var Address)
createLorentzContract :: Contract param st -> exk -> exm -> exs -> IndigoM (Var Address)
createLorentzContract lCtr :: Contract param st
lCtr ek :: exk
ek em :: exm
em es :: exs
es = IndigoM (Var Address) -> IndigoM (Var Address)
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM (Var Address) -> IndigoM (Var Address))
-> IndigoM (Var Address) -> IndigoM (Var Address)
forall a b. (a -> b) -> a -> b
$ StatementF IndigoM (Var Address) -> IndigoM (Var Address)
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF IndigoM (Var Address) -> IndigoM (Var Address))
-> StatementF IndigoM (Var Address) -> IndigoM (Var Address)
forall a b. (a -> b) -> a -> b
$
  Contract param st
-> Expr (Maybe KeyHash)
-> Expr Mutez
-> Expr st
-> StatementF IndigoM (Var Address)
forall st param (freer :: * -> *).
(IsObject st, NiceStorage st, NiceParameterFull param,
 HasSideEffects) =>
Contract param st
-> Expr (Maybe KeyHash)
-> Expr Mutez
-> Expr st
-> StatementF freer (Var Address)
CreateContract Contract param st
lCtr (exk -> Expr (ExprType exk)
forall a. ToExpr a => a -> Expr (ExprType a)
toExpr exk
ek) (exm -> Expr (ExprType exm)
forall a. ToExpr a => a -> Expr (ExprType a)
toExpr exm
em) (exs -> Expr (ExprType exs)
forall a. ToExpr a => a -> Expr (ExprType a)
toExpr exs
es)

----------------------------------------------------------------------------
-- Error
----------------------------------------------------------------------------

failWith
  :: forall ret a ex . (IsExpr ex a, ReturnableValue ret, HasCallStack)
  => ex -> IndigoM (RetVars ret)
failWith :: ex -> IndigoM (RetVars ret)
failWith = IndigoM (RetVars ret) -> IndigoM (RetVars ret)
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM (RetVars ret) -> IndigoM (RetVars ret))
-> (ex -> IndigoM (RetVars ret)) -> ex -> IndigoM (RetVars ret)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StatementF IndigoM (RetVars ret) -> IndigoM (RetVars ret)
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF IndigoM (RetVars ret) -> IndigoM (RetVars ret))
-> (ex -> StatementF IndigoM (RetVars ret))
-> ex
-> IndigoM (RetVars ret)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy ret
-> (forall (inp :: [*]). Expr a -> SomeIndigoState inp)
-> Expr a
-> StatementF IndigoM (RetVars ret)
forall ret a (freer :: * -> *).
ReturnableValue ret =>
Proxy ret
-> (forall (inp :: [*]). Expr a -> SomeIndigoState inp)
-> Expr a
-> StatementF freer (RetVars ret)
FailOver (Proxy ret
forall k (t :: k). Proxy t
Proxy @ret) (IndigoState inp Any -> SomeIndigoState inp
forall (inp :: [*]) (out :: [*]).
IndigoState inp out -> SomeIndigoState inp
toSIS (IndigoState inp Any -> SomeIndigoState inp)
-> (Expr a -> IndigoState inp Any) -> Expr a -> SomeIndigoState inp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr a -> IndigoState inp Any
forall a (s :: [*]) (t :: [*]).
KnownValue a =>
Expr a -> IndigoState s t
B.failWith) (Expr a -> StatementF IndigoM (RetVars ret))
-> (ex -> Expr a) -> ex -> StatementF IndigoM (RetVars ret)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ex -> Expr a
forall a. ToExpr a => a -> Expr (ExprType a)
toExpr

failUsing_
  :: forall ret x. (IsError x, Buildable x, ReturnableValue ret, HasCallStack)
  => x -> IndigoM (RetVars ret)
failUsing_ :: x -> IndigoM (RetVars ret)
failUsing_ x :: x
x = IndigoM (RetVars ret) -> IndigoM (RetVars ret)
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM (RetVars ret) -> IndigoM (RetVars ret))
-> IndigoM (RetVars ret) -> IndigoM (RetVars ret)
forall a b. (a -> b) -> a -> b
$ StatementF IndigoM (RetVars ret) -> IndigoM (RetVars ret)
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF IndigoM (RetVars ret) -> IndigoM (RetVars ret))
-> StatementF IndigoM (RetVars ret) -> IndigoM (RetVars ret)
forall a b. (a -> b) -> a -> b
$ Proxy ret
-> (forall (inp :: [*]). SomeIndigoState inp)
-> StatementF IndigoM (RetVars ret)
forall ret (freer :: * -> *).
ReturnableValue ret =>
Proxy ret
-> (forall (inp :: [*]). SomeIndigoState inp)
-> StatementF freer (RetVars ret)
Fail (Proxy ret
forall k (t :: k). Proxy t
Proxy @ret) (IndigoState inp Any -> SomeIndigoState inp
forall (inp :: [*]) (out :: [*]).
IndigoState inp out -> SomeIndigoState inp
toSIS (IndigoState inp Any -> SomeIndigoState inp)
-> IndigoState inp Any -> SomeIndigoState inp
forall a b. (a -> b) -> a -> b
$ x -> IndigoState inp Any
forall x (s :: [*]) (t :: [*]).
(IsError x, Buildable x) =>
x -> IndigoState s t
B.failUsing_ x
x)

failCustom
  :: forall ret tag err ex.
     ( ReturnableValue ret
     , err ~ ErrorArg tag
     , CustomErrorHasDoc tag
     , NiceConstant err
     , ex :~> err
     , HasCallStack
     )
  => Label tag -> ex -> IndigoM (RetVars ret)
failCustom :: Label tag -> ex -> IndigoM (RetVars ret)
failCustom l :: Label tag
l = IndigoM (RetVars ret) -> IndigoM (RetVars ret)
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM (RetVars ret) -> IndigoM (RetVars ret))
-> (ex -> IndigoM (RetVars ret)) -> ex -> IndigoM (RetVars ret)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StatementF IndigoM (RetVars ret) -> IndigoM (RetVars ret)
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF IndigoM (RetVars ret) -> IndigoM (RetVars ret))
-> (ex -> StatementF IndigoM (RetVars ret))
-> ex
-> IndigoM (RetVars ret)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy ret
-> (forall (inp :: [*]). Expr err -> SomeIndigoState inp)
-> Expr err
-> StatementF IndigoM (RetVars ret)
forall ret a (freer :: * -> *).
ReturnableValue ret =>
Proxy ret
-> (forall (inp :: [*]). Expr a -> SomeIndigoState inp)
-> Expr a
-> StatementF freer (RetVars ret)
FailOver (Proxy ret
forall k (t :: k). Proxy t
Proxy @ret) (IndigoState inp Any -> SomeIndigoState inp
forall (inp :: [*]) (out :: [*]).
IndigoState inp out -> SomeIndigoState inp
toSIS (IndigoState inp Any -> SomeIndigoState inp)
-> (Expr err -> IndigoState inp Any)
-> Expr err
-> SomeIndigoState inp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Label tag -> Expr err -> IndigoState inp Any
forall (tag :: Symbol) err (s :: [*]) (t :: [*]).
(err ~ ErrorArg tag, CustomErrorHasDoc tag, NiceConstant err) =>
Label tag -> Expr err -> IndigoState s t
B.failCustom Label tag
l) (Expr err -> StatementF IndigoM (RetVars ret))
-> (ex -> Expr err) -> ex -> StatementF IndigoM (RetVars ret)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ex -> Expr err
forall a. ToExpr a => a -> Expr (ExprType a)
toExpr

failCustom_
  :: forall ret tag notVoidErrorMsg.
     ( ReturnableValue ret
     , RequireNoArgError tag notVoidErrorMsg
     , CustomErrorHasDoc tag
     , HasCallStack
     )
  => Label tag -> IndigoM (RetVars ret)
failCustom_ :: Label tag -> IndigoM (RetVars ret)
failCustom_ tag :: Label tag
tag = IndigoM (RetVars ret) -> IndigoM (RetVars ret)
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM (RetVars ret) -> IndigoM (RetVars ret))
-> IndigoM (RetVars ret) -> IndigoM (RetVars ret)
forall a b. (a -> b) -> a -> b
$ StatementF IndigoM (RetVars ret) -> IndigoM (RetVars ret)
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF IndigoM (RetVars ret) -> IndigoM (RetVars ret))
-> StatementF IndigoM (RetVars ret) -> IndigoM (RetVars ret)
forall a b. (a -> b) -> a -> b
$ Proxy ret
-> (forall (inp :: [*]). SomeIndigoState inp)
-> StatementF IndigoM (RetVars ret)
forall ret (freer :: * -> *).
ReturnableValue ret =>
Proxy ret
-> (forall (inp :: [*]). SomeIndigoState inp)
-> StatementF freer (RetVars ret)
Fail (Proxy ret
forall k (t :: k). Proxy t
Proxy @ret) (IndigoState inp Any -> SomeIndigoState inp
forall (inp :: [*]) (out :: [*]).
IndigoState inp out -> SomeIndigoState inp
toSIS (IndigoState inp Any -> SomeIndigoState inp)
-> IndigoState inp Any -> SomeIndigoState inp
forall a b. (a -> b) -> a -> b
$ Label tag -> IndigoState inp Any
forall (tag :: Symbol) (s :: [*]) (t :: [*])
       (notVoidErrorMsg :: ErrorMessage).
(RequireNoArgError tag notVoidErrorMsg, CustomErrorHasDoc tag) =>
Label tag -> IndigoState s t
B.failCustom_ Label tag
tag)

failUnexpected_
  :: forall ret. (ReturnableValue ret, HasCallStack)
  => MText -> IndigoM (RetVars ret)
failUnexpected_ :: MText -> IndigoM (RetVars ret)
failUnexpected_ tx :: MText
tx = IndigoM (RetVars ret) -> IndigoM (RetVars ret)
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM (RetVars ret) -> IndigoM (RetVars ret))
-> IndigoM (RetVars ret) -> IndigoM (RetVars ret)
forall a b. (a -> b) -> a -> b
$ StatementF IndigoM (RetVars ret) -> IndigoM (RetVars ret)
forall a. StatementF IndigoM a -> IndigoM a
oneIndigoM (StatementF IndigoM (RetVars ret) -> IndigoM (RetVars ret))
-> StatementF IndigoM (RetVars ret) -> IndigoM (RetVars ret)
forall a b. (a -> b) -> a -> b
$ Proxy ret
-> (forall (inp :: [*]). SomeIndigoState inp)
-> StatementF IndigoM (RetVars ret)
forall ret (freer :: * -> *).
ReturnableValue ret =>
Proxy ret
-> (forall (inp :: [*]). SomeIndigoState inp)
-> StatementF freer (RetVars ret)
Fail (Proxy ret
forall k (t :: k). Proxy t
Proxy @ret) (IndigoState inp Any -> SomeIndigoState inp
forall (inp :: [*]) (out :: [*]).
IndigoState inp out -> SomeIndigoState inp
toSIS (IndigoState inp Any -> SomeIndigoState inp)
-> IndigoState inp Any -> SomeIndigoState inp
forall a b. (a -> b) -> a -> b
$ MText -> IndigoState inp Any
forall (s :: [*]) (t :: [*]). MText -> IndigoState s t
B.failUnexpected_ MText
tx)

assert
  :: forall x ex.
     ( IsError x
     , Buildable x
     , IsExpr ex Bool
     , HasCallStack
     )
  => x -> ex -> IndigoM ()
assert :: x -> ex -> IndigoM ()
assert err :: x
err ex :: ex
ex = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ()) -> IndigoM () -> IndigoM ()
forall a b. (a -> b) -> a -> b
$ ex -> IndigoM () -> IndigoM () -> IndigoM (RetVars ())
forall a b ex.
(IfConstraint a b, ex :~> Bool, HasCallStack) =>
ex -> IndigoM a -> IndigoM b -> IndigoM (RetVars a)
if_ ex
ex (() -> IndigoM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()) (x -> IndigoM (RetVars ())
forall ret x.
(IsError x, Buildable x, ReturnableValue ret, HasCallStack) =>
x -> IndigoM (RetVars ret)
failUsing_ @() x
err)

assertCustom
  :: forall tag err errEx ex .
     ( err ~ ErrorArg tag
     , CustomErrorHasDoc tag
     , NiceConstant err
     , IsExpr errEx err
     , IsExpr ex Bool
     , HasCallStack
     )
  => Label tag -> errEx -> ex -> IndigoM ()
assertCustom :: Label tag -> errEx -> ex -> IndigoM ()
assertCustom tag :: Label tag
tag errEx :: errEx
errEx ex :: ex
ex = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ()) -> IndigoM () -> IndigoM ()
forall a b. (a -> b) -> a -> b
$ ex -> IndigoM () -> IndigoM () -> IndigoM (RetVars ())
forall a b ex.
(IfConstraint a b, ex :~> Bool, HasCallStack) =>
ex -> IndigoM a -> IndigoM b -> IndigoM (RetVars a)
if_ ex
ex (() -> IndigoM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()) (Label tag -> errEx -> IndigoM (RetVars ())
forall ret (tag :: Symbol) err ex.
(ReturnableValue ret, err ~ ErrorArg tag, CustomErrorHasDoc tag,
 NiceConstant err, ex :~> err, HasCallStack) =>
Label tag -> ex -> IndigoM (RetVars ret)
failCustom @() Label tag
tag errEx
errEx)

assertCustom_
  :: forall tag notVoidErrorMsg ex.
     ( RequireNoArgError tag notVoidErrorMsg
     , CustomErrorHasDoc tag
     , IsExpr ex Bool
     , HasCallStack
     )
  => Label tag -> ex -> IndigoM ()
assertCustom_ :: Label tag -> ex -> IndigoM ()
assertCustom_ tag :: Label tag
tag ex :: ex
ex = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ()) -> IndigoM () -> IndigoM ()
forall a b. (a -> b) -> a -> b
$ ex -> IndigoM () -> IndigoM () -> IndigoM (RetVars ())
forall a b ex.
(IfConstraint a b, ex :~> Bool, HasCallStack) =>
ex -> IndigoM a -> IndigoM b -> IndigoM (RetVars a)
if_ ex
ex (() -> IndigoM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()) (Label tag -> IndigoM (RetVars ())
forall ret (tag :: Symbol) (notVoidErrorMsg :: ErrorMessage).
(ReturnableValue ret, RequireNoArgError tag notVoidErrorMsg,
 CustomErrorHasDoc tag, HasCallStack) =>
Label tag -> IndigoM (RetVars ret)
failCustom_ @() Label tag
tag)

assertSome
  :: forall x err ex.
  ( IsError err
  , Buildable err
  , KnownValue x
  , ex :~> Maybe x
  , HasCallStack
  )
  => err -> ex -> IndigoM ()
assertSome :: err -> ex -> IndigoM ()
assertSome err :: err
err ex :: ex
ex = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ()) -> IndigoM () -> IndigoM ()
forall a b. (a -> b) -> a -> b
$ ex -> (Var x -> IndigoM ()) -> IndigoM () -> IndigoM (RetVars ())
forall x a b ex.
(KnownValue x, ex :~> Maybe x, IfConstraint a b, HasCallStack) =>
ex -> (Var x -> IndigoM a) -> IndigoM b -> IndigoM (RetVars a)
ifSome ex
ex (\_ -> err -> IndigoM (RetVars ())
forall ret x.
(IsError x, Buildable x, ReturnableValue ret, HasCallStack) =>
x -> IndigoM (RetVars ret)
failUsing_ @() err
err) (() -> IndigoM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ())

assertNone
  :: forall x err ex.
  ( IsError err
  , Buildable err
  , KnownValue x
  , ex :~> Maybe x
  , HasCallStack
  )
  => err -> ex -> IndigoM ()
assertNone :: err -> ex -> IndigoM ()
assertNone err :: err
err ex :: ex
ex = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ()) -> IndigoM () -> IndigoM ()
forall a b. (a -> b) -> a -> b
$ ex -> (Var x -> IndigoM ()) -> IndigoM () -> IndigoM (RetVars ())
forall x a b ex.
(KnownValue x, ex :~> Maybe x, IfConstraint a b, HasCallStack) =>
ex -> (Var x -> IndigoM a) -> IndigoM b -> IndigoM (RetVars a)
ifSome ex
ex (\_ -> () -> IndigoM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()) (err -> IndigoM (RetVars ())
forall ret x.
(IsError x, Buildable x, ReturnableValue ret, HasCallStack) =>
x -> IndigoM (RetVars ret)
failUsing_ @() err
err)

assertRight
  :: forall x y err ex.
  ( IsError err
  , Buildable err
  , KnownValue x
  , KnownValue y
  , ex :~> Either y x
  , HasCallStack
  )
  => err -> ex -> IndigoM ()
assertRight :: err -> ex -> IndigoM ()
assertRight err :: err
err ex :: ex
ex = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ()) -> IndigoM () -> IndigoM ()
forall a b. (a -> b) -> a -> b
$ ex
-> (Var x -> IndigoM ())
-> (Var y -> IndigoM ())
-> IndigoM (RetVars ())
forall x y a b ex.
(KnownValue x, KnownValue y, ex :~> Either y x, IfConstraint a b,
 HasCallStack) =>
ex
-> (Var x -> IndigoM a)
-> (Var y -> IndigoM b)
-> IndigoM (RetVars a)
ifRight ex
ex (\_ -> err -> IndigoM (RetVars ())
forall ret x.
(IsError x, Buildable x, ReturnableValue ret, HasCallStack) =>
x -> IndigoM (RetVars ret)
failUsing_ @() err
err) (\_ -> () -> IndigoM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ())

assertLeft
  :: forall x y err ex.
  ( IsError err
  , Buildable err
  , KnownValue x
  , KnownValue y
  , ex :~> Either y x
  , HasCallStack
  )
  => err -> ex -> IndigoM ()
assertLeft :: err -> ex -> IndigoM ()
assertLeft err :: err
err ex :: ex
ex = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ()) -> IndigoM () -> IndigoM ()
forall a b. (a -> b) -> a -> b
$ ex
-> (Var x -> IndigoM ())
-> (Var y -> IndigoM ())
-> IndigoM (RetVars ())
forall x y a b ex.
(KnownValue x, KnownValue y, ex :~> Either y x, IfConstraint a b,
 HasCallStack) =>
ex
-> (Var x -> IndigoM a)
-> (Var y -> IndigoM b)
-> IndigoM (RetVars a)
ifRight ex
ex (\_ -> () -> IndigoM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()) (\_ -> err -> IndigoM (RetVars ())
forall ret x.
(IsError x, Buildable x, ReturnableValue ret, HasCallStack) =>
x -> IndigoM (RetVars ret)
failUsing_ @() err
err)

----------------------------------------------------------------------------
-- Comments
----------------------------------------------------------------------------

-- | Add a comment in a generated Michelson code
justComment :: HasCallStack => Text -> IndigoM ()
justComment :: Text -> IndigoM ()
justComment = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ())
-> (Text -> IndigoM ()) -> Text -> IndigoM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HasCallStack => CommentType -> IndigoM ()
CommentType -> IndigoM ()
comment (CommentType -> IndigoM ())
-> (Text -> CommentType) -> Text -> IndigoM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> CommentType
MT.JustComment

-- | Add a comment in a generated Michelson code
comment :: HasCallStack => MT.CommentType -> IndigoM ()
comment :: CommentType -> IndigoM ()
comment t :: CommentType
t = IndigoM () -> IndigoM ()
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM () -> IndigoM ()) -> IndigoM () -> IndigoM ()
forall a b. (a -> b) -> a -> b
$ (forall (inp :: [*]). SomeIndigoState inp) -> IndigoM ()
liftIndigoState ((forall (inp :: [*]). SomeIndigoState inp) -> IndigoM ())
-> (forall (inp :: [*]). SomeIndigoState inp) -> IndigoM ()
forall a b. (a -> b) -> a -> b
$ IndigoState inp inp -> SomeIndigoState inp
forall (inp :: [*]) (out :: [*]).
IndigoState inp out -> SomeIndigoState inp
toSIS (CommentType -> IndigoState inp inp
forall (i :: [*]). CommentType -> IndigoState i i
B.comment CommentType
t)

-- | Add a comment before and after the given Indigo function code.
-- The first argument is the name of the function.
commentAroundFun :: HasCallStack => Text -> IndigoM a -> IndigoM a
commentAroundFun :: Text -> IndigoM a -> IndigoM a
commentAroundFun fName :: Text
fName body :: IndigoM a
body = IndigoM a -> IndigoM a
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM a -> IndigoM a) -> IndigoM a -> IndigoM a
forall a b. (a -> b) -> a -> b
$
  HasCallStack => CommentType -> IndigoM ()
CommentType -> IndigoM ()
comment (Text -> CommentType
MT.FunctionStarts Text
fName) IndigoM () -> IndigoM a -> IndigoM a
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
  IndigoM a
body IndigoM a -> (a -> IndigoM a) -> IndigoM a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
  \res :: a
res -> a
res a -> IndigoM () -> IndigoM a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ HasCallStack => CommentType -> IndigoM ()
CommentType -> IndigoM ()
comment (Text -> CommentType
MT.FunctionEnds Text
fName)

-- | Add a comment before and after the given Indigo statement code.
-- The first argument is the name of the statement.
commentAroundStmt :: HasCallStack => Text -> IndigoM a -> IndigoM a
commentAroundStmt :: Text -> IndigoM a -> IndigoM a
commentAroundStmt sName :: Text
sName body :: IndigoM a
body = IndigoM a -> IndigoM a
forall a. HasCallStack => IndigoM a -> IndigoM a
calledFrom (IndigoM a -> IndigoM a) -> IndigoM a -> IndigoM a
forall a b. (a -> b) -> a -> b
$
  HasCallStack => CommentType -> IndigoM ()
CommentType -> IndigoM ()
comment (Text -> CommentType
MT.StatementStarts Text
sName) IndigoM () -> IndigoM a -> IndigoM a
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
  IndigoM a
body IndigoM a -> (a -> IndigoM a) -> IndigoM a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
  \res :: a
res -> a
res a -> IndigoM () -> IndigoM a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ HasCallStack => CommentType -> IndigoM ()
CommentType -> IndigoM ()
comment (Text -> CommentType
MT.StatementEnds Text
sName)