-- SPDX-FileCopyrightText: 2020 Tocqueville Group -- -- SPDX-License-Identifier: LicenseRef-MIT-TQ module Indigo.Internal.SIS ( SomeIndigoState (..) , SomeGenCode (..) , toSIS , runSIS , thenSIS , overSIS ) where import Indigo.Prelude import Indigo.Internal.State -- | 'GenCode' with hidden output stack data SomeGenCode inp where SomeGenCode :: GenCode inp out -> SomeGenCode inp -- | 'IndigoState' with hidden output stack, -- necessary to generate typed Lorentz code from untyped Indigo frontend. newtype SomeIndigoState inp = SomeIndigoState { unSIS :: MetaData inp -> SomeGenCode inp } -- | To run 'SomeIndigoState' you need to pass an handler of 'GenCode' with any -- output stack and initial 'MetaData'. runSIS :: SomeIndigoState inp -> MetaData inp -> (forall out . GenCode inp out -> r) -> r runSIS (SomeIndigoState act) md f = case act md of SomeGenCode gc -> f gc -- | Convert 'IndigoState' to 'SomeIndigoState' toSIS :: IndigoState inp out -> SomeIndigoState inp toSIS is = SomeIndigoState $ \md -> SomeGenCode $ runIndigoState is md -- | Similar to a @>>@ for 'SomeIndigoState'. thenSIS :: SomeIndigoState inp -> (forall out . SomeIndigoState out) -> SomeIndigoState inp thenSIS m f = SomeIndigoState $ \md -> case unSIS m md of (SomeGenCode (GenCode st1 cd1 cl1 :: GenCode inp out)) -> case unSIS (f @out) (replStkMd md st1) of SomeGenCode (GenCode st2 cd2 cl2) -> SomeGenCode (GenCode st2 (cd1 ## cd2) (cl2 ## cl1)) -- | Modify the 'GenCode' inside a 'SomeIndigoState' by passing an handler of -- 'GenCode' that returns a 'SomeGenCode'. -- Useful in some cases to "wrap" or update and exising 'SomeGenCode'. overSIS :: (forall out. GenCode inp out -> SomeGenCode inp) -> SomeIndigoState inp -> SomeIndigoState inp overSIS f si = SomeIndigoState $ \md -> runSIS si md f