indigo-0.3.0: src/Indigo/Compilation/Params.hs
-- SPDX-FileCopyrightText: 2020 Tocqueville Group
--
-- SPDX-License-Identifier: LicenseRef-MIT-TQ
module Indigo.Compilation.Params
( IndigoWithParams
, AreIndigoParams
, fromIndigoWithParams
, contractToIndigoWithParams
) where
import Data.Reflection (give)
import Data.Singletons (Sing, SingI(..))
import Indigo.Backend.Prelude
import Indigo.Frontend.Program (IndigoM, IndigoContract)
import Indigo.Internal.Var
import Indigo.Lorentz
import Util.Peano
-- | Type of a function with @n@ 'Var' arguments and @IndigoM a@ result.
--
-- Note that the arguments are the first @n@ elements of the @inp@ stack in
-- inverse order, for example:
-- @IndigoWithParams 2 [a, b, c] x@ is the same as:
-- @Var b -> Var a -> IndigoM x@
type IndigoWithParams n inp a = IndigoWithPeanoParams (ToPeano n) inp a
-- | Typeable and stack size constraints for the parameters of an 'IndigoWithParams'
-- and for converting to a 'Peano'
type AreIndigoParams n stk =
( AreIndigoPeanoParams (ToPeano n) stk
, SingI (ToPeano n)
)
-- | 'Peano' equivalent of 'IndigoWithParams'
type family IndigoWithPeanoParams n inp a where
IndigoWithPeanoParams 'Z _ a = IndigoM a
IndigoWithPeanoParams ('S n) inp a = Var (At n inp) -> IndigoWithPeanoParams n inp a
-- | Typeable and stack size constraints for the parameters of an 'IndigoWithPeanoParams'.
type family AreIndigoPeanoParams n stk :: Constraint where
AreIndigoPeanoParams 'Z _ = (() :: Constraint)
AreIndigoPeanoParams ('S n) stk =
(KnownValue (At n stk), RequireLongerThan stk n, AreIndigoPeanoParams n stk)
-- | Converts an 'IndigoWithParams' to its form without input 'Var's, alongside
-- the 'StackVars' to use it with and the first available (unassingned) 'RefId'.
fromIndigoWithParams
:: forall n a inp.
(AreIndigoParams n inp, KnownValue a, Default (StackVars inp))
=> IndigoWithParams n inp a
-> (IndigoM a, StackVars inp, RefId)
fromIndigoWithParams code = fromIndigoWithPeanoParams minBound def code (sing @(ToPeano n))
-- | 'Peano' version of 'fromIndigoWithParams'
fromIndigoWithPeanoParams
:: forall inp n a. (AreIndigoPeanoParams n inp, KnownValue a)
=> RefId
-> StackVars inp
-> IndigoWithPeanoParams n inp a
-> Sing n
-> (IndigoM a, StackVars inp, RefId)
fromIndigoWithPeanoParams ref md code = \case
SZ -> (code, md, ref)
SS n -> let var = Var ref in
fromIndigoWithPeanoParams @inp (ref + 1) (assignVarAt var md n) (code var) n
-- | Converts an 'IndigoContract' to the equivalent 'IndigoM' with the storage,
-- parameter and ops list as arguments.
contractToIndigoWithParams
:: forall param st . KnownValue st
=> IndigoContract param st
-> IndigoWithParams 3 '[param, st, Ops] ()
contractToIndigoWithParams code = \varOps varSt varParam ->
(give varOps $ give varSt code) varParam