-- | Loop related names. module DDC.Core.Flow.Prim.OpLoop ( readOpLoop , typeOpLoop , xLoopLoopN , xLoopGuard) where import DDC.Core.Flow.Prim.KiConFlow import DDC.Core.Flow.Prim.TyConPrim import DDC.Core.Flow.Prim.TyConFlow import DDC.Core.Flow.Prim.Base import DDC.Core.Compounds.Simple import DDC.Core.Exp.Simple import DDC.Base.Pretty import Control.DeepSeq instance NFData OpLoop instance Pretty OpLoop where ppr fo = case fo of OpLoopLoop -> text "loop#" OpLoopLoopN -> text "loopn#" OpLoopGuard -> text "guard#" -- | Read a loop operator name. readOpLoop :: String -> Maybe OpLoop readOpLoop str = case str of "loop#" -> Just $ OpLoopLoop "loopn#" -> Just $ OpLoopLoopN "guard#" -> Just $ OpLoopGuard _ -> Nothing -- Types ---------------------------------------------------------------------- -- | Yield the type of a loop operator. typeOpLoop :: OpLoop -> Type Name typeOpLoop op = case op of -- loop# :: [k : Rate]. (Nat# -> Unit) -> Unit OpLoopLoop -> tForall kRate $ \_ -> (tNat `tFun` tUnit) `tFun` tUnit -- loopn# :: [k : Rate]. RateNat k -> (Nat# -> Unit) -> Unit OpLoopLoopN -> tForall kRate $ \kR -> tRateNat kR `tFun` (tNat `tFun` tUnit) `tFun` tUnit -- guard# :: Ref# Nat# -> Bool# -- -> (Nat# -> Unit) -> Unit OpLoopGuard -> tRef tNat `tFun` tBool `tFun` (tNat `tFun` tUnit) `tFun` tUnit -- Compounds ------------------------------------------------------------------ xLoopLoopN :: Type Name -> Exp () Name -> Exp () Name -> Exp () Name xLoopLoopN tR xRN xF = xApps (xVarOpLoop OpLoopLoopN) [XType tR, xRN, xF] xLoopGuard :: Exp () Name -- ^ Reference to guard counter. -> Exp () Name -- ^ Boolean flag to test. -> Exp () Name -- ^ Body of guard. -> Exp () Name xLoopGuard xB xCount xF = xApps (xVarOpLoop OpLoopGuard) [xCount, xB, xF] -- Utils ----------------------------------------------------------------------- xVarOpLoop :: OpLoop -> Exp () Name xVarOpLoop op = XVar (UPrim (NameOpLoop op) (typeOpLoop op))